Skip to content

Instantly share code, notes, and snippets.

@k06a
Last active May 19, 2019 01:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save k06a/145f4e0f8edd467448397d80e576d13b to your computer and use it in GitHub Desktop.
Save k06a/145f4e0f8edd467448397d80e576d13b to your computer and use it in GitHub Desktop.
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