From 7142e1f9ee5c520c1fbf0555d5119f6543f18aa4 Mon Sep 17 00:00:00 2001 From: Samyak Date: Fri, 22 Mar 2019 01:38:56 +0530 Subject: [PATCH] dexes integration almost done --- contracts/ProxyLogics/dex.sol | 349 ++++++++++++++++++++++++++++++ contracts/ProxyLogics/kyber.sol | 182 +++++++++------- contracts/ProxyLogics/uniswap.sol | 40 ++-- 3 files changed, 462 insertions(+), 109 deletions(-) create mode 100644 contracts/ProxyLogics/dex.sol diff --git a/contracts/ProxyLogics/dex.sol b/contracts/ProxyLogics/dex.sol new file mode 100644 index 0000000..5f70491 --- /dev/null +++ b/contracts/ProxyLogics/dex.sol @@ -0,0 +1,349 @@ +pragma solidity 0.5.0; + + +import "./safemath.sol"; + +interface IERC20 { + function balanceOf(address who) external view returns (uint256); + function allowance(address _owner, address _spender) external view returns (uint256); + function transfer(address to, uint256 value) external returns (bool); + function approve(address spender, uint256 value) external returns (bool); + function transferFrom(address from, address to, uint256 value) external returns (bool); +} + +interface AddressRegistry { + function getAddr(string calldata name) external view returns (address); +} + +// Kyber's contract Interface +interface KyberExchange { + // Kyber's trade function + function trade(address src, uint srcAmount, address dest, address destAddress, uint maxDestAmount, uint minConversionRate, address walletId) external payable returns (uint); + // Kyber's Get expected Rate function + function getExpectedRate(address src, address dest, uint srcQty) external view returns (uint, uint); +} + +// Uniswap's factory Interface +interface UniswapFactory { + // get exchange from token's address + function getExchange(address token) external view returns (address exchange); +} + +// Uniswap's exchange Interface +interface UniswapExchange { + // Get Prices + function getEthToTokenInputPrice(uint256 eth_sold) external view returns (uint256 tokens_bought); + function getEthToTokenOutputPrice(uint256 tokens_bought) external view returns (uint256 eth_sold); + function getTokenToEthInputPrice(uint256 tokens_sold) external view returns (uint256 eth_bought); + function getTokenToEthOutputPrice(uint256 eth_bought) external view returns (uint256 tokens_sold); + // Trade ETH to ERC20 + function ethToTokenTransferInput(uint256 min_tokens, uint256 deadline, address recipient) external payable returns (uint256 tokens_bought); + function ethToTokenTransferOutput(uint256 tokens_bought, uint256 deadline, address recipient) external payable returns (uint256 eth_sold); + // Trade ERC20 to ETH + function tokenToEthTransferInput(uint256 tokens_sold, uint256 min_tokens, uint256 deadline, address recipient) external returns (uint256 eth_bought); + function tokenToEthTransferOutput(uint256 eth_bought, uint256 max_tokens, uint256 deadline, address recipient) external returns (uint256 tokens_sold); + // Trade ERC20 to ERC20 + function tokenToTokenTransferInput(uint256 tokens_sold, uint256 min_tokens_bought, uint256 min_eth_bought, uint256 deadline, address recipient, address token_addr) external returns (uint256 tokens_bought); + function tokenToTokenTransferOutput(uint256 tokens_bought, uint256 max_tokens_sold, uint256 max_eth_sold, uint256 deadline, address recipient, address token_addr) external returns (uint256 tokens_sold); +} + + +contract Registry { + address public addressRegistry; + modifier onlyAdmin() { + require(msg.sender == _getAddress("admin"), "Permission Denied"); + _; + } + function _getAddress(string memory name) internal view returns (address) { + AddressRegistry addrReg = AddressRegistry(addressRegistry); + return addrReg.getAddr(name); + } +} + +// common stuffs in Kyber and Uniswap's trade +contract commonStuffs { + + using SafeMath for uint; + + // Check required ETH Quantity to execute code + function _getToken( + address trader, + address src, + uint srcAmt, + address eth + ) internal returns (uint ethQty) { + if (src == eth) { + require(msg.value == srcAmt, "Invalid Operation"); + ethQty = srcAmt; + } else { + IERC20 tokenFunctions = IERC20(src); + tokenFunctions.transferFrom(trader, address(this), srcAmt); + ethQty = 0; + } + } + + function _approveDexes(address token, address dexToApprove) internal returns (bool) { + IERC20 tokenFunctions = IERC20(token); + return tokenFunctions.approve(dexToApprove, uint(0-1)); + } + + function _allowance(address token, address spender) internal view returns (uint) { + IERC20 tokenFunctions = IERC20(token); + return tokenFunctions.allowance(address(this), spender); + } + +} + + +// Kyber's dex functions +contract kyber is Registry, commonStuffs { + + function getExpectedRateKyber(address src, address dest, uint srcAmt) public view returns (uint, uint) { + KyberExchange kyberFunctions = KyberExchange(_getAddress("kyber")); + return kyberFunctions.getExpectedRate(src, dest, srcAmt); + } + + function _approveKyber(address token) internal returns (bool) { + address kyberProxy = _getAddress("kyber"); + return _approveDexes(token, kyberProxy); + } + + /** + * @title Kyber's trade when token to sell Amount fixed + * @param src - Token address to sell (for ETH it's "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee") + * @param srcAmt - amount of token for sell + * @param dest - Token address to buy (for ETH it's "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee") + * @param minDestAmt - min amount of token to buy (slippage) + */ + function tradeSrcKyber( + address src, // token to sell + uint srcAmt, // amount of token for sell + address dest, // token to buy + uint minDestAmt // minimum slippage rate + ) public payable returns (uint tokensBought) { + address eth = _getAddress("eth"); + uint ethQty = _getToken( + msg.sender, + src, + srcAmt, + eth + ); + + // Interacting with Kyber Proxy Contract + KyberExchange kyberFunctions = KyberExchange(_getAddress("kyber")); + tokensBought = kyberFunctions.trade.value(ethQty)( + src, + srcAmt, + dest, + msg.sender, + uint(0-1), + minDestAmt, + _getAddress("admin") + ); + + } + + function tradeDestKyber( + address src, // token to sell + uint maxSrcAmt, // amount of token for sell + address dest, // token to buy + uint destAmt // minimum slippage rate + ) public payable returns (uint tokensBought) { + address eth = _getAddress("eth"); + uint ethQty = _getToken( + msg.sender, + src, + maxSrcAmt, + eth + ); + + // Interacting with Kyber Proxy Contract + KyberExchange kyberFunctions = KyberExchange(_getAddress("kyber")); + tokensBought = kyberFunctions.trade.value(ethQty)( + src, + maxSrcAmt, + dest, + msg.sender, + destAmt, + destAmt, + _getAddress("admin") + ); + + // maxDestAmt usecase implementated + if (src == eth && address(this).balance > 0) { + msg.sender.transfer(address(this).balance); + } else if (src != eth) { + // as there is no balanceOf of eth + IERC20 srcTkn = IERC20(src); + uint srcBal = srcTkn.balanceOf(address(this)); + if (srcBal > 0) { + srcTkn.transfer(msg.sender, srcBal); + } + } + + } + +} + + +// Uinswap's dex functions +contract uniswap is Registry, commonStuffs { + + // Get Uniswap's Exchange address from Factory Contract + function _getExchangeAddress(address _token) internal view returns (address) { + UniswapFactory uniswapMain = UniswapFactory(_getAddress("uniswap")); + return uniswapMain.getExchange(_token); + } + + /** + * @title Uniswap's get expected rate from source + * @param src - Token address to sell (for ETH it's "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee") + * @param dest - Token address to buy (for ETH it's "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee") + * @param srcAmt - source token amount + */ + function getExpectedRateSrcUniswap( + address src, + address dest, + uint srcAmt + ) external view returns (uint256) { + address eth = _getAddress("eth"); + if (src == eth) { + // define uniswap exchange with dest address + UniswapExchange exchangeContract = UniswapExchange(_getExchangeAddress(dest)); + return exchangeContract.getEthToTokenInputPrice(srcAmt); + } else if (dest == eth) { + // define uniswap exchange with src address + UniswapExchange exchangeContract = UniswapExchange(_getExchangeAddress(src)); + return exchangeContract.getTokenToEthInputPrice(srcAmt); + } else { + UniswapExchange exchangeContractSrc = UniswapExchange(_getExchangeAddress(src)); + UniswapExchange exchangeContractDest = UniswapExchange(_getExchangeAddress(dest)); + uint ethQty = exchangeContractSrc.getTokenToEthInputPrice(srcAmt); + return exchangeContractDest.getEthToTokenInputPrice(ethQty); + } + } + + /** + * @title Uniswap's get expected rate from dest + * @param src - Token address to sell (for ETH it's "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee") + * @param dest - Token address to buy (for ETH it's "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee") + * @param destAmt - dest token amount + */ + function getExpectedRateDestUniswap( + address src, + address dest, + uint destAmt + ) external view returns (uint256) { + address eth = _getAddress("eth"); + if (src == eth) { + // define uniswap exchange with dest address + UniswapExchange exchangeContract = UniswapExchange(_getExchangeAddress(dest)); + return exchangeContract.getEthToTokenOutputPrice(destAmt); + } else if (dest == eth) { + // define uniswap exchange with src address + UniswapExchange exchangeContract = UniswapExchange(_getExchangeAddress(src)); + return exchangeContract.getTokenToEthOutputPrice(destAmt); + } else { + UniswapExchange exchangeContractSrc = UniswapExchange(_getExchangeAddress(src)); + UniswapExchange exchangeContractDest = UniswapExchange(_getExchangeAddress(dest)); + uint ethQty = exchangeContractDest.getTokenToEthInputPrice(destAmt); + return exchangeContractSrc.getEthToTokenInputPrice(ethQty); + } + } + + + /** + * @title Uniswap's trade when token to sell Amount fixed + * @param src - Token address to sell (for ETH it's "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee") + * @param srcAmt - amount of token for sell + * @param dest - Token address to buy (for ETH it's "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee") + * @param minDestAmt - min amount of token to buy (slippage) + * @param deadline - time for this transaction to be valid + */ + function tradeSrcUniswap( + address src, + uint srcAmt, + address dest, + uint minDestAmt, + uint deadline + ) public payable returns (uint) { + + address eth = _getAddress("eth"); + uint ethQty = _getToken( + msg.sender, + src, + srcAmt, + eth + ); + + if (src == eth) { + UniswapExchange exchangeContract = UniswapExchange(_getExchangeAddress(dest)); + uint tokensBought = exchangeContract.ethToTokenTransferInput.value(ethQty)(minDestAmt, deadline, msg.sender); + return tokensBought; + } else if (dest == eth) { + UniswapExchange exchangeContract = UniswapExchange(_getExchangeAddress(src)); + uint ethBought = exchangeContract.tokenToEthTransferInput(srcAmt, minDestAmt, deadline, msg.sender); + return ethBought; + } else { + UniswapExchange exchangeContract = UniswapExchange(_getExchangeAddress(src)); + uint tokensBought = exchangeContract.tokenToTokenTransferInput(srcAmt, minDestAmt, uint(0), deadline, msg.sender, dest); + return tokensBought; + } + } + + + /** + * @title Uniswap's trade when token to buy Amount fixed + * @param src - Token address to sell (for ETH it's "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee") + * @param maxSrcAmt - max amount of token for sell (slippage) + * @param dest - Token address to buy (for ETH it's "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee") + * @param destAmt - amount of token to buy + * @param deadline - time for this transaction to be valid + */ + function tradeDestUniswap( + address src, + uint maxSrcAmt, + address dest, + uint destAmt, + uint deadline + ) public payable returns (uint) { + + address eth = _getAddress("eth"); + uint ethQty = _getToken( + msg.sender, + src, + maxSrcAmt, + eth + ); + + if (src == eth) { + UniswapExchange exchangeContract = UniswapExchange(_getExchangeAddress(dest)); + uint ethSold = exchangeContract.ethToTokenTransferOutput.value(ethQty)(destAmt, deadline, msg.sender); + if (ethSold < ethQty) { + uint srcToReturn = ethQty - ethSold; + msg.sender.transfer(srcToReturn); + } + return ethSold; + } else if (dest == eth) { + UniswapExchange exchangeContract = UniswapExchange(_getExchangeAddress(src)); + uint tokensSold = exchangeContract.tokenToEthTransferOutput(destAmt, maxSrcAmt, deadline, msg.sender); + if (tokensSold < maxSrcAmt) { + IERC20 srcTkn = IERC20(src); + uint srcToReturn = maxSrcAmt - tokensSold; + srcTkn.transfer(msg.sender, srcToReturn); + } + return tokensSold; + } else { + UniswapExchange exchangeContractSrc = UniswapExchange(_getExchangeAddress(src)); + uint tokensSold = exchangeContractSrc.tokenToTokenTransferOutput(destAmt, maxSrcAmt, uint(0-1), deadline, msg.sender, dest); + if (tokensSold < maxSrcAmt) { + IERC20 srcTkn = IERC20(src); + uint srcToReturn = maxSrcAmt - tokensSold; + srcTkn.transfer(msg.sender, srcToReturn); + } + return tokensSold; + } + + } + +} \ No newline at end of file diff --git a/contracts/ProxyLogics/kyber.sol b/contracts/ProxyLogics/kyber.sol index 47709a1..cfb1530 100644 --- a/contracts/ProxyLogics/kyber.sol +++ b/contracts/ProxyLogics/kyber.sol @@ -15,16 +15,9 @@ interface AddressRegistry { } interface Kyber { - function trade( - address src, - uint srcAmount, - address dest, - address destAddress, - uint maxDestAmount, - uint minConversionRate, - address walletId - ) external payable returns (uint); - + // Kyber's trade function + function trade(address src, uint srcAmount, address dest, address destAddress, uint maxDestAmount, uint minConversionRate, address walletId) external payable returns (uint); + // Kyber's Get expected Rate function function getExpectedRate(address src, address dest, uint srcQty) external view returns (uint, uint); } @@ -32,14 +25,13 @@ interface Kyber { contract Registry { address public addressRegistry; modifier onlyAdmin() { - require(msg.sender == getAddress("admin"), "Permission Denied"); + require(msg.sender == _getAddress("admin"), "Permission Denied"); _; } - function getAddress(string memory name) internal view returns (address) { + function _getAddress(string memory name) internal view returns (address) { AddressRegistry addrReg = AddressRegistry(addressRegistry); return addrReg.getAddr(name); } - } @@ -49,75 +41,7 @@ contract Trade is Registry { event KyberTrade(address src, uint srcAmt, address dest, uint destAmt, address beneficiary, uint minConversionRate, address affiliate); - function getExpectedPrice(address src, address dest, uint srcAmt) public view returns (uint, uint) { - Kyber kyberFunctions = Kyber(getAddress("kyber")); - return kyberFunctions.getExpectedRate(src, dest, srcAmt); - } - - function approveKyber(address[] memory tokenArr) public { - address kyberProxy = getAddress("kyber"); - for (uint i = 0; i < tokenArr.length; i++) { - IERC20 tokenFunctions = IERC20(tokenArr[i]); - tokenFunctions.approve(kyberProxy, 2 ** 256 - 1); - } - } - - function executeTrade( - address src, // token to sell - address dest, // token to buy - uint srcAmt, // amount of token for sell - uint minConversionRate, // minimum slippage rate - uint maxDestAmt // max amount of dest token - ) - public - payable - returns (uint destAmt) - { - address eth = getAddress("eth"); - uint ethQty = getToken( - msg.sender, - src, - srcAmt, - eth - ); - - // Interacting with Kyber Proxy Contract - Kyber kyberFunctions = Kyber(getAddress("kyber")); - destAmt = kyberFunctions.trade.value(ethQty)( - src, - srcAmt, - dest, - msg.sender, - maxDestAmt, - minConversionRate, - getAddress("admin") - ); - - // maxDestAmt usecase implementated - if (src == eth && address(this).balance > 0) { - msg.sender.transfer(address(this).balance); - } else if (src != eth) { - // as there is no balanceOf of eth - IERC20 srcTkn = IERC20(src); - uint srcBal = srcTkn.balanceOf(address(this)); - if (srcBal > 0) { - srcTkn.transfer(msg.sender, srcBal); - } - } - - emit KyberTrade( - src, - srcAmt, - dest, - destAmt, - msg.sender, - minConversionRate, - getAddress("admin") - ); - - } - - function getToken( + function _getToken( address trader, address src, uint srcAmt, @@ -135,6 +59,100 @@ contract Trade is Registry { ethQty = 0; } } + + + function getExpectedRateKyber(address src, address dest, uint srcAmt) public view returns (uint, uint) { + Kyber kyberFunctions = Kyber(_getAddress("kyber")); + return kyberFunctions.getExpectedRate(src, dest, srcAmt); + } + + function approveKyber(address[] memory tokenArr) public { + address kyberProxy = _getAddress("kyber"); + for (uint i = 0; i < tokenArr.length; i++) { + IERC20 tokenFunctions = IERC20(tokenArr[i]); + tokenFunctions.approve(kyberProxy, 2 ** 256 - 1); + } + } + + /** + * @title Kyber's trade when token to sell Amount fixed + * @param src - Token address to sell (for ETH it's "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee") + * @param srcAmt - amount of token for sell + * @param dest - Token address to buy (for ETH it's "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee") + * @param minDestAmt - min amount of token to buy (slippage) + */ + function tradeSrcKyber( + address src, // token to sell + uint srcAmt, // amount of token for sell + address dest, // token to buy + uint minDestAmt // minimum slippage rate + ) public payable returns (uint tokensBought) { + address eth = _getAddress("eth"); + uint ethQty = _getToken( + msg.sender, + src, + srcAmt, + eth + ); + + // Interacting with Kyber Proxy Contract + Kyber kyberFunctions = Kyber(_getAddress("kyber")); + tokensBought = kyberFunctions.trade.value(ethQty)( + src, + srcAmt, + dest, + msg.sender, + uint(0-1), + minDestAmt, + _getAddress("admin") + ); + + emit KyberTrade(src, srcAmt, dest, tokensBought, msg.sender, minDestAmt, _getAddress("admin")); + + } + + function tradeDestKyber( + address src, // token to sell + uint maxSrcAmt, // amount of token for sell + address dest, // token to buy + uint destAmt // minimum slippage rate + ) public payable returns (uint tokensBought) { + address eth = _getAddress("eth"); + uint ethQty = _getToken( + msg.sender, + src, + maxSrcAmt, + eth + ); + + // Interacting with Kyber Proxy Contract + Kyber kyberFunctions = Kyber(_getAddress("kyber")); + tokensBought = kyberFunctions.trade.value(ethQty)( + src, + maxSrcAmt, + dest, + msg.sender, + destAmt, + destAmt, + _getAddress("admin") + ); + + // maxDestAmt usecase implementated + if (src == eth && address(this).balance > 0) { + msg.sender.transfer(address(this).balance); + } else if (src != eth) { + // as there is no balanceOf of eth + IERC20 srcTkn = IERC20(src); + uint srcBal = srcTkn.balanceOf(address(this)); + if (srcBal > 0) { + srcTkn.transfer(msg.sender, srcBal); + } + } + + emit KyberTrade(src, maxSrcAmt, dest, tokensBought, msg.sender, destAmt, _getAddress("admin")); + + } + } diff --git a/contracts/ProxyLogics/uniswap.sol b/contracts/ProxyLogics/uniswap.sol index 82263ca..b01a70b 100644 --- a/contracts/ProxyLogics/uniswap.sol +++ b/contracts/ProxyLogics/uniswap.sol @@ -14,43 +14,28 @@ interface AddressRegistry { function getAddr(string calldata name) external view returns (address); } -interface UniswapFactoryInterface { - // Get Exchange and Token Info +// Uniswap's factory Interface +interface UniswapFactory { + // get exchange from token's address function getExchange(address token) external view returns (address exchange); - function getToken(address exchange) external view returns (address token); } -// Solidity Interface +// Uniswap's exchange Interface interface UniswapExchange { - // Address of ERC20 token sold on this exchange - function tokenAddress() external view returns (address token); - // Address of Uniswap Factory - function factoryAddress() external view returns (address factory); // Get Prices function getEthToTokenInputPrice(uint256 eth_sold) external view returns (uint256 tokens_bought); function getEthToTokenOutputPrice(uint256 tokens_bought) external view returns (uint256 eth_sold); function getTokenToEthInputPrice(uint256 tokens_sold) external view returns (uint256 eth_bought); function getTokenToEthOutputPrice(uint256 eth_bought) external view returns (uint256 tokens_sold); // Trade ETH to ERC20 - function ethToTokenSwapInput(uint256 min_tokens, uint256 deadline) external payable returns (uint256 tokens_bought); function ethToTokenTransferInput(uint256 min_tokens, uint256 deadline, address recipient) external payable returns (uint256 tokens_bought); - function ethToTokenSwapOutput(uint256 tokens_bought, uint256 deadline) external payable returns (uint256 eth_sold); function ethToTokenTransferOutput(uint256 tokens_bought, uint256 deadline, address recipient) external payable returns (uint256 eth_sold); // Trade ERC20 to ETH - function tokenToEthSwapInput(uint256 tokens_sold, uint256 min_eth, uint256 deadline) external returns (uint256 eth_bought); function tokenToEthTransferInput(uint256 tokens_sold, uint256 min_tokens, uint256 deadline, address recipient) external returns (uint256 eth_bought); - function tokenToEthSwapOutput(uint256 eth_bought, uint256 max_tokens, uint256 deadline) external returns (uint256 tokens_sold); function tokenToEthTransferOutput(uint256 eth_bought, uint256 max_tokens, uint256 deadline, address recipient) external returns (uint256 tokens_sold); // Trade ERC20 to ERC20 - function tokenToTokenSwapInput(uint256 tokens_sold, uint256 min_tokens_bought, uint256 min_eth_bought, uint256 deadline, address token_addr) external returns (uint256 tokens_bought); function tokenToTokenTransferInput(uint256 tokens_sold, uint256 min_tokens_bought, uint256 min_eth_bought, uint256 deadline, address recipient, address token_addr) external returns (uint256 tokens_bought); - function tokenToTokenSwapOutput(uint256 tokens_bought, uint256 max_tokens_sold, uint256 max_eth_sold, uint256 deadline, address token_addr) external returns (uint256 tokens_sold); function tokenToTokenTransferOutput(uint256 tokens_bought, uint256 max_tokens_sold, uint256 max_eth_sold, uint256 deadline, address recipient, address token_addr) external returns (uint256 tokens_sold); - // Trade ERC20 to Custom Pool - function tokenToExchangeSwapInput(uint256 tokens_sold, uint256 min_tokens_bought, uint256 min_eth_bought, uint256 deadline, address exchange_addr) external returns (uint256 tokens_bought); - function tokenToExchangeTransferInput(uint256 tokens_sold, uint256 min_tokens_bought, uint256 min_eth_bought, uint256 deadline, address recipient, address exchange_addr) external returns (uint256 tokens_bought); - function tokenToExchangeSwapOutput(uint256 tokens_bought, uint256 max_tokens_sold, uint256 max_eth_sold, uint256 deadline, address exchange_addr) external returns (uint256 tokens_sold); - function tokenToExchangeTransferOutput(uint256 tokens_bought, uint256 max_tokens_sold, uint256 max_eth_sold, uint256 deadline, address recipient, address exchange_addr) external returns (uint256 tokens_sold); } @@ -64,16 +49,16 @@ contract Registry { AddressRegistry addrReg = AddressRegistry(addressRegistry); return addrReg.getAddr(name); } - } + contract Trade is Registry { using SafeMath for uint; // Get Uniswap's Exchange address from Factory Contract function _getExchangeAddress(address _token) internal view returns (address) { - UniswapFactoryInterface uniswapMain = UniswapFactoryInterface(getAddress("uniswap")); + UniswapFactory uniswapMain = UniswapFactory(getAddress("uniswap")); return uniswapMain.getExchange(_token); } @@ -104,7 +89,11 @@ contract Trade is Registry { * @param dest - Token address to buy (for ETH it's "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee") * @param srcAmt - source token amount */ - function getExpectedRateSrcUniswap(address src, address dest, uint srcAmt) external view returns (uint256) { + function getExpectedRateSrcUniswap( + address src, + address dest, + uint srcAmt + ) external view returns (uint256) { if (src == getAddress("eth")) { // define uniswap exchange with dest address UniswapExchange exchangeContract = UniswapExchange(_getExchangeAddress(dest)); @@ -184,7 +173,6 @@ contract Trade is Registry { return ethBought; } else { UniswapExchange exchangeContract = UniswapExchange(_getExchangeAddress(src)); - uint ethBought = exchangeContract.getTokenToEthInputPrice(srcAmt); uint tokensBought = exchangeContract.tokenToTokenTransferInput(srcAmt, minDestAmt, uint(0), deadline, msg.sender, dest); return tokensBought; } @@ -217,7 +205,7 @@ contract Trade is Registry { if (src == eth) { UniswapExchange exchangeContract = UniswapExchange(_getExchangeAddress(dest)); - uint ethSold = exchangeContract.ethToTokenTransferInput.value(ethQty)(destAmt, deadline, msg.sender); + uint ethSold = exchangeContract.ethToTokenTransferOutput.value(ethQty)(destAmt, deadline, msg.sender); if (ethSold < ethQty) { uint srcToReturn = ethQty - ethSold; msg.sender.transfer(srcToReturn); @@ -225,7 +213,7 @@ contract Trade is Registry { return ethSold; } else if (dest == eth) { UniswapExchange exchangeContract = UniswapExchange(_getExchangeAddress(src)); - uint tokensSold = exchangeContract.tokenToEthTransferInput(destAmt, maxSrcAmt, deadline, msg.sender); + uint tokensSold = exchangeContract.tokenToEthTransferOutput(destAmt, maxSrcAmt, deadline, msg.sender); if (tokensSold < maxSrcAmt) { IERC20 srcTkn = IERC20(src); uint srcToReturn = maxSrcAmt - tokensSold; @@ -234,8 +222,6 @@ contract Trade is Registry { return tokensSold; } else { UniswapExchange exchangeContractSrc = UniswapExchange(_getExchangeAddress(src)); - UniswapExchange exchangeContractdest = UniswapExchange(_getExchangeAddress(dest)); - uint ethBought = exchangeContractdest.getTokenToEthInputPrice(destAmt); uint tokensSold = exchangeContractSrc.tokenToTokenTransferOutput(destAmt, maxSrcAmt, uint(0-1), deadline, msg.sender, dest); if (tokensSold < maxSrcAmt) { IERC20 srcTkn = IERC20(src);