2022-03-22 14:47:37 +00:00
|
|
|
//SPDX-License-Identifier: MIT
|
2021-11-19 12:59:55 +00:00
|
|
|
pragma solidity ^0.7.6;
|
|
|
|
pragma abicoder v2;
|
|
|
|
|
2021-11-19 15:54:42 +00:00
|
|
|
import {UniswapV3Pool, ISwapRouter} from "./interface.sol";
|
2021-11-19 12:59:55 +00:00
|
|
|
import {SqrtPriceMath} from "./libraries/SqrtPriceMath.sol";
|
2021-11-19 14:40:44 +00:00
|
|
|
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
2021-11-19 15:54:42 +00:00
|
|
|
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
|
2021-11-19 14:40:44 +00:00
|
|
|
|
|
|
|
contract Helpers {
|
|
|
|
using SafeERC20 for IERC20;
|
2021-11-19 12:59:55 +00:00
|
|
|
|
2021-11-20 09:07:40 +00:00
|
|
|
ISwapRouter internal constant router =
|
2021-11-19 12:59:55 +00:00
|
|
|
ISwapRouter(0xE592427A0AEce92De3Edee1F18E0157C05861564);
|
|
|
|
|
2021-11-19 18:43:17 +00:00
|
|
|
bytes32 internal constant POOL_INIT_CODE_HASH =
|
|
|
|
0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54;
|
2021-11-19 12:59:55 +00:00
|
|
|
|
2021-11-19 18:43:17 +00:00
|
|
|
struct PoolKey {
|
|
|
|
address token0;
|
|
|
|
address token1;
|
|
|
|
uint24 fee;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getPoolAddress(
|
|
|
|
address tokenA,
|
|
|
|
address tokenB,
|
|
|
|
uint24 fee
|
|
|
|
) internal pure returns (address pool) {
|
|
|
|
if (tokenA > tokenB) (tokenA, tokenB) = (tokenB, tokenA);
|
|
|
|
return
|
|
|
|
computeAddress(
|
|
|
|
0x1F98431c8aD98523631AE4a59f267346ea31F984,
|
|
|
|
PoolKey({token0: tokenA, token1: tokenB, fee: fee})
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
function computeAddress(address factory, PoolKey memory key)
|
|
|
|
internal
|
|
|
|
pure
|
|
|
|
returns (address pool)
|
2021-11-19 12:59:55 +00:00
|
|
|
{
|
2021-11-19 18:43:17 +00:00
|
|
|
require(key.token0 < key.token1);
|
|
|
|
pool = address(
|
|
|
|
uint160(
|
|
|
|
uint256(
|
|
|
|
keccak256(
|
|
|
|
abi.encodePacked(
|
|
|
|
hex"ff",
|
|
|
|
factory,
|
|
|
|
keccak256(
|
|
|
|
abi.encode(key.token0, key.token1, key.fee)
|
|
|
|
),
|
|
|
|
POOL_INIT_CODE_HASH
|
|
|
|
)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
function getPriceLimit(
|
|
|
|
uint256 amountIn,
|
|
|
|
bool zeroForOne,
|
|
|
|
address tokenA,
|
|
|
|
address tokenB,
|
|
|
|
uint24 fee
|
2021-11-19 23:20:26 +00:00
|
|
|
) internal view returns (uint160) {
|
2021-11-19 18:43:17 +00:00
|
|
|
UniswapV3Pool state = UniswapV3Pool(
|
|
|
|
getPoolAddress(tokenA, tokenB, fee)
|
|
|
|
);
|
|
|
|
|
2021-11-19 12:59:55 +00:00
|
|
|
return (
|
|
|
|
SqrtPriceMath.getNextSqrtPriceFromInput(
|
|
|
|
state.slot0().sqrtPriceX96,
|
|
|
|
state.liquidity(),
|
|
|
|
amountIn,
|
|
|
|
zeroForOne
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
function getParams(
|
|
|
|
address tokenIn,
|
|
|
|
address tokenOut,
|
|
|
|
address recipient,
|
|
|
|
uint24 fee,
|
|
|
|
uint256 amountIn,
|
2021-11-20 10:51:36 +00:00
|
|
|
uint256 amountOutMinimum
|
2021-11-19 23:20:26 +00:00
|
|
|
) internal view returns (ISwapRouter.ExactInputSingleParams memory params) {
|
2021-11-19 12:59:55 +00:00
|
|
|
params = ISwapRouter.ExactInputSingleParams({
|
|
|
|
tokenIn: tokenIn,
|
|
|
|
tokenOut: tokenOut,
|
|
|
|
fee: fee,
|
|
|
|
recipient: recipient,
|
|
|
|
deadline: block.timestamp + 1,
|
|
|
|
amountIn: amountIn,
|
|
|
|
amountOutMinimum: amountOutMinimum,
|
2021-11-19 18:43:17 +00:00
|
|
|
sqrtPriceLimitX96: getPriceLimit(
|
|
|
|
amountIn,
|
2021-11-20 10:51:36 +00:00
|
|
|
tokenIn < tokenOut,
|
2021-11-19 18:43:17 +00:00
|
|
|
tokenIn,
|
|
|
|
tokenOut,
|
|
|
|
fee
|
|
|
|
)
|
2021-11-19 12:59:55 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-11-19 21:55:52 +00:00
|
|
|
function SwapTokens(
|
|
|
|
address tokenIn,
|
|
|
|
address tokenOut,
|
|
|
|
bool zeroForOne
|
2021-11-19 23:20:26 +00:00
|
|
|
) internal pure returns (address, address) {
|
2021-11-19 21:55:52 +00:00
|
|
|
if (!zeroForOne) return (tokenOut, tokenIn);
|
|
|
|
else return (tokenIn, tokenOut);
|
2021-11-19 12:59:55 +00:00
|
|
|
}
|
|
|
|
|
2021-11-19 14:22:34 +00:00
|
|
|
function swapSingleInput(ISwapRouter.ExactInputSingleParams memory params)
|
2021-11-19 23:20:26 +00:00
|
|
|
internal
|
2021-11-19 12:59:55 +00:00
|
|
|
returns (uint256)
|
|
|
|
{
|
|
|
|
return (uint256(router.exactInputSingle(params)));
|
|
|
|
}
|
|
|
|
}
|