mirror of
				https://github.com/Instadapp/dsa-connectors.git
				synced 2024-07-29 22:37:00 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			125 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Solidity
		
	
	
	
	
	
			
		
		
	
	
			125 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Solidity
		
	
	
	
	
	
//SPDX-License-Identifier: MIT
 | 
						|
pragma solidity ^0.7.6;
 | 
						|
pragma abicoder v2;
 | 
						|
 | 
						|
import {UniswapV3Pool, ISwapRouter} from "./interface.sol";
 | 
						|
import {SqrtPriceMath} from "./libraries/SqrtPriceMath.sol";
 | 
						|
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
 | 
						|
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
 | 
						|
 | 
						|
contract Helpers {
 | 
						|
    using SafeERC20 for IERC20;
 | 
						|
 | 
						|
    ISwapRouter internal constant router =
 | 
						|
        ISwapRouter(0xE592427A0AEce92De3Edee1F18E0157C05861564);
 | 
						|
 | 
						|
    bytes32 internal constant POOL_INIT_CODE_HASH =
 | 
						|
        0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54;
 | 
						|
 | 
						|
    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)
 | 
						|
    {
 | 
						|
        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
 | 
						|
    ) internal view returns (uint160) {
 | 
						|
        UniswapV3Pool state = UniswapV3Pool(
 | 
						|
            getPoolAddress(tokenA, tokenB, fee)
 | 
						|
        );
 | 
						|
 | 
						|
        return (
 | 
						|
            SqrtPriceMath.getNextSqrtPriceFromInput(
 | 
						|
                state.slot0().sqrtPriceX96,
 | 
						|
                state.liquidity(),
 | 
						|
                amountIn,
 | 
						|
                zeroForOne
 | 
						|
            )
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    function getParams(
 | 
						|
        address tokenIn,
 | 
						|
        address tokenOut,
 | 
						|
        address recipient,
 | 
						|
        uint24 fee,
 | 
						|
        uint256 amountIn,
 | 
						|
        uint256 amountOutMinimum
 | 
						|
    ) internal view returns (ISwapRouter.ExactInputSingleParams memory params) {
 | 
						|
        params = ISwapRouter.ExactInputSingleParams({
 | 
						|
            tokenIn: tokenIn,
 | 
						|
            tokenOut: tokenOut,
 | 
						|
            fee: fee,
 | 
						|
            recipient: recipient,
 | 
						|
            deadline: block.timestamp + 1,
 | 
						|
            amountIn: amountIn,
 | 
						|
            amountOutMinimum: amountOutMinimum,
 | 
						|
            sqrtPriceLimitX96: getPriceLimit(
 | 
						|
                amountIn,
 | 
						|
                tokenIn < tokenOut,
 | 
						|
                tokenIn,
 | 
						|
                tokenOut,
 | 
						|
                fee
 | 
						|
            )
 | 
						|
        });
 | 
						|
    }
 | 
						|
 | 
						|
    function SwapTokens(
 | 
						|
        address tokenIn,
 | 
						|
        address tokenOut,
 | 
						|
        bool zeroForOne
 | 
						|
    ) internal pure returns (address, address) {
 | 
						|
        if (!zeroForOne) return (tokenOut, tokenIn);
 | 
						|
        else return (tokenIn, tokenOut);
 | 
						|
    }
 | 
						|
 | 
						|
    function swapSingleInput(ISwapRouter.ExactInputSingleParams memory params)
 | 
						|
        internal
 | 
						|
        returns (uint256)
 | 
						|
    {
 | 
						|
        return (uint256(router.exactInputSingle(params)));
 | 
						|
    }
 | 
						|
}
 |