dsa-connectors/contracts/arbitrum/connectors/uniswap-sell-beta/helpers.sol

125 lines
3.5 KiB
Solidity
Raw Permalink Normal View History

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);
bytes32 internal constant POOL_INIT_CODE_HASH =
0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54;
2021-11-19 12:59:55 +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
{
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) {
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,
sqrtPriceLimitX96: getPriceLimit(
amountIn,
2021-11-20 10:51:36 +00:00
tokenIn < tokenOut,
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)));
}
}