mirror of
https://github.com/Instadapp/smart-contract.git
synced 2024-07-29 22:08:07 +00:00
183 lines
7.3 KiB
Solidity
183 lines
7.3 KiB
Solidity
/**
|
|
*Submitted for verification at Etherscan.io on 2019-06-19
|
|
*/
|
|
|
|
pragma solidity ^0.5.7;
|
|
|
|
|
|
interface ERC20 {
|
|
function totalSupply() external view returns (uint supply);
|
|
function balanceOf(address _owner) external view returns (uint balance);
|
|
function transfer(address _to, uint _value) external returns (bool success);
|
|
function transferFrom(address _from, address _to, uint _value) external returns (bool success);
|
|
function approve(address _spender, uint _value) external returns (bool success);
|
|
function allowance(address _owner, address _spender) external view returns (uint remaining);
|
|
function decimals() external view returns(uint digits);
|
|
function allocateTo(address recipient, uint256 value) external;
|
|
event Approval(address indexed _owner, address indexed _spender, uint _value);
|
|
}
|
|
|
|
|
|
contract KyberNetworkProxyInterface {
|
|
function maxGasPrice() external view returns(uint);
|
|
function getUserCapInWei(address user) external view returns(uint);
|
|
function getUserCapInTokenWei(address user, ERC20 token) external view returns(uint);
|
|
function enabled() external view returns(bool);
|
|
function info(bytes32 id) external view returns(uint);
|
|
|
|
function getExpectedRate(ERC20 src, ERC20 dest, uint srcQty) public
|
|
returns (uint expectedRate, uint slippageRate);
|
|
|
|
function tradeWithHint(ERC20 src, uint srcAmount, ERC20 dest, address destAddress, uint maxDestAmount,
|
|
uint minConversionRate, address walletId, bytes memory hint) public payable returns(uint);
|
|
|
|
function trade(ERC20 src, uint srcAmount, ERC20 dest, address destAddress, uint maxDestAmount,
|
|
uint minConversionRate, address walletId) public payable returns(uint);
|
|
|
|
function swapEtherToToken(ERC20 token, uint minConversionRate) external payable returns(uint);
|
|
function swapTokenToEther(ERC20 token, uint tokenQty, uint minRate) external payable returns(uint);
|
|
function swapTokenToToken(ERC20 src, uint srcAmount, ERC20 dest, uint minConversionRate) public returns(uint);
|
|
}
|
|
|
|
interface ExchangeInterface {
|
|
function swapEtherToToken (uint _ethAmount, address _tokenAddress, uint _maxAmount) payable external returns(uint, uint);
|
|
function swapTokenToEther (address _tokenAddress, uint _amount, uint _maxAmount) external returns(uint);
|
|
|
|
function getExpectedRate(address src, address dest, uint srcQty) external
|
|
returns (uint expectedRate, uint slippageRate);
|
|
}
|
|
|
|
contract Eth2DaiInterface {
|
|
function getBuyAmount(ERC20 tokenToBuy, ERC20 tokenToPay, uint256 amountToPay) external view returns(uint256 amountBought);
|
|
function getPayAmount(ERC20 tokenToPay, ERC20 tokenToBuy, uint amountToBuy) public view returns (uint amountPaid);
|
|
|
|
function sellAllAmount(ERC20 pay_gem, uint pay_amt, ERC20 buy_gem, uint min_fill_amount) public returns (uint fill_amt);
|
|
function buyAllAmount(ERC20 buy_gem, uint buy_amt, ERC20 pay_gem, uint max_fill_amount) public returns (uint fill_amt);
|
|
}
|
|
|
|
contract TokenInterface {
|
|
function allowance(address, address) public returns (uint);
|
|
function balanceOf(address) public returns (uint);
|
|
function approve(address, uint) public;
|
|
function transfer(address, uint) public returns (bool);
|
|
function transferFrom(address, address, uint) public returns (bool);
|
|
function deposit() public payable;
|
|
function withdraw(uint) public;
|
|
}
|
|
|
|
contract DSMath {
|
|
function add(uint x, uint y) internal pure returns (uint z) {
|
|
require((z = x + y) >= x);
|
|
}
|
|
function sub(uint x, uint y) internal pure returns (uint z) {
|
|
require((z = x - y) <= x);
|
|
}
|
|
function mul(uint x, uint y) internal pure returns (uint z) {
|
|
require(y == 0 || (z = x * y) / y == x);
|
|
}
|
|
|
|
function min(uint x, uint y) internal pure returns (uint z) {
|
|
return x <= y ? x : y;
|
|
}
|
|
function max(uint x, uint y) internal pure returns (uint z) {
|
|
return x >= y ? x : y;
|
|
}
|
|
function imin(int x, int y) internal pure returns (int z) {
|
|
return x <= y ? x : y;
|
|
}
|
|
function imax(int x, int y) internal pure returns (int z) {
|
|
return x >= y ? x : y;
|
|
}
|
|
|
|
uint constant WAD = 10 ** 18;
|
|
uint constant RAY = 10 ** 27;
|
|
|
|
function wmul(uint x, uint y) internal pure returns (uint z) {
|
|
z = add(mul(x, y), WAD / 2) / WAD;
|
|
}
|
|
function rmul(uint x, uint y) internal pure returns (uint z) {
|
|
z = add(mul(x, y), RAY / 2) / RAY;
|
|
}
|
|
function wdiv(uint x, uint y) internal pure returns (uint z) {
|
|
z = add(mul(x, WAD), y / 2) / y;
|
|
}
|
|
function rdiv(uint x, uint y) internal pure returns (uint z) {
|
|
z = add(mul(x, RAY), y / 2) / y;
|
|
}
|
|
|
|
// This famous algorithm is called "exponentiation by squaring"
|
|
// and calculates x^n with x as fixed-point and n as regular unsigned.
|
|
//
|
|
// It's O(log n), instead of O(n) for naive repeated multiplication.
|
|
//
|
|
// These facts are why it works:
|
|
//
|
|
// If n is even, then x^n = (x^2)^(n/2).
|
|
// If n is odd, then x^n = x * x^(n-1),
|
|
// and applying the equation for even x gives
|
|
// x^n = x * (x^2)^((n-1) / 2).
|
|
//
|
|
// Also, EVM division is flooring and
|
|
// floor[(n-1) / 2] = floor[n / 2].
|
|
//
|
|
function rpow(uint x, uint n) internal pure returns (uint z) {
|
|
z = n % 2 != 0 ? x : RAY;
|
|
|
|
for (n /= 2; n != 0; n /= 2) {
|
|
x = rmul(x, x);
|
|
|
|
if (n % 2 != 0) {
|
|
z = rmul(z, x);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
contract Eth2DaiWrapper is ExchangeInterface, DSMath {
|
|
|
|
address public constant KYBER_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
|
|
|
|
// Kovan
|
|
// address public constant OTC_ADDRESS = 0x4A6bC4e803c62081ffEbCc8d227B5a87a58f1F8F;
|
|
// address public constant WETH_ADDRESS = 0xd0A1E359811322d97991E03f863a0C30C2cF029C;
|
|
|
|
// Mainnet
|
|
address public constant OTC_ADDRESS = 0x39755357759cE0d7f32dC8dC45414CCa409AE24e;
|
|
address public constant WETH_ADDRESS = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
|
|
|
|
function swapEtherToToken (uint _ethAmount, address _tokenAddress, uint _maxAmount) external payable returns(uint, uint) {
|
|
require(ERC20(WETH_ADDRESS).approve(OTC_ADDRESS, _ethAmount));
|
|
TokenInterface(WETH_ADDRESS).deposit.value(_ethAmount)();
|
|
|
|
uint daiBought = Eth2DaiInterface(OTC_ADDRESS).sellAllAmount(ERC20(WETH_ADDRESS), _ethAmount,
|
|
ERC20(_tokenAddress), 0);
|
|
|
|
ERC20(_tokenAddress).transfer(msg.sender, daiBought);
|
|
|
|
return (daiBought, 0);
|
|
}
|
|
|
|
function swapTokenToEther (address _tokenAddress, uint _amount, uint _maxAmount) external returns(uint) {
|
|
require(ERC20(_tokenAddress).approve(OTC_ADDRESS, _amount));
|
|
|
|
uint ethBought = Eth2DaiInterface(OTC_ADDRESS).sellAllAmount(ERC20(_tokenAddress), _amount,
|
|
ERC20(WETH_ADDRESS), 0);
|
|
|
|
TokenInterface(WETH_ADDRESS).withdraw(ethBought);
|
|
|
|
msg.sender.transfer(ethBought);
|
|
|
|
return ethBought;
|
|
}
|
|
|
|
function getExpectedRate(address _src, address _dest, uint _srcQty) public returns (uint, uint) {
|
|
if(_src == KYBER_ETH_ADDRESS) {
|
|
return (wdiv(Eth2DaiInterface(OTC_ADDRESS).getBuyAmount(ERC20(_dest), ERC20(WETH_ADDRESS), _srcQty), _srcQty), 0);
|
|
} else if (_dest == KYBER_ETH_ADDRESS) {
|
|
return (wdiv(Eth2DaiInterface(OTC_ADDRESS).getBuyAmount(ERC20(WETH_ADDRESS), ERC20(_src), _srcQty), _srcQty), 0);
|
|
}
|
|
}
|
|
|
|
function() payable external {
|
|
}
|
|
} |