Skip to content

Instantly share code, notes, and snippets.

@k06a
Created November 1, 2019 13:33
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/402807c686c504578adbc78301d85724 to your computer and use it in GitHub Desktop.
Save k06a/402807c686c504578adbc78301d85724 to your computer and use it in GitHub Desktop.
SplitKyber
pragma solidity ^0.5.0;
import "github.com/openzeppelin/openzeppelin-contracts/contracts/math/SafeMath.sol";
import "github.com/openzeppelin/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
import "github.com/openzeppelin/openzeppelin-contracts/contracts/token/ERC20/SafeERC20.sol";
interface IKyberReserve {
function trade(
IERC20 srcToken,
uint srcAmount,
IERC20 destToken,
address destAddress,
uint conversionRate,
bool validate
)
external
payable
returns(bool);
function getConversionRate(
IERC20 src,
IERC20 dest,
uint srcQty,
uint blockNumber
)
external
view
returns(uint);
}
contract SplitKyber {
using SafeMath for uint256;
IKyberReserve[] public reserves;
function getConversionRate(
IERC20 src,
IERC20 dest,
uint srcQty,
uint parts
)
public
view
returns(
uint destQty,
uint[] memory distribution
)
{
uint256[] memory rates = new uint256[](reserves.length);
uint256[] memory fullRates = new uint256[](reserves.length);
for (uint i = 0; i < rates.length; i++) {
rates[i] = reserves[i].getConversionRate(src, dest, srcQty.mul(i).div(parts), block.number);
fullRates[i] = rates[i];
}
distribution = new uint256[](parts);
for (uint j = 0; j < parts; j++) {
// Find best part
uint256 bestIndex = 0;
for (uint i = 0; i < rates.length; i++) {
if (rates[i] > rates[bestIndex]) {
bestIndex = i;
}
}
// Add best part
destQty = destQty.add(rates[bestIndex]);
distribution[bestIndex]++;
uint256 srcAmount = srcQty; // Avoid CompilerError: Stack too deep
// Recalc part if needed
if (j + 1 < parts) {
uint256 newRate = reserves[bestIndex].getConversionRate(
src, dest, srcAmount.mul(distribution[bestIndex] + 1).div(parts), block.number
);
rates[bestIndex] = newRate.sub(fullRates[bestIndex]);
fullRates[bestIndex] = newRate;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment