94 lines
No EOL
3.1 KiB
Solidity
94 lines
No EOL
3.1 KiB
Solidity
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
pragma solidity ^0.8.19;
|
|
|
|
import {IUniswapV3Pool} from "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol";
|
|
import {IWETH9} from "../../src/interfaces/IWETH9.sol";
|
|
import {Kraiken} from "../../src/Kraiken.sol";
|
|
import {TickMath} from "@aperture/uni-v3-lib/TickMath.sol";
|
|
|
|
/**
|
|
* @title SwapExecutor
|
|
* @notice Helper contract to execute swaps on Uniswap V3 pools for analysis scripts
|
|
* @dev Extracted from analysis scripts to avoid code duplication
|
|
*/
|
|
contract SwapExecutor {
|
|
IUniswapV3Pool public pool;
|
|
IWETH9 public weth;
|
|
Kraiken public harberg;
|
|
bool public token0isWeth;
|
|
|
|
constructor(IUniswapV3Pool _pool, IWETH9 _weth, Kraiken _harberg, bool _token0isWeth) {
|
|
pool = _pool;
|
|
weth = _weth;
|
|
harberg = _harberg;
|
|
token0isWeth = _token0isWeth;
|
|
}
|
|
|
|
function executeBuy(uint256 amount, address recipient) external {
|
|
// For buying HARB with WETH, we're swapping in the direction that increases HARB price
|
|
// zeroForOne = true if WETH is token0, false if WETH is token1
|
|
bool zeroForOne = token0isWeth;
|
|
|
|
// Set appropriate price limit based on swap direction
|
|
uint160 sqrtPriceLimitX96;
|
|
if (zeroForOne) {
|
|
// Price goes down (in terms of token0/token1 ratio)
|
|
sqrtPriceLimitX96 = TickMath.MIN_SQRT_RATIO + 1;
|
|
} else {
|
|
// Price goes up
|
|
sqrtPriceLimitX96 = TickMath.MAX_SQRT_RATIO - 1;
|
|
}
|
|
|
|
try pool.swap(
|
|
recipient,
|
|
zeroForOne,
|
|
int256(amount),
|
|
sqrtPriceLimitX96,
|
|
""
|
|
) {} catch {
|
|
// Swap failed, likely due to extreme price - ignore
|
|
}
|
|
}
|
|
|
|
function executeSell(uint256 amount, address recipient) external {
|
|
// For selling HARB for WETH, we're swapping in the direction that decreases HARB price
|
|
// zeroForOne = false if WETH is token0, true if WETH is token1
|
|
bool zeroForOne = !token0isWeth;
|
|
|
|
// Set appropriate price limit based on swap direction
|
|
uint160 sqrtPriceLimitX96;
|
|
if (zeroForOne) {
|
|
// Price goes down (in terms of token0/token1 ratio)
|
|
sqrtPriceLimitX96 = TickMath.MIN_SQRT_RATIO + 1;
|
|
} else {
|
|
// Price goes up
|
|
sqrtPriceLimitX96 = TickMath.MAX_SQRT_RATIO - 1;
|
|
}
|
|
|
|
try pool.swap(
|
|
recipient,
|
|
zeroForOne,
|
|
int256(amount),
|
|
sqrtPriceLimitX96,
|
|
""
|
|
) {} catch {
|
|
// Swap failed, likely due to extreme price - ignore
|
|
}
|
|
}
|
|
|
|
// Callback required for Uniswap V3 swaps
|
|
function uniswapV3SwapCallback(
|
|
int256 amount0Delta,
|
|
int256 amount1Delta,
|
|
bytes calldata
|
|
) external {
|
|
require(msg.sender == address(pool), "Unauthorized callback");
|
|
|
|
if (amount0Delta > 0) {
|
|
IWETH9(pool.token0()).transfer(address(pool), uint256(amount0Delta));
|
|
}
|
|
if (amount1Delta > 0) {
|
|
IWETH9(pool.token1()).transfer(address(pool), uint256(amount1Delta));
|
|
}
|
|
}
|
|
} |