From b12e5231de01ee5c50153b15780ff7ed32eea10a Mon Sep 17 00:00:00 2001 From: Richa-iitr Date: Thu, 28 Apr 2022 22:15:07 +0530 Subject: [PATCH] swap connectors for uniswapV3 mainnet --- .../mainnet/connectors/uniswap/v3/events.sol | 18 ++++ .../connectors/uniswap/v3/interface.sol | 21 ++-- .../mainnet/connectors/uniswap/v3/main.sol | 98 +++++++++++++++++++ 3 files changed, 126 insertions(+), 11 deletions(-) diff --git a/contracts/mainnet/connectors/uniswap/v3/events.sol b/contracts/mainnet/connectors/uniswap/v3/events.sol index 1e14d668..07bc0ca5 100644 --- a/contracts/mainnet/connectors/uniswap/v3/events.sol +++ b/contracts/mainnet/connectors/uniswap/v3/events.sol @@ -32,4 +32,22 @@ contract Events { ); event LogBurnPosition(uint256 tokenId); + + event LogBuy( + address indexed buyToken, + address indexed sellToken, + uint256 buyAmt, + uint256 sellAmt, + uint256 getId, + uint256 setId + ); + + event LogSell( + address indexed buyToken, + address indexed sellToken, + uint256 buyAmt, + uint256 sellAmt, + uint256 getId, + uint256 setId + ); } diff --git a/contracts/mainnet/connectors/uniswap/v3/interface.sol b/contracts/mainnet/connectors/uniswap/v3/interface.sol index 76aef1cb..7f518435 100644 --- a/contracts/mainnet/connectors/uniswap/v3/interface.sol +++ b/contracts/mainnet/connectors/uniswap/v3/interface.sol @@ -36,6 +36,16 @@ interface ISwapRouter is IUniswapV3SwapCallback { uint256 amountOutMinimum; uint160 sqrtPriceLimitX96; } + struct ExactOutputSingleParams { + address tokenIn; + address tokenOut; + uint24 fee; + address recipient; + uint256 deadline; + uint256 amountOut; + uint256 amountInMaximum; + uint160 sqrtPriceLimitX96; + } /// @notice Swaps `amountIn` of one token for as much as possible of another token /// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata @@ -61,17 +71,6 @@ interface ISwapRouter is IUniswapV3SwapCallback { payable returns (uint256 amountOut); - struct ExactOutputSingleParams { - address tokenIn; - address tokenOut; - uint24 fee; - address recipient; - uint256 deadline; - uint256 amountOut; - uint256 amountInMaximum; - uint160 sqrtPriceLimitX96; - } - /// @notice Swaps as little as possible of one token for `amountOut` of another token /// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata /// @return amountIn The amount of the input token diff --git a/contracts/mainnet/connectors/uniswap/v3/main.sol b/contracts/mainnet/connectors/uniswap/v3/main.sol index 3580ab6b..1603e30d 100644 --- a/contracts/mainnet/connectors/uniswap/v3/main.sol +++ b/contracts/mainnet/connectors/uniswap/v3/main.sol @@ -9,6 +9,7 @@ pragma abicoder v2; import {TokenInterface} from "../../../common/interfaces.sol"; import {Helpers} from "./helpers.sol"; +import "./interface.sol"; import {Events} from "./events.sol"; abstract contract UniswapResolver is Helpers, Events { @@ -204,6 +205,103 @@ abstract contract UniswapResolver is Helpers, Events { _eventName = "LogBurnPosition(uint256)"; _eventParam = abi.encode(tokenId); } + + function buy( + address buyAddr, + address sellAddr, + uint24 fee, + uint256 buyAmt, + uint256 unitAmt, + uint256 getId, + uint256 setId + ) external payable returns (string memory _eventName, bytes memory _eventParam) { + uint _buyAmt = getUint(getId, buyAmt); + (TokenInterface _buyAddr, TokenInterface _sellAddr) = changeEthAddress(buyAddr, sellAddr); + + // uint _slippageAmt = convert18ToDec(_sellAddr.decimals(), + // wmul(unitAmt, convertTo18(_buyAddr.decimals(), _buyAmt)) + // ); + + bool isEth = address(_sellAddr) == wethAddr; + convertEthToWeth(isEth, _sellAddr, uint256(-1)); + approve(_sellAddr, address(swapRouter), uint256(-1)); + ISwapRouter.ExactOutputSingleParams memory params; + + { + params = ISwapRouter.ExactOutputSingleParams({ + tokenIn: sellAddr, + tokenOut: buyAddr, + fee: fee, + recipient: address(this), + deadline: block.timestamp + 1, + amountOut: _buyAmt, + amountInMaximum: uint256(-1), + sqrtPriceLimitX96: 0 + }); + } + + uint _sellAmt = swapRouter.exactOutputSingle(params); + + isEth = address(_buyAddr) == wethAddr; + convertWethToEth(isEth, _buyAddr, _buyAmt); + + setUint(setId, _sellAmt); + + _eventName = "LogBuy(address,address,uint256,uint256,uint256,uint256)"; + _eventParam = abi.encode(buyAddr, sellAddr, _buyAmt, _sellAmt, getId, setId); + } + + function sell( + address buyAddr, + address sellAddr, + uint24 fee, + uint256 sellAmt, + uint256 unitAmt, + uint256 getId, + uint256 setId + ) external payable returns (string memory _eventName, bytes memory _eventParam) { + uint _sellAmt = getUint(getId, sellAmt); + (TokenInterface _buyAddr, TokenInterface _sellAddr) = changeEthAddress(buyAddr, sellAddr); + + if (_sellAmt == uint(-1)) { + _sellAmt = sellAddr == ethAddr ? + address(this).balance : + _sellAddr.balanceOf(address(this)); + } + + // uint _slippageAmt = convert18ToDec(_buyAddr.decimals(), + // wmul(unitAmt, convertTo18(_sellAddr.decimals(), _sellAmt)) + // ); + // require(_slippageAmt <= _expectedAmt, "Too much slippage"); + + bool isEth = address(_sellAddr) == wethAddr; + convertEthToWeth(isEth, _sellAddr, _sellAmt); + approve(_sellAddr, address(swapRouter), _sellAmt); + ISwapRouter.ExactInputSingleParams memory params; + + { + params = ISwapRouter.ExactInputSingleParams({ + tokenIn: sellAddr, + tokenOut: buyAddr, + fee: fee, + recipient: address(this), + deadline: block.timestamp + 1, + amountIn: _sellAmt, + amountOutMinimum: 0, + sqrtPriceLimitX96: 0 + }); + } + + uint _buyAmt = swapRouter.exactInputSingle(params); + + isEth = address(_buyAddr) == wethAddr; + convertWethToEth(isEth, _buyAddr, _buyAmt); + + setUint(setId, _buyAmt); + + _eventName = "LogSell(address,address,uint256,uint256,uint256,uint256)"; + _eventParam = abi.encode(buyAddr, sellAddr, _buyAmt, _sellAmt, getId, setId); + } } contract ConnectV2UniswapV3 is UniswapResolver {