From 8ed8852a2838319f76d12dbc6ad7c46e1bd17f35 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Sat, 23 May 2020 04:17:47 +0530 Subject: [PATCH 01/20] Done with uniswap v2 swapping functions --- contracts/connectors/uniswapV2.sol | 336 +++++++++++++++++++++++++++++ 1 file changed, 336 insertions(+) create mode 100644 contracts/connectors/uniswapV2.sol diff --git a/contracts/connectors/uniswapV2.sol b/contracts/connectors/uniswapV2.sol new file mode 100644 index 0000000..2c30efa --- /dev/null +++ b/contracts/connectors/uniswapV2.sol @@ -0,0 +1,336 @@ +pragma solidity ^0.6.0; + +// import files from common directory +import { TokenInterface , MemoryInterface, EventInterface} from "../common/interfaces.sol"; +import { Stores } from "../common/stores.sol"; +import { DSMath } from "../common/math.sol"; + +interface IUniswapV2Router01 { + function factory() external pure returns (address); + function WETH() external pure returns (address); + + function addLiquidity( + address tokenA, + address tokenB, + uint amountADesired, + uint amountBDesired, + uint amountAMin, + uint amountBMin, + address to, + uint deadline + ) external returns (uint amountA, uint amountB, uint liquidity); + function addLiquidityETH( + address token, + uint amountTokenDesired, + uint amountTokenMin, + uint amountETHMin, + address to, + uint deadline + ) external payable returns (uint amountToken, uint amountETH, uint liquidity); + function removeLiquidity( + address tokenA, + address tokenB, + uint liquidity, + uint amountAMin, + uint amountBMin, + address to, + uint deadline + ) external returns (uint amountA, uint amountB); + function removeLiquidityETH( + address token, + uint liquidity, + uint amountTokenMin, + uint amountETHMin, + address to, + uint deadline + ) external returns (uint amountToken, uint amountETH); + function removeLiquidityWithPermit( + address tokenA, + address tokenB, + uint liquidity, + uint amountAMin, + uint amountBMin, + address to, + uint deadline, + bool approveMax, uint8 v, bytes32 r, bytes32 s + ) external returns (uint amountA, uint amountB); + function removeLiquidityETHWithPermit( + address token, + uint liquidity, + uint amountTokenMin, + uint amountETHMin, + address to, + uint deadline, + bool approveMax, uint8 v, bytes32 r, bytes32 s + ) external returns (uint amountToken, uint amountETH); + function swapExactTokensForTokens( + uint amountIn, + uint amountOutMin, + address[] calldata path, + address to, + uint deadline + ) external returns (uint[] memory amounts); + function swapTokensForExactTokens( + uint amountOut, + uint amountInMax, + address[] calldata path, + address to, + uint deadline + ) external returns (uint[] memory amounts); + function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) + external + payable + returns (uint[] memory amounts); + function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) + external + returns (uint[] memory amounts); + function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) + external + returns (uint[] memory amounts); + function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) + external + payable + returns (uint[] memory amounts); + + function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); + function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); + function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn); + function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); + function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); +} + +interface IUniswapV2Factory { + function getPair(address tokenA, address tokenB) external view returns (address pair); + function allPairs(uint) external view returns (address pair); + function allPairsLength() external view returns (uint); + + function feeTo() external view returns (address); + function feeToSetter() external view returns (address); + + function createPair(address tokenA, address tokenB) external returns (address pair); +} + +contract UniswapHelpers is Stores, DSMath { + /** + * @dev Return WETH address + */ + function getAddressWETH() internal pure returns (address) { + return 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; + } + + /** + * @dev Return uniswap v2 router Address + */ + function getUniswapAddr() internal pure returns (address) { + return 0x794e6e91555438aFc3ccF1c5076A74F42133d08D; + } + + function convert18ToDec(uint _dec, uint256 _amt) internal pure returns (uint256 amt) { + amt = (_amt / 10 ** (18 - _dec)); + } + + function convertTo18(uint _dec, uint256 _amt) internal pure returns (uint256 amt) { + amt = mul(_amt, 10 ** (18 - _dec)); + } + + function changeEthAddress(address buy, address sell) internal pure returns(TokenInterface _buy, TokenInterface _sell){ + _buy = buy == getEthAddr() ? TokenInterface(getAddressWETH()) : TokenInterface(buy); + _sell = sell == getEthAddr() ? TokenInterface(getAddressWETH()) : TokenInterface(sell); + } + + function convertEthToWeth(TokenInterface token, uint amount) internal { + if(address(token) == getAddressWETH()) token.deposit.value(amount)(); + } + + function convertWethToEth(TokenInterface token, uint amount) internal { + if(address(token) == getAddressWETH()) { + token.approve(getAddressWETH(), amount); + token.withdraw(amount); + } + } + + function getExpectedBuyAmt( + IUniswapV2Router01 router, + address[] memory paths, + uint sellAmt + ) internal view returns(uint buyAmt) { + uint[] memory amts = router.getAmountsOut( + sellAmt, + paths + ); + buyAmt = amts[1]; + } + + function getExpectedSellAmt( + IUniswapV2Router01 router, + address[] memory paths, + uint buyAmt + ) internal view returns(uint sellAmt) { + uint[] memory amts = router.getAmountsOut( + buyAmt, + paths + ); + sellAmt = amts[1]; + } + + function checkPair( + IUniswapV2Router01 router, + address[] memory paths + ) internal view { + address pair = IUniswapV2Factory(router.factory()).getPair(paths[0], paths[1]); + require(pair != address(0), "No-exchange-address"); + } + + function getPaths( + address sellAddr, + address buyAddr + ) internal view returns(address[] memory paths) { + paths = new address[](2); + paths[0] = address(sellAddr); + paths[1] = address(buyAddr); + } + + +} + + +contract UniswapResolver is UniswapHelpers { + 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 + ); + + /** + * @dev Buy ETH/ERC20_Token. + * @param buyAddr buying token address.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param sellAddr selling token amount.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param buyAmt buying token amount. + * @param unitAmt unit amount of sellAmt/buyAmt with slippage. + * @param getId Get token amount at this ID from `InstaMemory` Contract. + * @param setId Set token amount at this ID in `InstaMemory` Contract. + */ + function buy( + address buyAddr, + address sellAddr, + uint buyAmt, + uint unitAmt, + uint getId, + uint setId + ) external payable { + // swapTokensForExactTokens + uint _buyAmt = getUint(getId, buyAmt); + (TokenInterface _buyAddr, TokenInterface _sellAddr) = changeEthAddress(buyAddr, sellAddr); + address[] memory paths = getPaths(address(_buyAddr), address(_sellAddr)); + + uint __buyAmt18 = convertTo18(_buyAddr.decimals(), _buyAmt); + uint _slippageAmt = convert18ToDec(_sellAddr.decimals(), wmul(unitAmt, __buyAmt18)); + + IUniswapV2Router01 router = IUniswapV2Router01(getUniswapAddr()); + + checkPair(router, paths); + uint _expectedAmt = getExpectedSellAmt(router, paths, _buyAmt); + require(_slippageAmt >= _expectedAmt, "Too much slippage"); + + convertEthToWeth(_sellAddr, _expectedAmt); + _sellAddr.approve(address(router), _expectedAmt); + + + + uint[] memory _amts = router.swapTokensForExactTokens( + _buyAmt, + _expectedAmt, + paths, + address(this), + now + 6 hours // TODO - deadline? + ); + + uint _sellAmt = _amts[0]; + + convertWethToEth(_buyAddr, _buyAmt); + + setUint(setId, _sellAmt); + + emit LogBuy(buyAddr, sellAddr, _buyAmt, _sellAmt, getId, setId); + bytes32 _eventCode = keccak256("LogBuy(address,address,uint256,uint256,uint256,uint256)"); + bytes memory _eventParam = abi.encode(buyAddr, sellAddr, _buyAmt, _sellAmt, getId, setId); + (uint _type, uint _id) = connectorID(); + EventInterface(getEventAddr()).emitEvent(_type, _id, _eventCode, _eventParam); + } + + /** + * @dev Sell ETH/ERC20_Token. + * @param buyAddr buying token address.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param sellAddr selling token amount.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param sellAmt selling token amount. + * @param unitAmt unit amount of buyAmt/sellAmt with slippage. + * @param getId Get token amount at this ID from `InstaMemory` Contract. + * @param setId Set token amount at this ID in `InstaMemory` Contract. + */ + function sell( + address buyAddr, + address sellAddr, + uint sellAmt, + uint unitAmt, + uint getId, + uint setId + ) external payable { + // /swapExactTokensForTokens/ + uint _sellAmt = getUint(getId, sellAmt); + (TokenInterface _buyAddr, TokenInterface _sellAddr) = changeEthAddress(buyAddr, sellAddr); + address[] memory paths = getPaths(address(_buyAddr), address(_sellAddr)); + + if (_sellAmt == uint(-1)) { + _sellAmt = sellAddr == getEthAddr() ? address(this).balance : _buyAddr.balanceOf(address(this)); + } + + uint _sellAmt18 = convertTo18(_sellAddr.decimals(), _sellAmt); + uint _slippageAmt = convert18ToDec(_buyAddr.decimals(), wmul(unitAmt, _sellAmt18)); + + IUniswapV2Router01 router = IUniswapV2Router01(getUniswapAddr()); + + checkPair(router, paths); + uint _expectedAmt = getExpectedBuyAmt(router, paths, _sellAmt); + require(_slippageAmt >= _expectedAmt, "Too much slippage"); + + convertEthToWeth(_sellAddr, _sellAmt); + _sellAddr.approve(address(router), _sellAmt); + + uint[] memory _amts = router.swapExactTokensForTokens( + _sellAmt, + _expectedAmt, + paths, + address(this), + now + 6 hours // TODO - deadline? + ); + + uint _buyAmt = _amts[1]; + + convertWethToEth(_buyAddr, _buyAmt); + + setUint(setId, _buyAmt); + + emit LogSell(buyAddr, sellAddr, _buyAmt, _sellAmt, getId, setId); + bytes32 _eventCode = keccak256("LogSell(address,address,uint256,uint256,uint256,uint256)"); + bytes memory _eventParam = abi.encode(buyAddr, sellAddr, _buyAmt, _sellAmt, getId, setId); + (uint _type, uint _id) = connectorID(); + EventInterface(getEventAddr()).emitEvent(_type, _id, _eventCode, _eventParam); + } +} + + +contract ConnectUniswapV2 is UniswapResolver { + string public name = "UniswapV2-v1"; +} \ No newline at end of file From 2786b1630e6c1ac5919328226e744805de4675be Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Sat, 23 May 2020 04:20:05 +0530 Subject: [PATCH 02/20] Done with uniswap v2 swapping functions --- contracts/connectors/uniswapV2.sol | 4 ---- 1 file changed, 4 deletions(-) diff --git a/contracts/connectors/uniswapV2.sol b/contracts/connectors/uniswapV2.sol index 2c30efa..a933408 100644 --- a/contracts/connectors/uniswapV2.sol +++ b/contracts/connectors/uniswapV2.sol @@ -230,7 +230,6 @@ contract UniswapResolver is UniswapHelpers { uint getId, uint setId ) external payable { - // swapTokensForExactTokens uint _buyAmt = getUint(getId, buyAmt); (TokenInterface _buyAddr, TokenInterface _sellAddr) = changeEthAddress(buyAddr, sellAddr); address[] memory paths = getPaths(address(_buyAddr), address(_sellAddr)); @@ -247,8 +246,6 @@ contract UniswapResolver is UniswapHelpers { convertEthToWeth(_sellAddr, _expectedAmt); _sellAddr.approve(address(router), _expectedAmt); - - uint[] memory _amts = router.swapTokensForExactTokens( _buyAmt, _expectedAmt, @@ -287,7 +284,6 @@ contract UniswapResolver is UniswapHelpers { uint getId, uint setId ) external payable { - // /swapExactTokensForTokens/ uint _sellAmt = getUint(getId, sellAmt); (TokenInterface _buyAddr, TokenInterface _sellAddr) = changeEthAddress(buyAddr, sellAddr); address[] memory paths = getPaths(address(_buyAddr), address(_sellAddr)); From af765feaafe5beaf1c90b4e75c6c9a04d830fcc4 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Wed, 27 May 2020 03:34:38 +0530 Subject: [PATCH 03/20] Almost done with uniswap --- contracts/connectors/uniswapV2.sol | 196 ++++++++++++++++++++++++++++- 1 file changed, 192 insertions(+), 4 deletions(-) diff --git a/contracts/connectors/uniswapV2.sol b/contracts/connectors/uniswapV2.sol index a933408..fb9be95 100644 --- a/contracts/connectors/uniswapV2.sol +++ b/contracts/connectors/uniswapV2.sol @@ -184,17 +184,205 @@ contract UniswapHelpers is Stores, DSMath { function getPaths( address sellAddr, address buyAddr - ) internal view returns(address[] memory paths) { + ) internal pure returns(address[] memory paths) { paths = new address[](2); paths[0] = address(sellAddr); paths[1] = address(buyAddr); } - - } +contract LiquidityHelpers is UniswapHelpers { -contract UniswapResolver is UniswapHelpers { + function changeEthToWeth( + address[] memory tokens + ) internal pure returns(TokenInterface[] memory _tokens) { + _tokens = new TokenInterface[](2); + _tokens[0] = tokens[0] == getEthAddr() ? TokenInterface(getAddressWETH()) : TokenInterface(tokens[0]); + _tokens[1] = tokens[1] == getEthAddr() ? TokenInterface(getAddressWETH()) : TokenInterface(tokens[1]); + + } + + function _addLiquidity( + address[] memory tokens, + uint[] memory _amts, + uint[] memory slippages, + uint deadline + ) internal returns (uint _amtA, uint _amtB, uint _liquidity) { + IUniswapV2Router01 router = IUniswapV2Router01(getUniswapAddr()); + TokenInterface[] memory _tokens = changeEthToWeth(tokens); + _amts[0] = _amts[0] == uint(-1) ? _tokens[0].balanceOf(address(this)) : _amts[0]; + _amts[1] = _amts[1] == uint(-1) ? _tokens[1].balanceOf(address(this)) : _amts[1]; + + convertEthToWeth(_tokens[0], _amts[0]); + convertEthToWeth(_tokens[1], _amts[1]); + _tokens[0].approve(address(router), _amts[0]); + _tokens[0].approve(address(router), _amts[1]); + + (_amtA, _amtB, _liquidity) = router.addLiquidity( + address(_tokens[0]), + address(_tokens[1]), + _amts[0], + _amts[1], + slippages[0], + slippages[1], + address(this), + now + deadline // TODO - deadline? + ); + } + + function _removeLiquidity( + address[] memory tokens, + uint _amt, + uint[] memory slippages, + uint deadline + ) internal returns (uint _amtA, uint _amtB) { + IUniswapV2Router01 router = IUniswapV2Router01(getUniswapAddr()); + TokenInterface[] memory _tokens = changeEthToWeth(tokens); + address exchangeAddr = IUniswapV2Factory(router.factory()).getPair(address(_tokens[0]), address(_tokens[1])); + require(exchangeAddr != address(0), "pair-not-found."); + TokenInterface(exchangeAddr).approve(address(router), _amt); + + (_amtA, _amtB) = router.removeLiquidity( + address(_tokens[0]), + address(_tokens[1]), + _amt, + slippages[0], + slippages[1], + address(this), + now + deadline // TODO - deadline? + ); + + convertWethToEth(_tokens[0], _amtA); + convertWethToEth(_tokens[1], _amtB); + } +} + +contract UniswapLiquidity is LiquidityHelpers { + event LogDepositLiquidity( + address indexed tokenA, + address indexed tokenB, + uint amtA, + uint amtB, + uint uniAmount, + uint[] getId, + uint setId + ); + + event LogWithdrawLiquidity( + address indexed tokenA, + address indexed tokenB, + uint amountA, + uint amountB, + uint uniAmount, + uint getId, + uint[] setId + ); + + function emitDeposit( + address[] memory tokens, + uint _amtA, + uint _amtB, + uint _uniAmt, + uint[] memory getIds, + uint setId + ) internal { + emit LogDepositLiquidity( + tokens[0], + tokens[1], + _amtA, + _amtB, + _uniAmt, + getIds, + setId + ); + + bytes32 _eventCode = keccak256("LogDepositLiquidity(address,address,uint256,uint256,uint256,uint256[],uint256)"); + bytes memory _eventParam = abi.encode( + tokens[0], + tokens[1], + _amtA, + _amtB, + _uniAmt, + getIds, + setId + ); + emitEvent(_eventCode, _eventParam); + } + + function emitWithdraw( + address[] memory tokens, + uint _amtA, + uint _amtB, + uint _uniAmt, + uint getId, + uint[] memory setIds + ) internal { + emit LogWithdrawLiquidity( + tokens[0], + tokens[1], + _amtA, + _amtB, + _uniAmt, + getId, + setIds + ); + bytes32 _eventCode = keccak256("LogWithdrawLiquidity(address,address,uint256,uint256,uint256,uint256[],uint256)"); + bytes memory _eventParam = abi.encode( + tokens[0], + tokens[1], + _amtA, + _amtB, + _uniAmt, + getId, + setIds + ); + emitEvent(_eventCode, _eventParam); + } + + function deposit( + address[] calldata tokens, + uint[] calldata amts, + uint[] calldata slippages, + uint deadline, + uint[] calldata getIds, + uint setId + ) external payable { + require(tokens.length == 2 && amts.length == 2, "length-is-not-two"); + uint[] memory _amts = new uint[](2); + for (uint i = 0; i < getIds.length; i++) { + _amts[i] = getUint(getIds[i], amts[i]); + } + + (uint _amtA, uint _amtB, uint _uniAmt) = _addLiquidity( + tokens, + _amts, + slippages, + deadline + ); + setUint(setId, _uniAmt); + emitDeposit(tokens, _amtA, _amtB, _uniAmt, getIds, setId); + } + + function withdraw( + address[] calldata tokens, + uint amt, + uint[] calldata slippages, + uint deadline, + uint getId, + uint[] calldata setIds + ) external payable { + require(tokens.length == 2, "length-is-not-two"); + uint _uniAmt = getUint(getId, amt); + + (uint _amtA, uint _amtB) = _removeLiquidity(tokens, _uniAmt, slippages, deadline); + + setUint(setIds[0], _amtA); + setUint(setIds[1], _amtB); + emitWithdraw(tokens, _amtA, _amtB, _uniAmt, getId, setIds); + } +} + +contract UniswapResolver is UniswapLiquidity { event LogBuy( address indexed buyToken, address indexed sellToken, From 6bafbdfece150eb3fdf3032bc51381244f78f5d9 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Wed, 27 May 2020 03:35:19 +0530 Subject: [PATCH 04/20] solidity version change --- truffle-config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/truffle-config.js b/truffle-config.js index 71a9947..af2d1d7 100644 --- a/truffle-config.js +++ b/truffle-config.js @@ -108,7 +108,7 @@ module.exports = { // Configure your compilers compilers: { solc: { - version: "v0.6.0", // Fetch exact version from solc-bin (default: truffle's version) + version: "v0.6.2", // Fetch exact version from solc-bin (default: truffle's version) // docker: true, // Use "0.5.1" you've installed locally with docker (default: false) // settings: { // See the solidity docs for advice about optimization and evmVersion // optimizer: { From e5eb533a31ed694618e475bfc1d617c0bcec97a8 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Wed, 27 May 2020 04:49:25 +0530 Subject: [PATCH 05/20] Added uint(-1) for remove liquidity --- contracts/connectors/uniswapV2.sol | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/contracts/connectors/uniswapV2.sol b/contracts/connectors/uniswapV2.sol index fb9be95..2c75dce 100644 --- a/contracts/connectors/uniswapV2.sol +++ b/contracts/connectors/uniswapV2.sol @@ -235,12 +235,15 @@ contract LiquidityHelpers is UniswapHelpers { uint _amt, uint[] memory slippages, uint deadline - ) internal returns (uint _amtA, uint _amtB) { + ) internal returns (uint _amtA, uint _amtB, uint _uniAmt) { IUniswapV2Router01 router = IUniswapV2Router01(getUniswapAddr()); TokenInterface[] memory _tokens = changeEthToWeth(tokens); address exchangeAddr = IUniswapV2Factory(router.factory()).getPair(address(_tokens[0]), address(_tokens[1])); require(exchangeAddr != address(0), "pair-not-found."); - TokenInterface(exchangeAddr).approve(address(router), _amt); + + TokenInterface uniToken = TokenInterface(exchangeAddr); + _uniAmt = _amt == uint(-1) ? uniToken.balanceOf(address(this)) : _amt; + uniToken.approve(address(router), _uniAmt); (_amtA, _amtB) = router.removeLiquidity( address(_tokens[0]), @@ -372,9 +375,9 @@ contract UniswapLiquidity is LiquidityHelpers { uint[] calldata setIds ) external payable { require(tokens.length == 2, "length-is-not-two"); - uint _uniAmt = getUint(getId, amt); - - (uint _amtA, uint _amtB) = _removeLiquidity(tokens, _uniAmt, slippages, deadline); + uint _amt = getUint(getId, amt); + + (uint _amtA, uint _amtB, uint _uniAmt) = _removeLiquidity(tokens, _amt, slippages, deadline); setUint(setIds[0], _amtA); setUint(setIds[1], _amtB); From 4b90d3dbf17cc6ee5d2aecf25d3026e667aac684 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Wed, 27 May 2020 05:15:45 +0530 Subject: [PATCH 06/20] Fixed bugs --- contracts/connectors/uniswapV2.sol | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/contracts/connectors/uniswapV2.sol b/contracts/connectors/uniswapV2.sol index 2c75dce..fd30556 100644 --- a/contracts/connectors/uniswapV2.sol +++ b/contracts/connectors/uniswapV2.sol @@ -133,6 +133,10 @@ contract UniswapHelpers is Stores, DSMath { amt = mul(_amt, 10 ** (18 - _dec)); } + function getTokenBalace(address token) internal view returns (uint256 amt) { + amt = token == getEthAddr() ? address(this).balance : TokenInterface(token).balanceOf(address(this)); + } + function changeEthAddress(address buy, address sell) internal pure returns(TokenInterface _buy, TokenInterface _sell){ _buy = buy == getEthAddr() ? TokenInterface(getAddressWETH()) : TokenInterface(buy); _sell = sell == getEthAddr() ? TokenInterface(getAddressWETH()) : TokenInterface(sell); @@ -193,6 +197,16 @@ contract UniswapHelpers is Stores, DSMath { contract LiquidityHelpers is UniswapHelpers { + function getMinAmount( + TokenInterface token, + uint amt, + uint slippage + ) internal view returns(uint minAmt) { + uint _amt18 = convertTo18(token.decimals(), amt); + minAmt = wmul(_amt18, sub(WAD, slippage)); + minAmt = convert18ToDec(token.decimals(), minAmt); + } + function changeEthToWeth( address[] memory tokens ) internal pure returns(TokenInterface[] memory _tokens) { @@ -210,8 +224,8 @@ contract LiquidityHelpers is UniswapHelpers { ) internal returns (uint _amtA, uint _amtB, uint _liquidity) { IUniswapV2Router01 router = IUniswapV2Router01(getUniswapAddr()); TokenInterface[] memory _tokens = changeEthToWeth(tokens); - _amts[0] = _amts[0] == uint(-1) ? _tokens[0].balanceOf(address(this)) : _amts[0]; - _amts[1] = _amts[1] == uint(-1) ? _tokens[1].balanceOf(address(this)) : _amts[1]; + _amts[0] = _amts[0] == uint(-1) ? getTokenBalace(tokens[0]) : _amts[0]; + _amts[1] = _amts[1] == uint(-1) ? getTokenBalace(tokens[0]) : _amts[1]; convertEthToWeth(_tokens[0], _amts[0]); convertEthToWeth(_tokens[1], _amts[1]); @@ -223,8 +237,8 @@ contract LiquidityHelpers is UniswapHelpers { address(_tokens[1]), _amts[0], _amts[1], - slippages[0], - slippages[1], + getMinAmount(_tokens[0], _amts[0], slippages[0]), + getMinAmount(_tokens[1], _amts[1], slippages[1]), address(this), now + deadline // TODO - deadline? ); @@ -480,7 +494,7 @@ contract UniswapResolver is UniswapLiquidity { address[] memory paths = getPaths(address(_buyAddr), address(_sellAddr)); if (_sellAmt == uint(-1)) { - _sellAmt = sellAddr == getEthAddr() ? address(this).balance : _buyAddr.balanceOf(address(this)); + _sellAmt = sellAddr == getEthAddr() ? address(this).balance : _sellAddr.balanceOf(address(this)); } uint _sellAmt18 = convertTo18(_sellAddr.decimals(), _sellAmt); From 8bfc8f6ec79077c1f4ba610a2e654a3233cc51a5 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Thu, 28 May 2020 03:53:38 +0530 Subject: [PATCH 07/20] Major changes --- contracts/connectors/uniswapV2.sol | 132 ++++++++++------------------- 1 file changed, 44 insertions(+), 88 deletions(-) diff --git a/contracts/connectors/uniswapV2.sol b/contracts/connectors/uniswapV2.sol index fd30556..76cb47b 100644 --- a/contracts/connectors/uniswapV2.sol +++ b/contracts/connectors/uniswapV2.sol @@ -19,14 +19,6 @@ interface IUniswapV2Router01 { address to, uint deadline ) external returns (uint amountA, uint amountB, uint liquidity); - function addLiquidityETH( - address token, - uint amountTokenDesired, - uint amountTokenMin, - uint amountETHMin, - address to, - uint deadline - ) external payable returns (uint amountToken, uint amountETH, uint liquidity); function removeLiquidity( address tokenA, address tokenB, @@ -36,33 +28,6 @@ interface IUniswapV2Router01 { address to, uint deadline ) external returns (uint amountA, uint amountB); - function removeLiquidityETH( - address token, - uint liquidity, - uint amountTokenMin, - uint amountETHMin, - address to, - uint deadline - ) external returns (uint amountToken, uint amountETH); - function removeLiquidityWithPermit( - address tokenA, - address tokenB, - uint liquidity, - uint amountAMin, - uint amountBMin, - address to, - uint deadline, - bool approveMax, uint8 v, bytes32 r, bytes32 s - ) external returns (uint amountA, uint amountB); - function removeLiquidityETHWithPermit( - address token, - uint liquidity, - uint amountTokenMin, - uint amountETHMin, - address to, - uint deadline, - bool approveMax, uint8 v, bytes32 r, bytes32 s - ) external returns (uint amountToken, uint amountETH); function swapExactTokensForTokens( uint amountIn, uint amountOutMin, @@ -77,20 +42,6 @@ interface IUniswapV2Router01 { address to, uint deadline ) external returns (uint[] memory amounts); - function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) - external - payable - returns (uint[] memory amounts); - function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) - external - returns (uint[] memory amounts); - function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) - external - returns (uint[] memory amounts); - function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) - external - payable - returns (uint[] memory amounts); function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); @@ -217,28 +168,32 @@ contract LiquidityHelpers is UniswapHelpers { } function _addLiquidity( - address[] memory tokens, - uint[] memory _amts, - uint[] memory slippages, + address tokenA, + address tokenB, + uint _amt, + uint unitAmt, + uint slippage, uint deadline ) internal returns (uint _amtA, uint _amtB, uint _liquidity) { IUniswapV2Router01 router = IUniswapV2Router01(getUniswapAddr()); - TokenInterface[] memory _tokens = changeEthToWeth(tokens); - _amts[0] = _amts[0] == uint(-1) ? getTokenBalace(tokens[0]) : _amts[0]; - _amts[1] = _amts[1] == uint(-1) ? getTokenBalace(tokens[0]) : _amts[1]; + (TokenInterface _tokenA, TokenInterface _tokenB) = changeEthAddress(tokenA, tokenB); + + _amtA = _amt == uint(-1) ? getTokenBalace(tokenA) : _amt; + uint _amtA18 = convertTo18(_tokenA.decimals(), _amtA); + _amtB = convert18ToDec(_tokenB.decimals(), wmul(unitAmt, _amtA18)); + + convertEthToWeth(_tokenA, _amtA); + convertEthToWeth(_tokenB, _amtB); + _tokenA.approve(address(router), _amtA); + _tokenB.approve(address(router), _amtB); - convertEthToWeth(_tokens[0], _amts[0]); - convertEthToWeth(_tokens[1], _amts[1]); - _tokens[0].approve(address(router), _amts[0]); - _tokens[0].approve(address(router), _amts[1]); - (_amtA, _amtB, _liquidity) = router.addLiquidity( - address(_tokens[0]), - address(_tokens[1]), - _amts[0], - _amts[1], - getMinAmount(_tokens[0], _amts[0], slippages[0]), - getMinAmount(_tokens[1], _amts[1], slippages[1]), + address(_tokenA), + address(_tokenB), + _amtA, + _amtB, + getMinAmount(_tokenA, _amtB, slippage), + getMinAmount(_tokenB, _amtB, slippage), address(this), now + deadline // TODO - deadline? ); @@ -281,7 +236,7 @@ contract UniswapLiquidity is LiquidityHelpers { uint amtA, uint amtB, uint uniAmount, - uint[] getId, + uint getId, uint setId ); @@ -296,31 +251,32 @@ contract UniswapLiquidity is LiquidityHelpers { ); function emitDeposit( - address[] memory tokens, + address tokenA, + address tokenB, uint _amtA, uint _amtB, uint _uniAmt, - uint[] memory getIds, + uint getId, uint setId ) internal { emit LogDepositLiquidity( - tokens[0], - tokens[1], + tokenA, + tokenB, _amtA, _amtB, _uniAmt, - getIds, + getId, setId ); bytes32 _eventCode = keccak256("LogDepositLiquidity(address,address,uint256,uint256,uint256,uint256[],uint256)"); bytes memory _eventParam = abi.encode( - tokens[0], - tokens[1], + tokenA, + tokenB, _amtA, _amtB, _uniAmt, - getIds, + getId, setId ); emitEvent(_eventCode, _eventParam); @@ -357,27 +313,27 @@ contract UniswapLiquidity is LiquidityHelpers { } function deposit( - address[] calldata tokens, - uint[] calldata amts, - uint[] calldata slippages, + address tokenA, + address tokenB, + uint amtA, + uint unitAmt, + uint slippage, uint deadline, - uint[] calldata getIds, + uint getId, uint setId ) external payable { - require(tokens.length == 2 && amts.length == 2, "length-is-not-two"); - uint[] memory _amts = new uint[](2); - for (uint i = 0; i < getIds.length; i++) { - _amts[i] = getUint(getIds[i], amts[i]); - } + uint _amt = getUint(getId, amtA); (uint _amtA, uint _amtB, uint _uniAmt) = _addLiquidity( - tokens, - _amts, - slippages, + tokenA, + tokenB, + _amt, + unitAmt, + slippage, deadline ); setUint(setId, _uniAmt); - emitDeposit(tokens, _amtA, _amtB, _uniAmt, getIds, setId); + emitDeposit(tokenA, tokenB, _amtA, _amtB, _uniAmt, getId, setId); } function withdraw( From 1e7ef1945272a088e5d111f16e753dd108a7e0ee Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Thu, 28 May 2020 04:31:01 +0530 Subject: [PATCH 08/20] Lots of refactoring --- contracts/connectors/uniswapV2.sol | 62 ++++++++++++++++++------------ 1 file changed, 38 insertions(+), 24 deletions(-) diff --git a/contracts/connectors/uniswapV2.sol b/contracts/connectors/uniswapV2.sol index 76cb47b..4d28d42 100644 --- a/contracts/connectors/uniswapV2.sol +++ b/contracts/connectors/uniswapV2.sol @@ -200,32 +200,37 @@ contract LiquidityHelpers is UniswapHelpers { } function _removeLiquidity( - address[] memory tokens, + address tokenA, + address tokenB, uint _amt, - uint[] memory slippages, + uint unitAmtA, + uint unitAmtB, uint deadline ) internal returns (uint _amtA, uint _amtB, uint _uniAmt) { IUniswapV2Router01 router = IUniswapV2Router01(getUniswapAddr()); - TokenInterface[] memory _tokens = changeEthToWeth(tokens); - address exchangeAddr = IUniswapV2Factory(router.factory()).getPair(address(_tokens[0]), address(_tokens[1])); + (TokenInterface _tokenA, TokenInterface _tokenB) = changeEthAddress(tokenA, tokenB); + address exchangeAddr = IUniswapV2Factory(router.factory()).getPair(address(_tokenA), address(_tokenB)); require(exchangeAddr != address(0), "pair-not-found."); TokenInterface uniToken = TokenInterface(exchangeAddr); _uniAmt = _amt == uint(-1) ? uniToken.balanceOf(address(this)) : _amt; uniToken.approve(address(router), _uniAmt); + uint minAmtA = convert18ToDec(_tokenA.decimals(), wmul(unitAmtA, _amt)); + uint minAmtB = convert18ToDec(_tokenB.decimals(), wmul(unitAmtB, _amt)); + (_amtA, _amtB) = router.removeLiquidity( - address(_tokens[0]), - address(_tokens[1]), + address(_tokenA), + address(_tokenB), _amt, - slippages[0], - slippages[1], + minAmtA, + minAmtB, address(this), now + deadline // TODO - deadline? ); - convertWethToEth(_tokens[0], _amtA); - convertWethToEth(_tokens[1], _amtB); + convertWethToEth(_tokenA, _amtA); + convertWethToEth(_tokenB, _amtB); } } @@ -269,7 +274,7 @@ contract UniswapLiquidity is LiquidityHelpers { setId ); - bytes32 _eventCode = keccak256("LogDepositLiquidity(address,address,uint256,uint256,uint256,uint256[],uint256)"); + bytes32 _eventCode = keccak256("LogDepositLiquidity(address,address,uint256,uint256,uint256,uint256,uint256)"); bytes memory _eventParam = abi.encode( tokenA, tokenB, @@ -283,7 +288,8 @@ contract UniswapLiquidity is LiquidityHelpers { } function emitWithdraw( - address[] memory tokens, + address tokenA, + address tokenB, uint _amtA, uint _amtB, uint _uniAmt, @@ -291,18 +297,18 @@ contract UniswapLiquidity is LiquidityHelpers { uint[] memory setIds ) internal { emit LogWithdrawLiquidity( - tokens[0], - tokens[1], + tokenA, + tokenB, _amtA, _amtB, _uniAmt, getId, setIds ); - bytes32 _eventCode = keccak256("LogWithdrawLiquidity(address,address,uint256,uint256,uint256,uint256[],uint256)"); + bytes32 _eventCode = keccak256("LogWithdrawLiquidity(address,address,uint256,uint256,uint256,uint256,uint256[])"); bytes memory _eventParam = abi.encode( - tokens[0], - tokens[1], + tokenA, + tokenB, _amtA, _amtB, _uniAmt, @@ -337,21 +343,29 @@ contract UniswapLiquidity is LiquidityHelpers { } function withdraw( - address[] calldata tokens, - uint amt, - uint[] calldata slippages, + address tokenA, + address tokenB, + uint uinAmt, + uint unitAmtA, + uint unitAmtB, uint deadline, uint getId, uint[] calldata setIds ) external payable { - require(tokens.length == 2, "length-is-not-two"); - uint _amt = getUint(getId, amt); + uint _amt = getUint(getId, uinAmt); - (uint _amtA, uint _amtB, uint _uniAmt) = _removeLiquidity(tokens, _amt, slippages, deadline); + (uint _amtA, uint _amtB, uint _uniAmt) = _removeLiquidity( + tokenA, + tokenB, + _amt, + unitAmtA, + unitAmtB, + deadline + ); setUint(setIds[0], _amtA); setUint(setIds[1], _amtB); - emitWithdraw(tokens, _amtA, _amtB, _uniAmt, getId, setIds); + emitWithdraw(tokenA, tokenB, _amtA, _amtB, _uniAmt, getId, setIds); } } From e664e91a41f9216349ca53856a29041955f3a709 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Fri, 29 May 2020 02:22:37 +0530 Subject: [PATCH 09/20] Minor fix --- contracts/connectors/uniswapV2.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/connectors/uniswapV2.sol b/contracts/connectors/uniswapV2.sol index 4d28d42..4383cf9 100644 --- a/contracts/connectors/uniswapV2.sol +++ b/contracts/connectors/uniswapV2.sol @@ -192,7 +192,7 @@ contract LiquidityHelpers is UniswapHelpers { address(_tokenB), _amtA, _amtB, - getMinAmount(_tokenA, _amtB, slippage), + getMinAmount(_tokenA, _amtA, slippage), getMinAmount(_tokenB, _amtB, slippage), address(this), now + deadline // TODO - deadline? @@ -216,8 +216,8 @@ contract LiquidityHelpers is UniswapHelpers { _uniAmt = _amt == uint(-1) ? uniToken.balanceOf(address(this)) : _amt; uniToken.approve(address(router), _uniAmt); - uint minAmtA = convert18ToDec(_tokenA.decimals(), wmul(unitAmtA, _amt)); - uint minAmtB = convert18ToDec(_tokenB.decimals(), wmul(unitAmtB, _amt)); + uint minAmtA = convert18ToDec(_tokenA.decimals(), wmul(unitAmtA, _uniAmt)); + uint minAmtB = convert18ToDec(_tokenB.decimals(), wmul(unitAmtB, _uniAmt)); (_amtA, _amtB) = router.removeLiquidity( address(_tokenA), From ea7037e2dd6145d8f77f9e42a28eaa7b22c96a53 Mon Sep 17 00:00:00 2001 From: Samyak Jain <34437877+KaymasJain@users.noreply.github.com> Date: Sat, 4 Jul 2020 01:05:48 +1000 Subject: [PATCH 10/20] name change uniswap connector --- contracts/connectors/{uniswapV2.sol => uniswap.sol} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename contracts/connectors/{uniswapV2.sol => uniswap.sol} (99%) diff --git a/contracts/connectors/uniswapV2.sol b/contracts/connectors/uniswap.sol similarity index 99% rename from contracts/connectors/uniswapV2.sol rename to contracts/connectors/uniswap.sol index 4383cf9..b939b04 100644 --- a/contracts/connectors/uniswapV2.sol +++ b/contracts/connectors/uniswap.sol @@ -503,5 +503,5 @@ contract UniswapResolver is UniswapLiquidity { contract ConnectUniswapV2 is UniswapResolver { - string public name = "UniswapV2-v1"; + string public name = "Uniswap-v1"; } \ No newline at end of file From 7c9faf98df2e744bcc8718f5c7cbcce46a5ff5d5 Mon Sep 17 00:00:00 2001 From: Samyak Jain <34437877+KaymasJain@users.noreply.github.com> Date: Sat, 4 Jul 2020 01:34:58 +1000 Subject: [PATCH 11/20] minor change --- contracts/connectors/uniswap.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/connectors/uniswap.sol b/contracts/connectors/uniswap.sol index b939b04..54d2970 100644 --- a/contracts/connectors/uniswap.sol +++ b/contracts/connectors/uniswap.sol @@ -409,8 +409,8 @@ contract UniswapResolver is UniswapLiquidity { (TokenInterface _buyAddr, TokenInterface _sellAddr) = changeEthAddress(buyAddr, sellAddr); address[] memory paths = getPaths(address(_buyAddr), address(_sellAddr)); - uint __buyAmt18 = convertTo18(_buyAddr.decimals(), _buyAmt); - uint _slippageAmt = convert18ToDec(_sellAddr.decimals(), wmul(unitAmt, __buyAmt18)); + uint _buyAmt18 = convertTo18(_buyAddr.decimals(), _buyAmt); + uint _slippageAmt = convert18ToDec(_sellAddr.decimals(), wmul(unitAmt, _buyAmt18)); IUniswapV2Router01 router = IUniswapV2Router01(getUniswapAddr()); From 51403c47751953042f8809d3b3c314df0de02252 Mon Sep 17 00:00:00 2001 From: Samyak Jain <34437877+KaymasJain@users.noreply.github.com> Date: Sat, 4 Jul 2020 01:53:12 +1000 Subject: [PATCH 12/20] fixed bug on sell --- contracts/connectors/uniswap.sol | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/contracts/connectors/uniswap.sol b/contracts/connectors/uniswap.sol index 54d2970..d54c104 100644 --- a/contracts/connectors/uniswap.sol +++ b/contracts/connectors/uniswap.sol @@ -164,7 +164,6 @@ contract LiquidityHelpers is UniswapHelpers { _tokens = new TokenInterface[](2); _tokens[0] = tokens[0] == getEthAddr() ? TokenInterface(getAddressWETH()) : TokenInterface(tokens[0]); _tokens[1] = tokens[1] == getEthAddr() ? TokenInterface(getAddressWETH()) : TokenInterface(tokens[1]); - } function _addLiquidity( @@ -264,7 +263,7 @@ contract UniswapLiquidity is LiquidityHelpers { uint getId, uint setId ) internal { - emit LogDepositLiquidity( + emit LogDepositLiquidity( tokenA, tokenB, _amtA, @@ -296,7 +295,7 @@ contract UniswapLiquidity is LiquidityHelpers { uint getId, uint[] memory setIds ) internal { - emit LogWithdrawLiquidity( + emit LogWithdrawLiquidity( tokenA, tokenB, _amtA, @@ -353,7 +352,7 @@ contract UniswapLiquidity is LiquidityHelpers { uint[] calldata setIds ) external payable { uint _amt = getUint(getId, uinAmt); - + (uint _amtA, uint _amtB, uint _uniAmt) = _removeLiquidity( tokenA, tokenB, @@ -474,7 +473,7 @@ contract UniswapResolver is UniswapLiquidity { checkPair(router, paths); uint _expectedAmt = getExpectedBuyAmt(router, paths, _sellAmt); - require(_slippageAmt >= _expectedAmt, "Too much slippage"); + require(_slippageAmt <= _expectedAmt, "Too much slippage"); convertEthToWeth(_sellAddr, _sellAmt); _sellAddr.approve(address(router), _sellAmt); From 4f4e38b3f71c5a678246c91d40f35e2561b7c62f Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Sat, 4 Jul 2020 03:27:01 +0530 Subject: [PATCH 13/20] Fixed deadline --- contracts/connectors/uniswap.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/connectors/uniswap.sol b/contracts/connectors/uniswap.sol index d54c104..c1e56b7 100644 --- a/contracts/connectors/uniswap.sol +++ b/contracts/connectors/uniswap.sol @@ -425,7 +425,7 @@ contract UniswapResolver is UniswapLiquidity { _expectedAmt, paths, address(this), - now + 6 hours // TODO - deadline? + now + 1 ); uint _sellAmt = _amts[0]; @@ -483,7 +483,7 @@ contract UniswapResolver is UniswapLiquidity { _expectedAmt, paths, address(this), - now + 6 hours // TODO - deadline? + now + 1 ); uint _buyAmt = _amts[1]; From cbc7a2e78241bede08862d84b12b64897f090b41 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Sat, 4 Jul 2020 03:28:16 +0530 Subject: [PATCH 14/20] Updated uniswap router address --- contracts/connectors/uniswap.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/connectors/uniswap.sol b/contracts/connectors/uniswap.sol index c1e56b7..540ab4d 100644 --- a/contracts/connectors/uniswap.sol +++ b/contracts/connectors/uniswap.sol @@ -73,7 +73,7 @@ contract UniswapHelpers is Stores, DSMath { * @dev Return uniswap v2 router Address */ function getUniswapAddr() internal pure returns (address) { - return 0x794e6e91555438aFc3ccF1c5076A74F42133d08D; + return 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D; } function convert18ToDec(uint _dec, uint256 _amt) internal pure returns (uint256 amt) { From 489fc8b69a0ce1e3d8f72da62fa159721c6d91aa Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Mon, 6 Jul 2020 15:29:35 +0530 Subject: [PATCH 15/20] Fixed minor bugs --- contracts/connectors/uniswap.sol | 34 ++++++++++++++++---------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/contracts/connectors/uniswap.sol b/contracts/connectors/uniswap.sol index 540ab4d..5bdc84a 100644 --- a/contracts/connectors/uniswap.sol +++ b/contracts/connectors/uniswap.sol @@ -5,7 +5,7 @@ import { TokenInterface , MemoryInterface, EventInterface} from "../common/inter import { Stores } from "../common/stores.sol"; import { DSMath } from "../common/math.sol"; -interface IUniswapV2Router01 { +interface IUniswapV2Router02 { function factory() external pure returns (address); function WETH() external pure returns (address); @@ -70,7 +70,7 @@ contract UniswapHelpers is Stores, DSMath { } /** - * @dev Return uniswap v2 router Address + * @dev Return uniswap v2 router02 Address */ function getUniswapAddr() internal pure returns (address) { return 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D; @@ -105,7 +105,7 @@ contract UniswapHelpers is Stores, DSMath { } function getExpectedBuyAmt( - IUniswapV2Router01 router, + IUniswapV2Router02 router, address[] memory paths, uint sellAmt ) internal view returns(uint buyAmt) { @@ -117,19 +117,19 @@ contract UniswapHelpers is Stores, DSMath { } function getExpectedSellAmt( - IUniswapV2Router01 router, + IUniswapV2Router02 router, address[] memory paths, uint buyAmt ) internal view returns(uint sellAmt) { - uint[] memory amts = router.getAmountsOut( + uint[] memory amts = router.getAmountsIn( buyAmt, paths ); - sellAmt = amts[1]; + sellAmt = amts[0]; } function checkPair( - IUniswapV2Router01 router, + IUniswapV2Router02 router, address[] memory paths ) internal view { address pair = IUniswapV2Factory(router.factory()).getPair(paths[0], paths[1]); @@ -137,8 +137,8 @@ contract UniswapHelpers is Stores, DSMath { } function getPaths( - address sellAddr, - address buyAddr + address buyAddr, + address sellAddr ) internal pure returns(address[] memory paths) { paths = new address[](2); paths[0] = address(sellAddr); @@ -174,7 +174,7 @@ contract LiquidityHelpers is UniswapHelpers { uint slippage, uint deadline ) internal returns (uint _amtA, uint _amtB, uint _liquidity) { - IUniswapV2Router01 router = IUniswapV2Router01(getUniswapAddr()); + IUniswapV2Router02 router = IUniswapV2Router02(getUniswapAddr()); (TokenInterface _tokenA, TokenInterface _tokenB) = changeEthAddress(tokenA, tokenB); _amtA = _amt == uint(-1) ? getTokenBalace(tokenA) : _amt; @@ -206,7 +206,7 @@ contract LiquidityHelpers is UniswapHelpers { uint unitAmtB, uint deadline ) internal returns (uint _amtA, uint _amtB, uint _uniAmt) { - IUniswapV2Router01 router = IUniswapV2Router01(getUniswapAddr()); + IUniswapV2Router02 router = IUniswapV2Router02(getUniswapAddr()); (TokenInterface _tokenA, TokenInterface _tokenB) = changeEthAddress(tokenA, tokenB); address exchangeAddr = IUniswapV2Factory(router.factory()).getPair(address(_tokenA), address(_tokenB)); require(exchangeAddr != address(0), "pair-not-found."); @@ -408,10 +408,10 @@ contract UniswapResolver is UniswapLiquidity { (TokenInterface _buyAddr, TokenInterface _sellAddr) = changeEthAddress(buyAddr, sellAddr); address[] memory paths = getPaths(address(_buyAddr), address(_sellAddr)); - uint _buyAmt18 = convertTo18(_buyAddr.decimals(), _buyAmt); - uint _slippageAmt = convert18ToDec(_sellAddr.decimals(), wmul(unitAmt, _buyAmt18)); + uint _slippageAmt = convert18ToDec(_sellAddr.decimals(), + wmul(unitAmt, convertTo18(_buyAddr.decimals(), _buyAmt))); - IUniswapV2Router01 router = IUniswapV2Router01(getUniswapAddr()); + IUniswapV2Router02 router = IUniswapV2Router02(getUniswapAddr()); checkPair(router, paths); uint _expectedAmt = getExpectedSellAmt(router, paths, _buyAmt); @@ -466,10 +466,10 @@ contract UniswapResolver is UniswapLiquidity { _sellAmt = sellAddr == getEthAddr() ? address(this).balance : _sellAddr.balanceOf(address(this)); } - uint _sellAmt18 = convertTo18(_sellAddr.decimals(), _sellAmt); - uint _slippageAmt = convert18ToDec(_buyAddr.decimals(), wmul(unitAmt, _sellAmt18)); + uint _slippageAmt = convert18ToDec(_buyAddr.decimals(), + wmul(unitAmt, convertTo18(_sellAddr.decimals(), _sellAmt))); - IUniswapV2Router01 router = IUniswapV2Router01(getUniswapAddr()); + IUniswapV2Router02 router = IUniswapV2Router02(getUniswapAddr()); checkPair(router, paths); uint _expectedAmt = getExpectedBuyAmt(router, paths, _sellAmt); From 3d6d1e21e2fcff669ec39b4b43239017de9618b8 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Mon, 6 Jul 2020 15:31:37 +0530 Subject: [PATCH 16/20] Fixed stack too deep error --- contracts/connectors/uniswap.sol | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/contracts/connectors/uniswap.sol b/contracts/connectors/uniswap.sol index 5bdc84a..94879cb 100644 --- a/contracts/connectors/uniswap.sol +++ b/contracts/connectors/uniswap.sol @@ -420,15 +420,13 @@ contract UniswapResolver is UniswapLiquidity { convertEthToWeth(_sellAddr, _expectedAmt); _sellAddr.approve(address(router), _expectedAmt); - uint[] memory _amts = router.swapTokensForExactTokens( + uint _sellAmt = router.swapTokensForExactTokens( _buyAmt, _expectedAmt, paths, address(this), now + 1 - ); - - uint _sellAmt = _amts[0]; + )[0]; convertWethToEth(_buyAddr, _buyAmt); @@ -478,15 +476,13 @@ contract UniswapResolver is UniswapLiquidity { convertEthToWeth(_sellAddr, _sellAmt); _sellAddr.approve(address(router), _sellAmt); - uint[] memory _amts = router.swapExactTokensForTokens( + uint _buyAmt = router.swapExactTokensForTokens( _sellAmt, _expectedAmt, paths, address(this), now + 1 - ); - - uint _buyAmt = _amts[1]; + )[1]; convertWethToEth(_buyAddr, _buyAmt); From 668d0457b186ececb8c89506f398e45345b0a6d0 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Mon, 6 Jul 2020 16:18:22 +0530 Subject: [PATCH 17/20] Fixed stack too deep error --- contracts/connectors/uniswap.sol | 59 ++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/contracts/connectors/uniswap.sol b/contracts/connectors/uniswap.sol index 94879cb..27319c0 100644 --- a/contracts/connectors/uniswap.sol +++ b/contracts/connectors/uniswap.sol @@ -171,15 +171,13 @@ contract LiquidityHelpers is UniswapHelpers { address tokenB, uint _amt, uint unitAmt, - uint slippage, - uint deadline + uint slippage ) internal returns (uint _amtA, uint _amtB, uint _liquidity) { IUniswapV2Router02 router = IUniswapV2Router02(getUniswapAddr()); (TokenInterface _tokenA, TokenInterface _tokenB) = changeEthAddress(tokenA, tokenB); _amtA = _amt == uint(-1) ? getTokenBalace(tokenA) : _amt; - uint _amtA18 = convertTo18(_tokenA.decimals(), _amtA); - _amtB = convert18ToDec(_tokenB.decimals(), wmul(unitAmt, _amtA18)); + _amtB = convert18ToDec(_tokenB.decimals(), wmul(unitAmt, convertTo18(_tokenA.decimals(), _amtA))); convertEthToWeth(_tokenA, _amtA); convertEthToWeth(_tokenB, _amtB); @@ -194,7 +192,7 @@ contract LiquidityHelpers is UniswapHelpers { getMinAmount(_tokenA, _amtA, slippage), getMinAmount(_tokenB, _amtB, slippage), address(this), - now + deadline // TODO - deadline? + now + 1 ); } @@ -203,34 +201,47 @@ contract LiquidityHelpers is UniswapHelpers { address tokenB, uint _amt, uint unitAmtA, - uint unitAmtB, - uint deadline + uint unitAmtB ) internal returns (uint _amtA, uint _amtB, uint _uniAmt) { - IUniswapV2Router02 router = IUniswapV2Router02(getUniswapAddr()); - (TokenInterface _tokenA, TokenInterface _tokenB) = changeEthAddress(tokenA, tokenB); - address exchangeAddr = IUniswapV2Factory(router.factory()).getPair(address(_tokenA), address(_tokenB)); - require(exchangeAddr != address(0), "pair-not-found."); - - TokenInterface uniToken = TokenInterface(exchangeAddr); - _uniAmt = _amt == uint(-1) ? uniToken.balanceOf(address(this)) : _amt; - uniToken.approve(address(router), _uniAmt); - + IUniswapV2Router02 router; + TokenInterface _tokenA; + TokenInterface _tokenB; + (router, _tokenA, _tokenB, _uniAmt) = _getRemoveLiquidityData( + tokenA, + tokenB, + _amt + ); + { uint minAmtA = convert18ToDec(_tokenA.decimals(), wmul(unitAmtA, _uniAmt)); uint minAmtB = convert18ToDec(_tokenB.decimals(), wmul(unitAmtB, _uniAmt)); - - (_amtA, _amtB) = router.removeLiquidity( + (_amtA, _amtB) = router.removeLiquidity( address(_tokenA), address(_tokenB), _amt, minAmtA, minAmtB, address(this), - now + deadline // TODO - deadline? + now + 1 ); - + } convertWethToEth(_tokenA, _amtA); convertWethToEth(_tokenB, _amtB); } + + function _getRemoveLiquidityData( + address tokenA, + address tokenB, + uint _amt + ) internal returns (IUniswapV2Router02 router, TokenInterface _tokenA, TokenInterface _tokenB, uint _uniAmt) { + router = IUniswapV2Router02(getUniswapAddr()); + (_tokenA, _tokenB) = changeEthAddress(tokenA, tokenB); + address exchangeAddr = IUniswapV2Factory(router.factory()).getPair(address(_tokenA), address(_tokenB)); + require(exchangeAddr != address(0), "pair-not-found."); + + TokenInterface uniToken = TokenInterface(exchangeAddr); + _uniAmt = _amt == uint(-1) ? uniToken.balanceOf(address(this)) : _amt; + uniToken.approve(address(router), _uniAmt); + } } contract UniswapLiquidity is LiquidityHelpers { @@ -323,7 +334,6 @@ contract UniswapLiquidity is LiquidityHelpers { uint amtA, uint unitAmt, uint slippage, - uint deadline, uint getId, uint setId ) external payable { @@ -334,8 +344,7 @@ contract UniswapLiquidity is LiquidityHelpers { tokenB, _amt, unitAmt, - slippage, - deadline + slippage ); setUint(setId, _uniAmt); emitDeposit(tokenA, tokenB, _amtA, _amtB, _uniAmt, getId, setId); @@ -347,7 +356,6 @@ contract UniswapLiquidity is LiquidityHelpers { uint uinAmt, uint unitAmtA, uint unitAmtB, - uint deadline, uint getId, uint[] calldata setIds ) external payable { @@ -358,8 +366,7 @@ contract UniswapLiquidity is LiquidityHelpers { tokenB, _amt, unitAmtA, - unitAmtB, - deadline + unitAmtB ); setUint(setIds[0], _amtA); From 48b7703c592277f4aab07d004ebb904fe33a760b Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Mon, 6 Jul 2020 16:22:56 +0530 Subject: [PATCH 18/20] Minor changes --- contracts/connectors/uniswap.sol | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/contracts/connectors/uniswap.sol b/contracts/connectors/uniswap.sol index 27319c0..5cefcf5 100644 --- a/contracts/connectors/uniswap.sol +++ b/contracts/connectors/uniswap.sol @@ -184,13 +184,15 @@ contract LiquidityHelpers is UniswapHelpers { _tokenA.approve(address(router), _amtA); _tokenB.approve(address(router), _amtB); + uint minAmtA = getMinAmount(_tokenA, _amtA, slippage); + uint minAmtB = getMinAmount(_tokenB, _amtB, slippage); (_amtA, _amtB, _liquidity) = router.addLiquidity( address(_tokenA), address(_tokenB), _amtA, _amtB, - getMinAmount(_tokenA, _amtA, slippage), - getMinAmount(_tokenB, _amtB, slippage), + minAmtA, + minAmtB, address(this), now + 1 ); From e9d74b2ba19304bdb15ae93566a33e3132865250 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Wed, 8 Jul 2020 15:41:00 +0530 Subject: [PATCH 19/20] Fixed bug --- contracts/connectors/uniswap.sol | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/contracts/connectors/uniswap.sol b/contracts/connectors/uniswap.sol index 5cefcf5..4400593 100644 --- a/contracts/connectors/uniswap.sol +++ b/contracts/connectors/uniswap.sol @@ -219,7 +219,7 @@ contract LiquidityHelpers is UniswapHelpers { (_amtA, _amtB) = router.removeLiquidity( address(_tokenA), address(_tokenB), - _amt, + _uniAmt, minAmtA, minAmtB, address(this), @@ -330,6 +330,16 @@ contract UniswapLiquidity is LiquidityHelpers { emitEvent(_eventCode, _eventParam); } + /** + * @dev Deposit Liquidity. + * @param tokenA tokenA address.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param tokenB tokenB address.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param amtA tokenA amount. + * @param unitAmt unit amount of amtB/amtA with slippage. + * @param slippage slippage amount. + * @param getId Get token amount at this ID from `InstaMemory` Contract. + * @param setId Set token amount at this ID in `InstaMemory` Contract. + */ function deposit( address tokenA, address tokenB, @@ -352,6 +362,16 @@ contract UniswapLiquidity is LiquidityHelpers { emitDeposit(tokenA, tokenB, _amtA, _amtB, _uniAmt, getId, setId); } + /** + * @dev Withdraw Liquidity. + * @param tokenA tokenA address.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param tokenB tokenB address.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param uinAmt uni token amount. + * @param unitAmtA unit amount of amtA/uinAmt with slippage. + * @param unitAmtB unit amount of amtB/uinAmt with slippage. + * @param getId Get token amount at this ID from `InstaMemory` Contract. + * @param setIds Set token amounts at this IDs in `InstaMemory` Contract. + */ function withdraw( address tokenA, address tokenB, @@ -507,5 +527,5 @@ contract UniswapResolver is UniswapLiquidity { contract ConnectUniswapV2 is UniswapResolver { - string public name = "Uniswap-v1"; + string public name = "UniswapV2-v1"; } \ No newline at end of file From 96ed4f62ddee3de26d999f287c97e787fa1c9df1 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Wed, 8 Jul 2020 22:44:51 +0530 Subject: [PATCH 20/20] Fixed typo --- contracts/connectors/uniswap.sol | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/contracts/connectors/uniswap.sol b/contracts/connectors/uniswap.sol index 4400593..8c5eacd 100644 --- a/contracts/connectors/uniswap.sol +++ b/contracts/connectors/uniswap.sol @@ -366,22 +366,22 @@ contract UniswapLiquidity is LiquidityHelpers { * @dev Withdraw Liquidity. * @param tokenA tokenA address.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) * @param tokenB tokenB address.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) - * @param uinAmt uni token amount. - * @param unitAmtA unit amount of amtA/uinAmt with slippage. - * @param unitAmtB unit amount of amtB/uinAmt with slippage. + * @param uniAmt uni token amount. + * @param unitAmtA unit amount of amtA/uniAmt with slippage. + * @param unitAmtB unit amount of amtB/uniAmt with slippage. * @param getId Get token amount at this ID from `InstaMemory` Contract. * @param setIds Set token amounts at this IDs in `InstaMemory` Contract. */ function withdraw( address tokenA, address tokenB, - uint uinAmt, + uint uniAmt, uint unitAmtA, uint unitAmtB, uint getId, uint[] calldata setIds ) external payable { - uint _amt = getUint(getId, uinAmt); + uint _amt = getUint(getId, uniAmt); (uint _amtA, uint _amtB, uint _uniAmt) = _removeLiquidity( tokenA,