dexes integration almost done

This commit is contained in:
Samyak 2019-03-22 01:38:56 +05:30
parent 5b2ae84dab
commit 7142e1f9ee
3 changed files with 462 additions and 109 deletions

View 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;
}
}
}

View File

@ -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"));
}
}

View File

@ -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);