From 6c95281b8c7a382548ebee1acd4c12e748a6d791 Mon Sep 17 00:00:00 2001 From: Richa-iitr Date: Sun, 1 May 2022 13:30:54 +0530 Subject: [PATCH] updated check for slippage --- .../connectors/uniswap/v3_swap/helpers.sol | 13 +- .../connectors/uniswap/v3_swap/main.sol | 74 +++--- .../connectors/uniswap/v3_swap/helpers.sol | 13 +- .../connectors/uniswap/v3_swap/main.sol | 78 +++--- .../connectors/uniswap/v3_swap/helpers.sol | 13 +- .../connectors/uniswap/v3_swap/main.sol | 78 +++--- .../connectors/uniswap/v3_swap/helpers.sol | 13 +- .../connectors/uniswap/v3_swap/main.sol | 55 ++-- test/mainnet/uniswap/uniswap-swap.test.ts | 243 +----------------- 9 files changed, 176 insertions(+), 404 deletions(-) diff --git a/contracts/arbitrum/connectors/uniswap/v3_swap/helpers.sol b/contracts/arbitrum/connectors/uniswap/v3_swap/helpers.sol index d4012c24..02d335bc 100644 --- a/contracts/arbitrum/connectors/uniswap/v3_swap/helpers.sol +++ b/contracts/arbitrum/connectors/uniswap/v3_swap/helpers.sol @@ -18,10 +18,19 @@ abstract contract Helpers is DSMath, Basic { address buyAddr; //token to be bought address sellAddr; //token to be sold uint24 fee; //pool fees for buyAddr-sellAddr token pair - uint256 unitAmt; //The unit amount of sellAMt/buyAmt with slippage - uint256 expectedAmt; //The amount that is expected to be returned after the swap + uint256 unitAmt; //The unit amount of sellAmt/buyAmt with slippage uint256 buyAmt; //amount of token to be bought uint256 getId; //Id to get buyAmt uint256 setId; //Id to store sellAmt } + + struct SellInfo { + address buyAddr; //token to be bought + address sellAddr; //token to be sold + uint24 fee; //pool fees for buyAddr-sellAddr token pair + uint256 unitAmt; //The unit amount of buyAmt/sellAmt with slippage. + uint256 sellAmt; //amount of token to be bought + uint256 getId; //Id to get buyAmt + uint256 setId; //Id to store sellAmt + } } \ No newline at end of file diff --git a/contracts/arbitrum/connectors/uniswap/v3_swap/main.sol b/contracts/arbitrum/connectors/uniswap/v3_swap/main.sol index ae4ce130..99295ea7 100644 --- a/contracts/arbitrum/connectors/uniswap/v3_swap/main.sol +++ b/contracts/arbitrum/connectors/uniswap/v3_swap/main.sol @@ -13,7 +13,7 @@ import {Events} from "./events.sol"; import "./interface.sol"; abstract contract UniswapResolver is Helpers, Events { - /** + /** * @dev Buy Function * @notice Swap token(sellAddr) with token(buyAddr), buy token with minimum sell token * @param buyData Data input for the buy action @@ -26,22 +26,19 @@ abstract contract UniswapResolver is Helpers, Events { returns (string memory _eventName, bytes memory _eventParam) { uint256 _buyAmt = getUint(buyData.getId, buyData.buyAmt); + ISwapRouter.ExactOutputSingleParams memory params; + (TokenInterface _buyAddr, TokenInterface _sellAddr) = changeEthAddress( buyData.buyAddr, buyData.sellAddr ); - { - uint _slippageAmt = convert18ToDec(_sellAddr.decimals(), - wmul(buyData.unitAmt, convertTo18(_buyAddr.decimals(), _buyAmt)) - ); - require(_slippageAmt >= buyData.expectedAmt, "Too much slippage"); - } - + uint _slippageAmt = convert18ToDec(_sellAddr.decimals(), + wmul(buyData.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; + convertEthToWeth(isEth, _sellAddr, _slippageAmt); + approve(_sellAddr, address(swapRouter), _slippageAmt); { params = ISwapRouter.ExactOutputSingleParams({ @@ -51,12 +48,13 @@ abstract contract UniswapResolver is Helpers, Events { recipient: address(this), deadline: block.timestamp + 1, amountOut: _buyAmt, - amountInMaximum: buyData.expectedAmt, + amountInMaximum: _slippageAmt, sqrtPriceLimitX96: 0 }); } uint256 _sellAmt = swapRouter.exactOutputSingle(params); + require(_slippageAmt >= _sellAmt, "Too much slippage"); isEth = address(_buyAddr) == wethAddr; convertWethToEth(isEth, _buyAddr, _buyAmt); @@ -76,42 +74,31 @@ abstract contract UniswapResolver is Helpers, Events { /** * @dev Sell Function - * @notice Swap token(sellAddr) with token(buyAddr), sell token to get maximum amount of buy token - * @param buyAddr token to be bought - * @param sellAddr token to be sold - * @param fee pool fees for buyAddr-sellAddr token pair - * @param sellAmt amount of token to be sold - * @param getId Id to get sellAmount - * @param setId Id to store buyAmount + * @notice Swap token(sellAddr) with token(buyAddr), to get max buy tokens + * @param sellData Data input for the buy action */ function sell( - address buyAddr, - address sellAddr, - uint24 fee, - uint256 sellAmt, - uint256 getId, - uint256 setId + SellInfo memory sellData ) external payable returns (string memory _eventName, bytes memory _eventParam) { - uint256 _sellAmt = getUint(getId, sellAmt); + uint256 _sellAmt = getUint(sellData.getId, sellData.sellAmt); (TokenInterface _buyAddr, TokenInterface _sellAddr) = changeEthAddress( - buyAddr, - sellAddr + sellData.buyAddr, + sellData.sellAddr ); - if (_sellAmt == uint256(-1)) { - _sellAmt = sellAddr == ethAddr + if (_sellAmt == uint256(-1)) { //change uint256(-1) + _sellAmt = sellData.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"); + uint _slippageAmt = convert18ToDec(_buyAddr.decimals(), + wmul(sellData.unitAmt, convertTo18(_sellAddr.decimals(), _sellAmt)) + ); bool isEth = address(_sellAddr) == wethAddr; convertEthToWeth(isEth, _sellAddr, _sellAmt); @@ -120,32 +107,33 @@ abstract contract UniswapResolver is Helpers, Events { { params = ISwapRouter.ExactInputSingleParams({ - tokenIn: sellAddr, - tokenOut: buyAddr, - fee: fee, + tokenIn: sellData.sellAddr, + tokenOut: sellData.buyAddr, + fee: sellData.fee, recipient: address(this), deadline: block.timestamp + 1, amountIn: _sellAmt, - amountOutMinimum: 0, + amountOutMinimum: _slippageAmt, sqrtPriceLimitX96: 0 }); } uint256 _buyAmt = swapRouter.exactInputSingle(params); + require(_slippageAmt <= _buyAmt, "Too much slippage"); isEth = address(_buyAddr) == wethAddr; convertWethToEth(isEth, _buyAddr, _buyAmt); - setUint(setId, _buyAmt); + setUint(sellData.setId, _buyAmt); _eventName = "LogSell(address,address,uint256,uint256,uint256,uint256)"; _eventParam = abi.encode( - buyAddr, - sellAddr, + sellData.buyAddr, + sellData.sellAddr, _buyAmt, _sellAmt, - getId, - setId + sellData.getId, + sellData.setId ); } } diff --git a/contracts/mainnet/connectors/uniswap/v3_swap/helpers.sol b/contracts/mainnet/connectors/uniswap/v3_swap/helpers.sol index 6f4a7905..607687d5 100644 --- a/contracts/mainnet/connectors/uniswap/v3_swap/helpers.sol +++ b/contracts/mainnet/connectors/uniswap/v3_swap/helpers.sol @@ -18,10 +18,19 @@ abstract contract Helpers is DSMath, Basic { address buyAddr; //token to be bought address sellAddr; //token to be sold uint24 fee; //pool fees for buyAddr-sellAddr token pair - uint256 unitAmt; //The unit amount of sellAMt/buyAmt with slippage - uint256 expectedAmt; //The amount that is expected to be returned after the swap + uint256 unitAmt; //The unit amount of sellAmt/buyAmt with slippage uint256 buyAmt; //amount of token to be bought uint256 getId; //Id to get buyAmt uint256 setId; //Id to store sellAmt } + + struct SellInfo { + address buyAddr; //token to be bought + address sellAddr; //token to be sold + uint24 fee; //pool fees for buyAddr-sellAddr token pair + uint256 unitAmt; //The unit amount of buyAmt/sellAmt with slippage. + uint256 sellAmt; //amount of token to be bought + uint256 getId; //Id to get buyAmt + uint256 setId; //Id to store sellAmt + } } \ No newline at end of file diff --git a/contracts/mainnet/connectors/uniswap/v3_swap/main.sol b/contracts/mainnet/connectors/uniswap/v3_swap/main.sol index 9fce8eb2..49bb7376 100644 --- a/contracts/mainnet/connectors/uniswap/v3_swap/main.sol +++ b/contracts/mainnet/connectors/uniswap/v3_swap/main.sol @@ -13,7 +13,7 @@ import {Events} from "./events.sol"; import "./interface.sol"; abstract contract UniswapResolver is Helpers, Events { - /** + /** * @dev Buy Function * @notice Swap token(sellAddr) with token(buyAddr), buy token with minimum sell token * @param buyData Data input for the buy action @@ -26,22 +26,21 @@ abstract contract UniswapResolver is Helpers, Events { returns (string memory _eventName, bytes memory _eventParam) { uint256 _buyAmt = getUint(buyData.getId, buyData.buyAmt); + uint _slippageAmt; + bool isEth; + ISwapRouter.ExactOutputSingleParams memory params; + (TokenInterface _buyAddr, TokenInterface _sellAddr) = changeEthAddress( buyData.buyAddr, buyData.sellAddr ); - { - uint _slippageAmt = convert18ToDec(_sellAddr.decimals(), - wmul(buyData.unitAmt, convertTo18(_buyAddr.decimals(), _buyAmt)) - ); - require(_slippageAmt >= buyData.expectedAmt, "Too much slippage"); - } - - bool isEth = address(_sellAddr) == wethAddr; - convertEthToWeth(isEth, _sellAddr, uint256(-1)); - approve(_sellAddr, address(swapRouter), uint256(-1)); - ISwapRouter.ExactOutputSingleParams memory params; + _slippageAmt = convert18ToDec(_sellAddr.decimals(), + wmul(buyData.unitAmt, convertTo18(_buyAddr.decimals(), _buyAmt)) + ); + isEth = address(_sellAddr) == wethAddr; + convertEthToWeth(isEth, _sellAddr, _slippageAmt); + approve(_sellAddr, address(swapRouter), _slippageAmt); { params = ISwapRouter.ExactOutputSingleParams({ @@ -51,12 +50,13 @@ abstract contract UniswapResolver is Helpers, Events { recipient: address(this), deadline: block.timestamp + 1, amountOut: _buyAmt, - amountInMaximum: buyData.expectedAmt, + amountInMaximum: _slippageAmt, sqrtPriceLimitX96: 0 }); } uint256 _sellAmt = swapRouter.exactOutputSingle(params); + require(_slippageAmt >= _sellAmt, "Too much slippage"); isEth = address(_buyAddr) == wethAddr; convertWethToEth(isEth, _buyAddr, _buyAmt); @@ -76,42 +76,31 @@ abstract contract UniswapResolver is Helpers, Events { /** * @dev Sell Function - * @notice Swap token(sellAddr) with token(buyAddr), sell token to get maximum amount of buy token - * @param buyAddr token to be bought - * @param sellAddr token to be sold - * @param fee pool fees for buyAddr-sellAddr token pair - * @param sellAmt amount of token to be sold - * @param getId Id to get sellAmount - * @param setId Id to store buyAmount + * @notice Swap token(sellAddr) with token(buyAddr), to get max buy tokens + * @param sellData Data input for the buy action */ function sell( - address buyAddr, - address sellAddr, - uint24 fee, - uint256 sellAmt, - uint256 getId, - uint256 setId + SellInfo memory sellData ) external payable returns (string memory _eventName, bytes memory _eventParam) { - uint256 _sellAmt = getUint(getId, sellAmt); + uint256 _sellAmt = getUint(sellData.getId, sellData.sellAmt); (TokenInterface _buyAddr, TokenInterface _sellAddr) = changeEthAddress( - buyAddr, - sellAddr + sellData.buyAddr, + sellData.sellAddr ); - if (_sellAmt == uint256(-1)) { - _sellAmt = sellAddr == ethAddr + if (_sellAmt == uint256(-1)) { //change uint256(-1) + _sellAmt = sellData.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"); + uint _slippageAmt = convert18ToDec(_buyAddr.decimals(), + wmul(sellData.unitAmt, convertTo18(_sellAddr.decimals(), _sellAmt)) + ); bool isEth = address(_sellAddr) == wethAddr; convertEthToWeth(isEth, _sellAddr, _sellAmt); @@ -120,32 +109,33 @@ abstract contract UniswapResolver is Helpers, Events { { params = ISwapRouter.ExactInputSingleParams({ - tokenIn: sellAddr, - tokenOut: buyAddr, - fee: fee, + tokenIn: sellData.sellAddr, + tokenOut: sellData.buyAddr, + fee: sellData.fee, recipient: address(this), deadline: block.timestamp + 1, amountIn: _sellAmt, - amountOutMinimum: 0, + amountOutMinimum: _slippageAmt, sqrtPriceLimitX96: 0 }); } uint256 _buyAmt = swapRouter.exactInputSingle(params); + require(_slippageAmt <= _buyAmt, "Too much slippage"); isEth = address(_buyAddr) == wethAddr; convertWethToEth(isEth, _buyAddr, _buyAmt); - setUint(setId, _buyAmt); + setUint(sellData.setId, _buyAmt); _eventName = "LogSell(address,address,uint256,uint256,uint256,uint256)"; _eventParam = abi.encode( - buyAddr, - sellAddr, + sellData.buyAddr, + sellData.sellAddr, _buyAmt, _sellAmt, - getId, - setId + sellData.getId, + sellData.setId ); } } diff --git a/contracts/optimism/connectors/uniswap/v3_swap/helpers.sol b/contracts/optimism/connectors/uniswap/v3_swap/helpers.sol index 2950f6a1..73ef69df 100644 --- a/contracts/optimism/connectors/uniswap/v3_swap/helpers.sol +++ b/contracts/optimism/connectors/uniswap/v3_swap/helpers.sol @@ -18,10 +18,19 @@ abstract contract Helpers is DSMath, Basic { address buyAddr; //token to be bought address sellAddr; //token to be sold uint24 fee; //pool fees for buyAddr-sellAddr token pair - uint256 unitAmt; //The unit amount of sellAMt/buyAmt with slippage - uint256 expectedAmt; //The amount that is expected to be returned after the swap + uint256 unitAmt; //The unit amount of sellAmt/buyAmt with slippage uint256 buyAmt; //amount of token to be bought uint256 getId; //Id to get buyAmt uint256 setId; //Id to store sellAmt } + + struct SellInfo { + address buyAddr; //token to be bought + address sellAddr; //token to be sold + uint24 fee; //pool fees for buyAddr-sellAddr token pair + uint256 unitAmt; //The unit amount of sellAmt/buyAmt with slippage + uint256 sellAmt; //amount of token to be bought + uint256 getId; //Id to get buyAmt + uint256 setId; //Id to store sellAmt + } } \ No newline at end of file diff --git a/contracts/optimism/connectors/uniswap/v3_swap/main.sol b/contracts/optimism/connectors/uniswap/v3_swap/main.sol index 0d6e5a5f..aa992b80 100644 --- a/contracts/optimism/connectors/uniswap/v3_swap/main.sol +++ b/contracts/optimism/connectors/uniswap/v3_swap/main.sol @@ -13,7 +13,7 @@ import {Events} from "./events.sol"; import "./interface.sol"; abstract contract UniswapResolver is Helpers, Events { - /** + /** * @dev Buy Function * @notice Swap token(sellAddr) with token(buyAddr), buy token with minimum sell token * @param buyData Data input for the buy action @@ -26,22 +26,21 @@ abstract contract UniswapResolver is Helpers, Events { returns (string memory _eventName, bytes memory _eventParam) { uint256 _buyAmt = getUint(buyData.getId, buyData.buyAmt); + uint _slippageAmt; + bool isEth; + ISwapRouter.ExactOutputSingleParams memory params; + (TokenInterface _buyAddr, TokenInterface _sellAddr) = changeEthAddress( buyData.buyAddr, buyData.sellAddr ); - - { - uint _slippageAmt = convert18ToDec(_sellAddr.decimals(), - wmul(buyData.unitAmt, convertTo18(_buyAddr.decimals(), _buyAmt)) - ); - require(_slippageAmt >= buyData.expectedAmt, "Too much slippage"); - } - bool isEth = address(_sellAddr) == wethAddr; - convertEthToWeth(isEth, _sellAddr, uint256(-1)); - approve(_sellAddr, address(swapRouter), uint256(-1)); - ISwapRouter.ExactOutputSingleParams memory params; + _slippageAmt = convert18ToDec(_sellAddr.decimals(), + wmul(buyData.unitAmt, convertTo18(_buyAddr.decimals(), _buyAmt)) + ); + isEth = address(_sellAddr) == wethAddr; + convertEthToWeth(isEth, _sellAddr, _slippageAmt); + approve(_sellAddr, address(swapRouter), _slippageAmt); { params = ISwapRouter.ExactOutputSingleParams({ @@ -51,12 +50,13 @@ abstract contract UniswapResolver is Helpers, Events { recipient: address(this), deadline: block.timestamp + 1, amountOut: _buyAmt, - amountInMaximum: buyData.expectedAmt, + amountInMaximum: _slippageAmt, sqrtPriceLimitX96: 0 }); } uint256 _sellAmt = swapRouter.exactOutputSingle(params); + require(_slippageAmt >= _sellAmt, "Too much slippage"); isEth = address(_buyAddr) == wethAddr; convertWethToEth(isEth, _buyAddr, _buyAmt); @@ -76,42 +76,31 @@ abstract contract UniswapResolver is Helpers, Events { /** * @dev Sell Function - * @notice Swap token(sellAddr) with token(buyAddr), sell token to get maximum amount of buy token - * @param buyAddr token to be bought - * @param sellAddr token to be sold - * @param fee pool fees for buyAddr-sellAddr token pair - * @param sellAmt amount of token to be sold - * @param getId Id to get sellAmount - * @param setId Id to store buyAmount + * @notice Swap token(sellAddr) with token(buyAddr), to get max buy tokens + * @param sellData Data input for the buy action */ function sell( - address buyAddr, - address sellAddr, - uint24 fee, - uint256 sellAmt, - uint256 getId, - uint256 setId + SellInfo memory sellData ) external payable returns (string memory _eventName, bytes memory _eventParam) { - uint256 _sellAmt = getUint(getId, sellAmt); + uint256 _sellAmt = getUint(sellData.getId, sellData.sellAmt); (TokenInterface _buyAddr, TokenInterface _sellAddr) = changeEthAddress( - buyAddr, - sellAddr + sellData.buyAddr, + sellData.sellAddr ); - if (_sellAmt == uint256(-1)) { - _sellAmt = sellAddr == ethAddr + if (_sellAmt == uint256(-1)) { //change uint256(-1) + _sellAmt = sellData.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"); + uint _slippageAmt = convert18ToDec(_buyAddr.decimals(), + wmul(sellData.unitAmt, convertTo18(_sellAddr.decimals(), _sellAmt)) + ); bool isEth = address(_sellAddr) == wethAddr; convertEthToWeth(isEth, _sellAddr, _sellAmt); @@ -120,32 +109,33 @@ abstract contract UniswapResolver is Helpers, Events { { params = ISwapRouter.ExactInputSingleParams({ - tokenIn: sellAddr, - tokenOut: buyAddr, - fee: fee, + tokenIn: sellData.sellAddr, + tokenOut: sellData.buyAddr, + fee: sellData.fee, recipient: address(this), deadline: block.timestamp + 1, amountIn: _sellAmt, - amountOutMinimum: 0, + amountOutMinimum: _slippageAmt, sqrtPriceLimitX96: 0 }); } uint256 _buyAmt = swapRouter.exactInputSingle(params); + require(_slippageAmt <= _buyAmt, "Too much slippage"); isEth = address(_buyAddr) == wethAddr; convertWethToEth(isEth, _buyAddr, _buyAmt); - setUint(setId, _buyAmt); + setUint(sellData.setId, _buyAmt); _eventName = "LogSell(address,address,uint256,uint256,uint256,uint256)"; _eventParam = abi.encode( - buyAddr, - sellAddr, + sellData.buyAddr, + sellData.sellAddr, _buyAmt, _sellAmt, - getId, - setId + sellData.getId, + sellData.setId ); } } diff --git a/contracts/polygon/connectors/uniswap/v3_swap/helpers.sol b/contracts/polygon/connectors/uniswap/v3_swap/helpers.sol index 5794ae22..a60bd9bb 100644 --- a/contracts/polygon/connectors/uniswap/v3_swap/helpers.sol +++ b/contracts/polygon/connectors/uniswap/v3_swap/helpers.sol @@ -18,10 +18,19 @@ abstract contract Helpers is DSMath, Basic { address buyAddr; //token to be bought address sellAddr; //token to be sold uint24 fee; //pool fees for buyAddr-sellAddr token pair - uint256 unitAmt; //The unit amount of sellAMt/buyAmt with slippage - uint256 expectedAmt; //The amount that is expected to be returned after the swap + uint256 unitAmt; //The unit amount of sellAmt/buyAmt with slippage uint256 buyAmt; //amount of token to be bought uint256 getId; //Id to get buyAmt uint256 setId; //Id to store sellAmt } + + struct SellInfo { + address buyAddr; //token to be bought + address sellAddr; //token to be sold + uint24 fee; //pool fees for buyAddr-sellAddr token pair + uint256 unitAmt; //The unit amount of sellAmt/buyAmt with slippage + uint256 sellAmt; //amount of token to be bought + uint256 getId; //Id to get buyAmt + uint256 setId; //Id to store sellAmt + } } \ No newline at end of file diff --git a/contracts/polygon/connectors/uniswap/v3_swap/main.sol b/contracts/polygon/connectors/uniswap/v3_swap/main.sol index 5c128bb9..180a2f91 100644 --- a/contracts/polygon/connectors/uniswap/v3_swap/main.sol +++ b/contracts/polygon/connectors/uniswap/v3_swap/main.sol @@ -34,11 +34,10 @@ abstract contract UniswapResolver is Helpers, Events { uint _slippageAmt = convert18ToDec(_sellAddr.decimals(), wmul(buyData.unitAmt, convertTo18(_buyAddr.decimals(), _buyAmt)) ); - require(_slippageAmt >= buyData.expectedAmt, "Too much slippage"); bool isMatic = address(_sellAddr) == wmaticAddr; - convertMaticToWmatic(isMatic, _sellAddr, uint256(-1)); - approve(_sellAddr, address(swapRouter), uint256(-1)); + convertMaticToWmatic(isMatic, _sellAddr, _slippageAmt); + approve(_sellAddr, address(swapRouter), _slippageAmt); ISwapRouter.ExactOutputSingleParams memory params; { @@ -49,12 +48,13 @@ abstract contract UniswapResolver is Helpers, Events { recipient: address(this), deadline: block.timestamp + 1, amountOut: _buyAmt, - amountInMaximum: buyData.expectedAmt, + amountInMaximum: _slippageAmt, sqrtPriceLimitX96: 0 }); } uint256 _sellAmt = swapRouter.exactOutputSingle(params); + require(_slippageAmt >= _sellAmt, "Too much slippage"); isMatic = address(_buyAddr) == wmaticAddr; convertWmaticToMatic(isMatic, _buyAddr, _buyAmt); @@ -74,38 +74,32 @@ abstract contract UniswapResolver is Helpers, Events { /** * @dev Sell Function - * @notice Swap token(sellAddr) with token(buyAddr), sell token to get maximum amount of buy token - * @param buyAddr token to be bought - * @param sellAddr token to be sold - * @param fee pool fees for buyAddr-sellAddr token pair - * @param sellAmt amount of token to be sold - * @param getId Id to get sellAmount - * @param setId Id to store buyAmount + * @notice Swap token(sellAddr) with token(buyAddr), to get max buy tokens + * @param sellData Data input for the buy action */ function sell( - address buyAddr, - address sellAddr, - uint24 fee, - uint256 sellAmt, - uint256 getId, - uint256 setId + SellInfo memory sellData ) external payable returns (string memory _eventName, bytes memory _eventParam) { - uint256 _sellAmt = getUint(getId, sellAmt); + uint256 _sellAmt = getUint(sellData.getId, sellData.sellAmt); ( TokenInterface _buyAddr, TokenInterface _sellAddr - ) = changeMaticAddress(buyAddr, sellAddr); + ) = changeMaticAddress(sellData.buyAddr, sellData.sellAddr); - if (_sellAmt == uint256(-1)) { - _sellAmt = sellAddr == maticAddr + if (_sellAmt == uint256(-1)) { + _sellAmt = sellData.sellAddr == maticAddr ? address(this).balance : _sellAddr.balanceOf(address(this)); } + uint _slippageAmt = convert18ToDec(_buyAddr.decimals(), + wmul(sellData.unitAmt, convertTo18(_sellAddr.decimals(), _sellAmt)) + ); + bool isMatic = address(_sellAddr) == wmaticAddr; convertMaticToWmatic(isMatic, _sellAddr, _sellAmt); approve(_sellAddr, address(swapRouter), _sellAmt); @@ -113,32 +107,33 @@ abstract contract UniswapResolver is Helpers, Events { { params = ISwapRouter.ExactInputSingleParams({ - tokenIn: sellAddr, - tokenOut: buyAddr, - fee: fee, + tokenIn: sellData.sellAddr, + tokenOut: sellData.buyAddr, + fee: sellData.fee, recipient: address(this), deadline: block.timestamp + 1, amountIn: _sellAmt, - amountOutMinimum: 0, + amountOutMinimum: _slippageAmt, sqrtPriceLimitX96: 0 }); } uint256 _buyAmt = swapRouter.exactInputSingle(params); + require(_slippageAmt <= _buyAmt, "Too much slippage"); isMatic = address(_buyAddr) == wmaticAddr; convertWmaticToMatic(isMatic, _buyAddr, _buyAmt); - setUint(setId, _buyAmt); + setUint(sellData.setId, _buyAmt); _eventName = "LogSell(address,address,uint256,uint256,uint256,uint256)"; _eventParam = abi.encode( - buyAddr, - sellAddr, + sellData.buyAddr, + sellData.sellAddr, _buyAmt, _sellAmt, - getId, - setId + sellData.getId, + sellData.setId ); } } diff --git a/test/mainnet/uniswap/uniswap-swap.test.ts b/test/mainnet/uniswap/uniswap-swap.test.ts index 988c6664..7151ae6a 100644 --- a/test/mainnet/uniswap/uniswap-swap.test.ts +++ b/test/mainnet/uniswap/uniswap-swap.test.ts @@ -122,247 +122,20 @@ describe("UniswapV3", function() { }); describe("Main", function() { - it("Should mint successfully", async function() { - const ethAmount = ethers.utils.parseEther("0.1"); // 1 ETH - const daiAmount = ethers.utils.parseEther("400"); // 1 ETH - const usdtAmount = Number(ethers.utils.parseEther("400")) / Math.pow(10, 12); // 1 ETH - const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"; - - const getIds = ["0", "0"]; - const setId = "0"; - - const spells = [ - { - connector: connectorName, - method: "mint", - args: [ - ethAddress, - DAI_ADDR, - FeeAmount.MEDIUM, - getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - ethAmount, - daiAmount, - "500000000000000000", - getIds, - setId, - ], - }, - { - connector: connectorName, - method: "mint", - args: [ - DAI_ADDR, - USDT_ADDR, - FeeAmount.MEDIUM, - getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - daiAmount, - usdtAmount, - "300000000000000000", - getIds, - setId, - ], - }, - { - connector: connectorName, - method: "mint", - args: [ - ethAddress, - USDT_ADDR, - FeeAmount.MEDIUM, - getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - ethAmount, - usdtAmount, - "300000000000000000", - getIds, - setId, - ], - }, - ]; - - const tx = await dsaWallet0 - .connect(wallet0) - .cast(...encodeSpells(spells), wallet1.address); - let receipt = await tx.wait(); - let castEvent = new Promise((resolve, reject) => { - dsaWallet0.on( - "LogCast", - ( - origin: any, - sender: any, - value: any, - targetNames: any, - targets: any, - eventNames: any, - eventParams: any, - event: any - ) => { - const params = abiCoder.decode( - ["uint256", "uint256", "uint256", "uint256", "int24", "int24"], - eventParams[0] - ); - const params1 = abiCoder.decode( - ["uint256", "uint256", "uint256", "uint256", "int24", "int24"], - eventParams[2] - ); - tokenIds.push(params[0]); - tokenIds.push(params1[0]); - liquidities.push(params[1]); - event.removeListener(); - - resolve({ - eventNames, - }); - } - ); - - setTimeout(() => { - reject(new Error("timeout")); - }, 60000); - }); - - let event = await castEvent; - - const data = await nftManager.positions(tokenIds[0]); - - expect(data.liquidity).to.be.equals(liquidities[0]); - }).timeout(10000000000); - - it("Should deposit successfully", async function() { - const daiAmount = ethers.utils.parseEther("400"); // 1 ETH - const ethAmount = ethers.utils.parseEther("0.1"); // 1 ETH - - const getIds = ["0", "0"]; - const setId = "0"; - - const spells = [ - { - connector: connectorName, - method: "deposit", - args: [ - tokenIds[0], - daiAmount, - ethAmount, - "500000000000000000", - getIds, - setId, - ], - }, - ]; - - const tx = await dsaWallet0 - .connect(wallet0) - .cast(...encodeSpells(spells), wallet1.address); - const receipt = await tx.wait(); - - let castEvent = new Promise((resolve, reject) => { - dsaWallet0.on( - "LogCast", - ( - origin: any, - sender: any, - value: any, - targetNames: any, - targets: any, - eventNames: any, - eventParams: any, - event: any - ) => { - const params = abiCoder.decode( - ["uint256", "uint256", "uint256", "uint256"], - eventParams[0] - ); - liquidities[0] = liquidities[0].add(params[1]); - event.removeListener(); - - resolve({ - eventNames, - }); - } - ); - - setTimeout(() => { - reject(new Error("timeout")); - }, 60000); - }); - - let event = await castEvent; - - const data = await nftManager.positions(tokenIds[0]); - expect(data.liquidity).to.be.equals(liquidities[0]); - }); - - it("Should withdraw successfully", async function() { - const getId = "0"; - const setIds = ["0", "0"]; - - const data = await nftManager.positions(tokenIds[0]); - let data1 = await nftManager.positions(tokenIds[1]); - - const spells = [ - { - connector: connectorName, - method: "withdraw", - args: [tokenIds[0], data.liquidity, 0, 0, getId, setIds], - }, - { - connector: connectorName, - method: "withdraw", - args: [0, data1.liquidity, 0, 0, getId, setIds], - }, - ]; - - const tx = await dsaWallet0 - .connect(wallet0) - .cast(...encodeSpells(spells), wallet1.address); - const receipt = await tx.wait(); - - data1 = await nftManager.positions(tokenIds[1]); - expect(data1.liquidity.toNumber()).to.be.equals(0); - }); - - it("Should collect successfully", async function() { - const ethAmount = ethers.utils.parseEther("0.2"); // 1 ETH - const daiAmount = ethers.utils.parseEther("800"); // 1 ETH - const getIds = ["0", "0"]; - const setIds = ["0", "0"]; - - const spells = [ - { - connector: connectorName, - method: "collect", - args: [tokenIds[0], daiAmount, ethAmount, getIds, setIds], - }, - ]; - - const tx = await dsaWallet0 - .connect(wallet0) - .cast(...encodeSpells(spells), wallet1.address); - const receipt = await tx.wait(); - }); - - it("Should burn successfully", async function() { - const spells = [ - { - connector: connectorName, - method: "burn", - args: [tokenIds[0]], - }, - ]; - - const tx = await dsaWallet0 - .connect(wallet0) - .cast(...encodeSpells(spells), wallet1.address); - const receipt = await tx.wait(); - }); it("Should buy successfully", async function() { const daiAmount = ethers.utils.parseEther("400"); const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"; const getId = "0"; const setId = "0"; + // const _expectedAmt = + const data = { + buyAddr: DAI_ADDR, + sellAddr: ethAddress, + fee: FeeAmount.MEDIUM, + unitAmt: "0", + + } const spells = [ {