Last active
May 19, 2019 01:49
-
-
Save k06a/145f4e0f8edd467448397d80e576d13b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface IUniswap { | |
function getEthToTokenInputPrice(uint256 eth_sold) external view returns(uint256); | |
function getEthToTokenOutputPrice(uint256 tokens_bought) external view returns(uint256); | |
function getTokenToEthInputPrice(uint256 tokens_sold) external view returns(uint256); | |
function getTokenToEthOutputPrice(uint256 eth_bought) external view returns(uint256); | |
} | |
interface IBancor { | |
function getReturnByPath(address[] calldata _path, uint256 _amount) external view | |
returns (uint256 amount, uint256 conversion_fee); | |
} | |
interface IKyber { | |
function getExpectedRate(address src, address dest, uint srcQty) external view | |
returns (uint expectedRate, uint slippageRate); | |
} | |
contract BestPrice { | |
address constant KYBER_NETWORK_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; | |
function _getBestPrice( | |
address fromToken, | |
address toToken, | |
address[] calldata path, | |
uint256 amount, | |
uint256 parts, | |
IUniswap uniswap, | |
IBancor bancor, | |
IKyber kyber | |
) | |
external | |
view | |
returns(uint256[7] memory res) | |
{ | |
uint256[] memory uniswapReturns = new uint256[](parts + 1); | |
uint256[] memory bancorReturns = new uint256[](parts + 1); | |
uint256[] memory kyberReturns = new uint256[](parts + 1); | |
for (uint i = 1; i <= parts; i++) { | |
if (address(uniswap) != address(0)) { | |
uniswapReturns[i] = _getUniswapRate(uniswap, fromToken, amount * i / parts); | |
} | |
if (address(bancor) != address(0)) { | |
(bancorReturns[i],) = bancor.getReturnByPath(path, amount * i / parts); | |
} | |
if (address(kyber) != address(0)) { | |
(kyberReturns[i],) = kyber.getExpectedRate(fromToken, toToken, amount * i / parts); | |
} | |
} | |
res[3] = uniswapReturns[parts]; | |
res[4] = bancorReturns[parts]; | |
res[5] = kyberReturns[parts]; | |
for (uint i = 0; i < parts; i++) { | |
for (uint j = i; j < parts; j++) { | |
uint256 theReturn = uniswapReturns[i] + bancorReturns[j - i] + kyberReturns[parts - 1 - j]; | |
if (theReturn > res[6]) { | |
res[0] = i; | |
res[1] = j - i; | |
res[2] = parts - 1 - j; | |
res[6] = theReturn; | |
} | |
} | |
} | |
} | |
function _getUniswapRate( | |
IUniswap uniswap, | |
address fromToken, | |
uint256 amount | |
) | |
internal | |
view | |
returns(uint256) | |
{ | |
if (fromToken == address(0) || fromToken == KYBER_NETWORK_ETH_ADDRESS) { | |
return uniswap.getEthToTokenInputPrice(amount); | |
} | |
return uniswap.getTokenToEthInputPrice(amount); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment