harb/onchain/analysis/helpers/SwapExecutor.sol
2025-08-09 18:03:31 +02:00

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));
}
}
}