mirror of
				https://github.com/Instadapp/smart-contract.git
				synced 2024-07-29 22:08:07 +00:00 
			
		
		
		
	dexes integration almost done
This commit is contained in:
		
							parent
							
								
									5b2ae84dab
								
							
						
					
					
						commit
						7142e1f9ee
					
				
							
								
								
									
										349
									
								
								contracts/ProxyLogics/dex.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										349
									
								
								contracts/ProxyLogics/dex.sol
									
									
									
									
									
										Normal file
									
								
							|  | @ -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; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -15,16 +15,9 @@ interface AddressRegistry { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| interface Kyber { | interface Kyber { | ||||||
|     function trade( |     // Kyber's trade function | ||||||
|         address src, |     function trade(address src, uint srcAmount, address dest, address destAddress, uint maxDestAmount, uint minConversionRate, address walletId) external payable returns (uint); | ||||||
|         uint srcAmount, |     // Kyber's Get expected Rate function | ||||||
|         address dest, |  | ||||||
|         address destAddress, |  | ||||||
|         uint maxDestAmount, |  | ||||||
|         uint minConversionRate, |  | ||||||
|         address walletId |  | ||||||
|     ) external payable returns (uint); |  | ||||||
| 
 |  | ||||||
|     function getExpectedRate(address src, address dest, uint srcQty) external view returns (uint, uint); |     function getExpectedRate(address src, address dest, uint srcQty) external view returns (uint, uint); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -32,14 +25,13 @@ interface Kyber { | ||||||
| contract Registry { | contract Registry { | ||||||
|     address public addressRegistry; |     address public addressRegistry; | ||||||
|     modifier onlyAdmin() { |     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); |         AddressRegistry addrReg = AddressRegistry(addressRegistry); | ||||||
|         return addrReg.getAddr(name); |         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); |     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) { |     function _getToken( | ||||||
|         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( |  | ||||||
|         address trader, |         address trader, | ||||||
|         address src, |         address src, | ||||||
|         uint srcAmt, |         uint srcAmt, | ||||||
|  | @ -135,6 +59,100 @@ contract Trade is Registry { | ||||||
|             ethQty = 0; |             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")); | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -14,43 +14,28 @@ interface AddressRegistry { | ||||||
|     function getAddr(string calldata name) external view returns (address); |     function getAddr(string calldata name) external view returns (address); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| interface UniswapFactoryInterface { | // Uniswap's factory Interface | ||||||
|     // Get Exchange and Token Info | interface UniswapFactory { | ||||||
|  |     // get exchange from token's address | ||||||
|     function getExchange(address token) external view returns (address exchange); |     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 { | 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 |     // Get Prices | ||||||
|     function getEthToTokenInputPrice(uint256 eth_sold) external view returns (uint256 tokens_bought); |     function getEthToTokenInputPrice(uint256 eth_sold) external view returns (uint256 tokens_bought); | ||||||
|     function getEthToTokenOutputPrice(uint256 tokens_bought) external view returns (uint256 eth_sold); |     function getEthToTokenOutputPrice(uint256 tokens_bought) external view returns (uint256 eth_sold); | ||||||
|     function getTokenToEthInputPrice(uint256 tokens_sold) external view returns (uint256 eth_bought); |     function getTokenToEthInputPrice(uint256 tokens_sold) external view returns (uint256 eth_bought); | ||||||
|     function getTokenToEthOutputPrice(uint256 eth_bought) external view returns (uint256 tokens_sold); |     function getTokenToEthOutputPrice(uint256 eth_bought) external view returns (uint256 tokens_sold); | ||||||
|     // Trade ETH to ERC20 |     // 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 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); |     function ethToTokenTransferOutput(uint256 tokens_bought, uint256 deadline, address recipient) external payable returns (uint256  eth_sold); | ||||||
|     // Trade ERC20 to ETH |     // 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 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); |     function tokenToEthTransferOutput(uint256 eth_bought, uint256 max_tokens, uint256 deadline, address recipient) external returns (uint256  tokens_sold); | ||||||
|     // Trade ERC20 to ERC20 |     // 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 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); |     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); |         AddressRegistry addrReg = AddressRegistry(addressRegistry); | ||||||
|         return addrReg.getAddr(name); |         return addrReg.getAddr(name); | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| contract Trade is Registry { | contract Trade is Registry { | ||||||
|      |      | ||||||
|     using SafeMath for uint; |     using SafeMath for uint; | ||||||
| 
 | 
 | ||||||
|     // Get Uniswap's Exchange address from Factory Contract |     // Get Uniswap's Exchange address from Factory Contract | ||||||
|     function _getExchangeAddress(address _token) internal view returns (address) { |     function _getExchangeAddress(address _token) internal view returns (address) { | ||||||
|         UniswapFactoryInterface uniswapMain = UniswapFactoryInterface(getAddress("uniswap")); |         UniswapFactory uniswapMain = UniswapFactory(getAddress("uniswap")); | ||||||
|         return uniswapMain.getExchange(_token); |         return uniswapMain.getExchange(_token); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -104,7 +89,11 @@ contract Trade is Registry { | ||||||
|      * @param dest - Token address to buy (for ETH it's "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee") |      * @param dest - Token address to buy (for ETH it's "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee") | ||||||
|      * @param srcAmt - source token amount |      * @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")) { |         if (src == getAddress("eth")) { | ||||||
|             // define uniswap exchange with dest address |             // define uniswap exchange with dest address | ||||||
|             UniswapExchange exchangeContract = UniswapExchange(_getExchangeAddress(dest)); |             UniswapExchange exchangeContract = UniswapExchange(_getExchangeAddress(dest)); | ||||||
|  | @ -184,7 +173,6 @@ contract Trade is Registry { | ||||||
|             return ethBought; |             return ethBought; | ||||||
|         } else { |         } else { | ||||||
|             UniswapExchange exchangeContract = UniswapExchange(_getExchangeAddress(src)); |             UniswapExchange exchangeContract = UniswapExchange(_getExchangeAddress(src)); | ||||||
|             uint ethBought = exchangeContract.getTokenToEthInputPrice(srcAmt); |  | ||||||
|             uint tokensBought = exchangeContract.tokenToTokenTransferInput(srcAmt, minDestAmt, uint(0), deadline, msg.sender, dest); |             uint tokensBought = exchangeContract.tokenToTokenTransferInput(srcAmt, minDestAmt, uint(0), deadline, msg.sender, dest); | ||||||
|             return tokensBought; |             return tokensBought; | ||||||
|         } |         } | ||||||
|  | @ -217,7 +205,7 @@ contract Trade is Registry { | ||||||
| 
 | 
 | ||||||
|         if (src == eth) { |         if (src == eth) { | ||||||
|             UniswapExchange exchangeContract = UniswapExchange(_getExchangeAddress(dest)); |             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) { |             if (ethSold < ethQty) { | ||||||
|                 uint srcToReturn = ethQty - ethSold; |                 uint srcToReturn = ethQty - ethSold; | ||||||
|                 msg.sender.transfer(srcToReturn); |                 msg.sender.transfer(srcToReturn); | ||||||
|  | @ -225,7 +213,7 @@ contract Trade is Registry { | ||||||
|             return ethSold; |             return ethSold; | ||||||
|         } else if (dest == eth) { |         } else if (dest == eth) { | ||||||
|             UniswapExchange exchangeContract = UniswapExchange(_getExchangeAddress(src)); |             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) { |             if (tokensSold < maxSrcAmt) { | ||||||
|                 IERC20 srcTkn = IERC20(src); |                 IERC20 srcTkn = IERC20(src); | ||||||
|                 uint srcToReturn = maxSrcAmt - tokensSold; |                 uint srcToReturn = maxSrcAmt - tokensSold; | ||||||
|  | @ -234,8 +222,6 @@ contract Trade is Registry { | ||||||
|             return tokensSold; |             return tokensSold; | ||||||
|         } else { |         } else { | ||||||
|             UniswapExchange exchangeContractSrc = UniswapExchange(_getExchangeAddress(src)); |             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); |             uint tokensSold = exchangeContractSrc.tokenToTokenTransferOutput(destAmt, maxSrcAmt, uint(0-1), deadline, msg.sender, dest); | ||||||
|             if (tokensSold < maxSrcAmt) { |             if (tokensSold < maxSrcAmt) { | ||||||
|                 IERC20 srcTkn = IERC20(src); |                 IERC20 srcTkn = IERC20(src); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Samyak
						Samyak