mirror of
https://github.com/Instadapp/smart-contract.git
synced 2024-07-29 22:08:07 +00:00
commit
6a12915ce0
|
@ -2,5 +2,8 @@ module.exports = {
|
|||
port: 9545,
|
||||
testrpcOptions:
|
||||
'-p 9545 -m "candy maple cake sugar pudding cream honey rich smooth crumble sweet treat"',
|
||||
copyNodeModules: false
|
||||
testCommand: 'truffle test --network coverage',
|
||||
norpc: true,
|
||||
copyPackages: ['openzeppelin-solidity'],
|
||||
skipFiles: ['Bin/DEX.sol', 'Bin/Kyber.sol', 'Bin/Uniswap.sol', 'Bin/FreeProxy.sol', 'Reference/Auth.sol','Migrations.sol']
|
||||
}
|
||||
|
|
13
compiler.json
Normal file
13
compiler.json
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"contractsDir": "contracts",
|
||||
"artifactsDir": "docs",
|
||||
"contracts": "*",
|
||||
"compilerSettings": {
|
||||
"optimizer": { "enabled": false },
|
||||
"outputSelection": {
|
||||
"*": {
|
||||
"*": ["abi","devdoc"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
|
||||
interface TubInterface {
|
||||
|
|
|
@ -1,26 +1,7 @@
|
|||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
|
||||
library SafeMath {
|
||||
|
||||
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
if (a == 0) {
|
||||
return 0;
|
||||
}
|
||||
uint256 c = a * b;
|
||||
require(c / a == b, "Assertion Failed");
|
||||
return c;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
import "openzeppelin-solidity/contracts/math/SafeMath.sol";
|
||||
import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
|
||||
|
||||
interface AddressRegistry {
|
||||
function getAddr(string calldata name) external view returns (address);
|
||||
|
@ -28,12 +9,19 @@ interface AddressRegistry {
|
|||
|
||||
interface Kyber {
|
||||
// Kyber's trade function
|
||||
function trade(address src, uint srcAmount, address dest, address destAddress, uint maxDestAmount, uint minConversionRate, address walletId) external payable returns (uint);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
contract Registry {
|
||||
address public addressRegistry;
|
||||
modifier onlyAdmin() {
|
||||
|
@ -47,16 +35,7 @@ contract Registry {
|
|||
}
|
||||
|
||||
contract helper is Registry {
|
||||
|
||||
function _getToken(
|
||||
address trader,
|
||||
address src,
|
||||
uint srcAmt,
|
||||
address eth
|
||||
)
|
||||
internal
|
||||
returns (uint ethQty)
|
||||
{
|
||||
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;
|
||||
|
@ -71,7 +50,7 @@ contract helper is Registry {
|
|||
function _approveKyber(address token) internal returns (bool) {
|
||||
address kyberProxy = _getAddress("kyber");
|
||||
IERC20 tokenFunctions = IERC20(token);
|
||||
return tokenFunctions.approve(kyberProxy, uint(0-1));
|
||||
return tokenFunctions.approve(kyberProxy, uint(0 - 1));
|
||||
}
|
||||
|
||||
// Check Allowance to Kyber Proxy contract
|
||||
|
@ -92,9 +71,7 @@ contract helper is Registry {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
contract Trade is helper {
|
||||
|
||||
using SafeMath for uint;
|
||||
|
||||
event KyberTrade(address src, uint srcAmt, address dest, uint destAmt, address beneficiary, uint minConversionRate, address affiliate);
|
||||
|
@ -104,9 +81,8 @@ contract Trade is helper {
|
|||
return kyberFunctions.getExpectedRate(src, dest, srcAmt);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @title Kyber's trade when token to sell Amount fixed
|
||||
* @dev 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")
|
||||
|
@ -119,12 +95,7 @@ contract Trade is helper {
|
|||
uint minDestAmt // minimum slippage rate
|
||||
) public payable returns (uint tokensBought) {
|
||||
address eth = _getAddress("eth");
|
||||
uint ethQty = _getToken(
|
||||
msg.sender,
|
||||
src,
|
||||
srcAmt,
|
||||
eth
|
||||
);
|
||||
uint ethQty = _getToken(msg.sender, src, srcAmt, eth);
|
||||
|
||||
if (src != eth) {
|
||||
_allowanceApproveKyber(src);
|
||||
|
@ -132,23 +103,14 @@ contract Trade is helper {
|
|||
|
||||
// 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")
|
||||
);
|
||||
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"));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @title Kyber's trade when token to sell Amount fixed
|
||||
* @dev Kyber's trade when token to sell 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")
|
||||
|
@ -160,14 +122,8 @@ contract Trade is helper {
|
|||
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
|
||||
);
|
||||
uint ethQty = _getToken(msg.sender, src, maxSrcAmt, eth);
|
||||
|
||||
if (src != eth) {
|
||||
_allowanceApproveKyber(src);
|
||||
|
@ -175,15 +131,7 @@ contract Trade is helper {
|
|||
|
||||
// Interacting with Kyber Proxy Contract
|
||||
Kyber kyberFunctions = Kyber(_getAddress("kyber"));
|
||||
tokensBought = kyberFunctions.trade.value(ethQty)(
|
||||
src,
|
||||
maxSrcAmt,
|
||||
dest,
|
||||
msg.sender,
|
||||
destAmt,
|
||||
destAmt - 1,
|
||||
_getAddress("admin")
|
||||
);
|
||||
tokensBought = kyberFunctions.trade.value(ethQty)(src, maxSrcAmt, dest, msg.sender, destAmt, destAmt - 1, _getAddress("admin"));
|
||||
|
||||
// maxDestAmt usecase implementated
|
||||
if (src == eth && address(this).balance > 0) {
|
||||
|
@ -205,11 +153,9 @@ contract Trade is helper {
|
|||
|
||||
|
||||
contract InstaKyber is Trade {
|
||||
|
||||
constructor(address rAddr) public {
|
||||
addressRegistry = rAddr;
|
||||
}
|
||||
|
||||
function() external payable {}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,288 +0,0 @@
|
|||
pragma solidity ^0.4.23;
|
||||
|
||||
/// math.sol -- mixin for inline numerical wizardry
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
pragma solidity ^0.4.13;
|
||||
|
||||
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 TubInterface {
|
||||
function open() public returns (bytes32);
|
||||
function join(uint) public;
|
||||
function exit(uint) public;
|
||||
function lock(bytes32, uint) public;
|
||||
function free(bytes32, uint) public;
|
||||
function draw(bytes32, uint) public;
|
||||
function wipe(bytes32, uint) public;
|
||||
function give(bytes32, address) public;
|
||||
function shut(bytes32) public;
|
||||
function cups(bytes32) public view returns (address, uint, uint, uint);
|
||||
function gem() public view returns (TokenInterface);
|
||||
function gov() public view returns (TokenInterface);
|
||||
function skr() public view returns (TokenInterface);
|
||||
function sai() public view returns (TokenInterface);
|
||||
function mat() public view returns (uint);
|
||||
function ink(bytes32) public view returns (uint);
|
||||
function tab(bytes32) public view returns (uint);
|
||||
function rap(bytes32) public view returns (uint);
|
||||
function per() public view returns (uint);
|
||||
function pep() public view returns (PepInterface);
|
||||
}
|
||||
|
||||
contract TokenInterface {
|
||||
function allowance(address, address) public view returns (uint);
|
||||
function balanceOf(address) public view 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 PepInterface {
|
||||
function peek() public returns (bytes32, bool);
|
||||
}
|
||||
|
||||
contract OtcInterface {
|
||||
function getPayAmount(address, address, uint) public view returns (uint);
|
||||
function buyAllAmount(address, uint, address pay_gem, uint) public returns (uint);
|
||||
}
|
||||
|
||||
contract SaiProxy is DSMath {
|
||||
function open(address tub_) public returns (bytes32) {
|
||||
return TubInterface(tub_).open();
|
||||
}
|
||||
|
||||
function give(address tub_, bytes32 cup, address lad) public {
|
||||
TubInterface(tub_).give(cup, lad);
|
||||
}
|
||||
|
||||
function lock(address tub_, bytes32 cup) public payable {
|
||||
if (msg.value > 0) {
|
||||
TubInterface tub = TubInterface(tub_);
|
||||
|
||||
(address lad,,,) = tub.cups(cup);
|
||||
require(lad == address(this), "cup-not-owned");
|
||||
|
||||
tub.gem().deposit.value(msg.value)();
|
||||
|
||||
uint ink = rdiv(msg.value, tub.per());
|
||||
ink = rmul(ink, tub.per()) <= msg.value ? ink : ink - 1;
|
||||
|
||||
if (tub.gem().allowance(this, tub) != uint(-1)) {
|
||||
tub.gem().approve(tub, uint(-1));
|
||||
}
|
||||
tub.join(ink);
|
||||
|
||||
if (tub.skr().allowance(this, tub) != uint(-1)) {
|
||||
tub.skr().approve(tub, uint(-1));
|
||||
}
|
||||
tub.lock(cup, ink);
|
||||
}
|
||||
}
|
||||
|
||||
function draw(address tub_, bytes32 cup, uint wad) public {
|
||||
if (wad > 0) {
|
||||
TubInterface tub = TubInterface(tub_);
|
||||
tub.draw(cup, wad);
|
||||
tub.sai().transfer(msg.sender, wad);
|
||||
}
|
||||
}
|
||||
|
||||
function handleGovFee(TubInterface tub, uint saiDebtFee, address otc_) internal {
|
||||
bytes32 val;
|
||||
bool ok;
|
||||
(val, ok) = tub.pep().peek();
|
||||
if (ok && val != 0) {
|
||||
uint govAmt = wdiv(saiDebtFee, uint(val));
|
||||
if (otc_ != address(0)) {
|
||||
uint saiGovAmt = OtcInterface(otc_).getPayAmount(tub.sai(), tub.gov(), govAmt);
|
||||
if (tub.sai().allowance(this, otc_) != uint(-1)) {
|
||||
tub.sai().approve(otc_, uint(-1));
|
||||
}
|
||||
tub.sai().transferFrom(msg.sender, this, saiGovAmt);
|
||||
OtcInterface(otc_).buyAllAmount(tub.gov(), govAmt, tub.sai(), saiGovAmt);
|
||||
} else {
|
||||
tub.gov().transferFrom(msg.sender, this, govAmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function wipe(address tub_, bytes32 cup, uint wad, address otc_) public {
|
||||
if (wad > 0) {
|
||||
TubInterface tub = TubInterface(tub_);
|
||||
|
||||
tub.sai().transferFrom(msg.sender, this, wad);
|
||||
handleGovFee(tub, rmul(wad, rdiv(tub.rap(cup), tub.tab(cup))), otc_);
|
||||
|
||||
if (tub.sai().allowance(this, tub) != uint(-1)) {
|
||||
tub.sai().approve(tub, uint(-1));
|
||||
}
|
||||
if (tub.gov().allowance(this, tub) != uint(-1)) {
|
||||
tub.gov().approve(tub, uint(-1));
|
||||
}
|
||||
tub.wipe(cup, wad);
|
||||
}
|
||||
}
|
||||
|
||||
function wipe(address tub_, bytes32 cup, uint wad) public {
|
||||
wipe(tub_, cup, wad, address(0));
|
||||
}
|
||||
|
||||
function free(address tub_, bytes32 cup, uint jam) public {
|
||||
if (jam > 0) {
|
||||
TubInterface tub = TubInterface(tub_);
|
||||
uint ink = rdiv(jam, tub.per());
|
||||
ink = rmul(ink, tub.per()) <= jam ? ink : ink - 1;
|
||||
tub.free(cup, ink);
|
||||
if (tub.skr().allowance(this, tub) != uint(-1)) {
|
||||
tub.skr().approve(tub, uint(-1));
|
||||
}
|
||||
tub.exit(ink);
|
||||
uint freeJam = tub.gem().balanceOf(this); // Withdraw possible previous stuck WETH as well
|
||||
tub.gem().withdraw(freeJam);
|
||||
address(msg.sender).transfer(freeJam);
|
||||
}
|
||||
}
|
||||
|
||||
function lockAndDraw(address tub_, bytes32 cup, uint wad) public payable {
|
||||
lock(tub_, cup);
|
||||
draw(tub_, cup, wad);
|
||||
}
|
||||
|
||||
function lockAndDraw(address tub_, uint wad) public payable returns (bytes32 cup) {
|
||||
cup = open(tub_);
|
||||
lockAndDraw(tub_, cup, wad);
|
||||
}
|
||||
|
||||
function wipeAndFree(address tub_, bytes32 cup, uint jam, uint wad) public payable {
|
||||
wipe(tub_, cup, wad);
|
||||
free(tub_, cup, jam);
|
||||
}
|
||||
|
||||
function wipeAndFree(address tub_, bytes32 cup, uint jam, uint wad, address otc_) public payable {
|
||||
wipe(tub_, cup, wad, otc_);
|
||||
free(tub_, cup, jam);
|
||||
}
|
||||
|
||||
function shut(address tub_, bytes32 cup) public {
|
||||
TubInterface tub = TubInterface(tub_);
|
||||
wipeAndFree(tub_, cup, rmul(tub.ink(cup), tub.per()), tub.tab(cup));
|
||||
tub.shut(cup);
|
||||
}
|
||||
|
||||
function shut(address tub_, bytes32 cup, address otc_) public {
|
||||
TubInterface tub = TubInterface(tub_);
|
||||
wipeAndFree(tub_, cup, rmul(tub.ink(cup), tub.per()), tub.tab(cup), otc_);
|
||||
tub.shut(cup);
|
||||
}
|
||||
}
|
||||
|
||||
contract ProxyRegistryInterface {
|
||||
function build(address) public returns (address);
|
||||
}
|
||||
|
||||
contract SaiProxyCreateAndExecute is SaiProxy {
|
||||
|
||||
// Create a DSProxy instance and open a cup
|
||||
function createAndOpen(address registry_, address tub_) public returns (address proxy, bytes32 cup) {
|
||||
proxy = ProxyRegistryInterface(registry_).build(msg.sender);
|
||||
cup = open(tub_);
|
||||
TubInterface(tub_).give(cup, proxy);
|
||||
}
|
||||
|
||||
// Create a DSProxy instance, open a cup, and lock collateral
|
||||
function createOpenAndLock(address registry_, address tub_) public payable returns (address proxy, bytes32 cup) {
|
||||
proxy = ProxyRegistryInterface(registry_).build(msg.sender);
|
||||
cup = open(tub_);
|
||||
lock(tub_, cup);
|
||||
TubInterface(tub_).give(cup, proxy);
|
||||
}
|
||||
|
||||
// Create a DSProxy instance, open a cup, lock collateral, and draw DAI
|
||||
function createOpenLockAndDraw(address registry_, address tub_, uint wad) public payable returns (address proxy, bytes32 cup) {
|
||||
proxy = ProxyRegistryInterface(registry_).build(msg.sender);
|
||||
cup = open(tub_);
|
||||
lockAndDraw(tub_, cup, wad);
|
||||
TubInterface(tub_).give(cup, proxy);
|
||||
}
|
||||
}
|
|
@ -1,15 +1,7 @@
|
|||
pragma solidity 0.5.0;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
import "openzeppelin-solidity/contracts/math/SafeMath.sol";
|
||||
import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
|
||||
|
||||
interface AddressRegistry {
|
||||
function getAddr(string calldata name) external view returns (address);
|
||||
|
@ -18,7 +10,15 @@ interface AddressRegistry {
|
|||
// 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);
|
||||
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);
|
||||
}
|
||||
|
@ -37,17 +37,40 @@ interface UniswapExchange {
|
|||
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);
|
||||
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_eth, 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);
|
||||
function tokenToEthTransferInput(uint256 tokens_sold, uint256 min_eth, 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);
|
||||
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() {
|
||||
|
@ -62,16 +85,10 @@ contract Registry {
|
|||
|
||||
// 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) {
|
||||
// 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;
|
||||
|
@ -84,24 +101,22 @@ contract CommonStuffs {
|
|||
|
||||
function _approveDexes(address token, address dexToApprove) internal returns (bool) {
|
||||
IERC20 tokenFunctions = IERC20(token);
|
||||
return tokenFunctions.approve(dexToApprove, uint(0-1));
|
||||
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) internal view returns (uint) {
|
||||
KyberExchange kyberFunctions = KyberExchange(_getAddress("kyber"));
|
||||
uint expectedRate;
|
||||
(expectedRate,) = kyberFunctions.getExpectedRate(src, dest, srcAmt);
|
||||
(expectedRate, ) = kyberFunctions.getExpectedRate(src, dest, srcAmt);
|
||||
uint kyberRate = expectedRate.mul(srcAmt);
|
||||
return kyberRate;
|
||||
}
|
||||
|
@ -128,7 +143,7 @@ contract Kyber is Registry, CommonStuffs {
|
|||
}
|
||||
|
||||
/**
|
||||
* @title Kyber's trade when token to sell Amount fixed
|
||||
* @dev 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")
|
||||
|
@ -141,24 +156,11 @@ contract Kyber is Registry, CommonStuffs {
|
|||
uint minDestAmt // minimum slippage rate
|
||||
) public payable returns (uint tokensBought) {
|
||||
address eth = _getAddress("eth");
|
||||
uint ethQty = _getToken(
|
||||
msg.sender,
|
||||
src,
|
||||
srcAmt,
|
||||
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")
|
||||
);
|
||||
tokensBought = kyberFunctions.trade.value(ethQty)(src, srcAmt, dest, msg.sender, uint(0 - 1), minDestAmt, _getAddress("admin"));
|
||||
|
||||
}
|
||||
|
||||
|
@ -169,24 +171,11 @@ contract Kyber is Registry, CommonStuffs {
|
|||
uint destAmt // minimum slippage rate
|
||||
) public payable returns (uint tokensBought) {
|
||||
address eth = _getAddress("eth");
|
||||
uint ethQty = _getToken(
|
||||
msg.sender,
|
||||
src,
|
||||
maxSrcAmt,
|
||||
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")
|
||||
);
|
||||
tokensBought = kyberFunctions.trade.value(ethQty)(src, maxSrcAmt, dest, msg.sender, destAmt, destAmt, _getAddress("admin"));
|
||||
|
||||
// maxDestAmt usecase implementated
|
||||
if (src == eth && address(this).balance > 0) {
|
||||
|
@ -204,10 +193,8 @@ contract Kyber is Registry, CommonStuffs {
|
|||
|
||||
}
|
||||
|
||||
|
||||
// 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"));
|
||||
|
@ -236,17 +223,12 @@ contract Uniswap is Registry, CommonStuffs {
|
|||
}
|
||||
|
||||
/**
|
||||
* @title Uniswap's get expected rate from source
|
||||
* @dev 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
|
||||
* @returns expected Dest Amount
|
||||
*/
|
||||
function getExpectedRateSrcUniswap(
|
||||
address src,
|
||||
address dest,
|
||||
uint srcAmt
|
||||
) internal view returns (uint256) {
|
||||
function getExpectedRateSrcUniswap(address src, address dest, uint srcAmt) internal view returns (uint256) {
|
||||
address eth = _getAddress("eth");
|
||||
if (src == eth) {
|
||||
// define uniswap exchange with dest address
|
||||
|
@ -265,16 +247,12 @@ contract Uniswap is Registry, CommonStuffs {
|
|||
}
|
||||
|
||||
/**
|
||||
* @title Uniswap's get expected rate from dest
|
||||
* @dev 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
|
||||
) internal view returns (uint256) {
|
||||
function getExpectedRateDestUniswap(address src, address dest, uint destAmt) internal view returns (uint256) {
|
||||
address eth = _getAddress("eth");
|
||||
if (src == eth) {
|
||||
// define uniswap exchange with dest address
|
||||
|
@ -292,30 +270,17 @@ contract Uniswap is Registry, CommonStuffs {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @title Uniswap's trade when token to sell Amount fixed
|
||||
* @dev 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) {
|
||||
|
||||
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
|
||||
);
|
||||
uint ethQty = _getToken(msg.sender, src, srcAmt, eth);
|
||||
|
||||
if (src == eth) {
|
||||
UniswapExchange exchangeContract = UniswapExchange(_getExchangeAddress(dest));
|
||||
|
@ -332,30 +297,17 @@ contract Uniswap is Registry, CommonStuffs {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @title Uniswap's trade when token to buy Amount fixed
|
||||
* @dev 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) {
|
||||
|
||||
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
|
||||
);
|
||||
uint ethQty = _getToken(msg.sender, src, maxSrcAmt, eth);
|
||||
|
||||
if (src == eth) {
|
||||
UniswapExchange exchangeContract = UniswapExchange(_getExchangeAddress(dest));
|
||||
|
@ -376,7 +328,7 @@ contract Uniswap is Registry, CommonStuffs {
|
|||
return tokensSold;
|
||||
} else {
|
||||
UniswapExchange exchangeContractSrc = UniswapExchange(_getExchangeAddress(src));
|
||||
uint tokensSold = exchangeContractSrc.tokenToTokenTransferOutput(destAmt, maxSrcAmt, uint(0-1), deadline, msg.sender, dest);
|
||||
uint tokensSold = exchangeContractSrc.tokenToTokenTransferOutput(destAmt, maxSrcAmt, uint(0 - 1), deadline, msg.sender, dest);
|
||||
if (tokensSold < maxSrcAmt) {
|
||||
IERC20 srcTkn = IERC20(src);
|
||||
uint srcToReturn = maxSrcAmt - tokensSold;
|
||||
|
@ -389,9 +341,9 @@ contract Uniswap is Registry, CommonStuffs {
|
|||
|
||||
}
|
||||
|
||||
contract Trade is Kyber, Uniswap {
|
||||
|
||||
function getRateFromSrc(address src, address dest, uint srcAmt) public view returns(uint, uint) {
|
||||
contract Trade is Kyber, Uniswap {
|
||||
function getRateFromSrc(address src, address dest, uint srcAmt) public view returns (uint, uint) {
|
||||
uint uniswapRate = getExpectedRateSrcUniswap(src, dest, srcAmt);
|
||||
uint kyberRate = getExpectedRateKyber(src, dest, srcAmt);
|
||||
if (uniswapRate > kyberRate) {
|
||||
|
@ -401,13 +353,7 @@ contract Trade is Kyber, Uniswap {
|
|||
}
|
||||
}
|
||||
|
||||
function tradeFromSrc(
|
||||
address src,
|
||||
uint srcAmt,
|
||||
address dest,
|
||||
uint minDestAmt,
|
||||
uint dexNum
|
||||
) public payable returns (uint) {
|
||||
function tradeFromSrc(address src, uint srcAmt, address dest, uint minDestAmt, uint dexNum) public payable returns (uint) {
|
||||
address eth = _getAddress("eth");
|
||||
if (dexNum == 1) {
|
||||
if (src == eth) {
|
||||
|
@ -426,13 +372,7 @@ contract Trade is Kyber, Uniswap {
|
|||
}
|
||||
}
|
||||
|
||||
function tradeFromDest(
|
||||
address src,
|
||||
uint maxSrcAmt,
|
||||
address dest,
|
||||
uint destAmt,
|
||||
uint dexNum
|
||||
) public payable returns (uint) {
|
||||
function tradeFromDest(address src, uint maxSrcAmt, address dest, uint destAmt, uint dexNum) public payable returns (uint) {
|
||||
address eth = _getAddress("eth");
|
||||
if (dexNum == 1) {
|
||||
if (src == eth) {
|
||||
|
@ -450,5 +390,4 @@ contract Trade is Kyber, Uniswap {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,14 +1,7 @@
|
|||
pragma solidity 0.5.0;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
|
||||
import "./Safemath.sol";
|
||||
|
||||
interface IERC20 {
|
||||
function balanceOf(address who) 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);
|
||||
}
|
||||
import "openzeppelin-solidity/contracts/math/SafeMath.sol";
|
||||
import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
|
||||
|
||||
interface AddressRegistry {
|
||||
function getAddr(string calldata name) external view returns (address);
|
||||
|
@ -28,17 +21,40 @@ interface UniswapExchange {
|
|||
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);
|
||||
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);
|
||||
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);
|
||||
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() {
|
||||
|
@ -51,9 +67,7 @@ contract Registry {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
contract Trade is Registry {
|
||||
|
||||
contract UniswapTrade is Registry {
|
||||
using SafeMath for uint;
|
||||
|
||||
// Get Uniswap's Exchange address from Factory Contract
|
||||
|
@ -62,16 +76,8 @@ contract Trade is Registry {
|
|||
return uniswapMain.getExchange(_token);
|
||||
}
|
||||
|
||||
// Check required ETH Quantity to execute code
|
||||
function _getToken(
|
||||
address trader,
|
||||
address src,
|
||||
uint srcAmt,
|
||||
address eth
|
||||
)
|
||||
internal
|
||||
returns (uint ethQty)
|
||||
{
|
||||
// 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;
|
||||
|
@ -82,18 +88,13 @@ contract Trade is Registry {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @title Uniswap's get expected rate from source
|
||||
* @dev 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) {
|
||||
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));
|
||||
|
@ -111,16 +112,12 @@ contract Trade is Registry {
|
|||
}
|
||||
|
||||
/**
|
||||
* @title Uniswap's get expected rate from dest
|
||||
* @dev 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) {
|
||||
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
|
||||
|
@ -138,30 +135,17 @@ contract Trade is Registry {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @title Uniswap's trade when token to sell Amount fixed
|
||||
* @dev 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) {
|
||||
|
||||
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
|
||||
);
|
||||
uint ethQty = _getToken(msg.sender, src, srcAmt, eth);
|
||||
|
||||
if (src == eth) {
|
||||
UniswapExchange exchangeContract = UniswapExchange(_getExchangeAddress(dest));
|
||||
|
@ -178,30 +162,17 @@ contract Trade is Registry {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @title Uniswap's trade when token to buy Amount fixed
|
||||
* @dev 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) {
|
||||
|
||||
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
|
||||
);
|
||||
uint ethQty = _getToken(msg.sender, src, maxSrcAmt, eth);
|
||||
|
||||
if (src == eth) {
|
||||
UniswapExchange exchangeContract = UniswapExchange(_getExchangeAddress(dest));
|
||||
|
@ -222,7 +193,7 @@ contract Trade is Registry {
|
|||
return tokensSold;
|
||||
} else {
|
||||
UniswapExchange exchangeContractSrc = UniswapExchange(_getExchangeAddress(src));
|
||||
uint tokensSold = exchangeContractSrc.tokenToTokenTransferOutput(destAmt, maxSrcAmt, uint(0-1), deadline, msg.sender, dest);
|
||||
uint tokensSold = exchangeContractSrc.tokenToTokenTransferOutput(destAmt, maxSrcAmt, uint(0 - 1), deadline, msg.sender, dest);
|
||||
if (tokensSold < maxSrcAmt) {
|
||||
IERC20 srcTkn = IERC20(src);
|
||||
uint srcToReturn = maxSrcAmt - tokensSold;
|
||||
|
@ -233,4 +204,4 @@ contract Trade is Registry {
|
|||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,16 +1,20 @@
|
|||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "./UserWallet.sol";
|
||||
|
||||
|
||||
/**
|
||||
* @title Address Registry
|
||||
*/
|
||||
/// @title AddressRegistry
|
||||
/// @notice
|
||||
/// @dev
|
||||
contract AddressRegistry {
|
||||
event LogSetAddress(string name, address addr);
|
||||
|
||||
/// @notice Registry of role and address
|
||||
mapping(bytes32 => address) registry;
|
||||
|
||||
/**
|
||||
* @dev Check if msg.sender is admin or owner.
|
||||
*/
|
||||
modifier isAdmin() {
|
||||
require(
|
||||
msg.sender == getAddress("admin") ||
|
||||
|
@ -20,103 +24,95 @@ contract AddressRegistry {
|
|||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev get the address from system registry
|
||||
*/
|
||||
function getAddress(string memory name) public view returns(address) {
|
||||
return registry[keccak256(abi.encodePacked(name))];
|
||||
/// @dev Get the address from system registry
|
||||
/// @param _name (string)
|
||||
/// @return (address) Returns address based on role
|
||||
function getAddress(string memory _name) public view returns(address) {
|
||||
return registry[keccak256(abi.encodePacked(_name))];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev set new address in system registry
|
||||
*/
|
||||
function setAddress(string memory name, address addr) public isAdmin {
|
||||
registry[keccak256(abi.encodePacked(name))] = addr;
|
||||
emit LogSetAddress(name, addr);
|
||||
/// @dev Set new address in system registry
|
||||
/// @param _name (string) Role name
|
||||
/// @param _userAddress (string) User Address
|
||||
function setAddress(string memory _name, address _userAddress) public isAdmin {
|
||||
registry[keccak256(abi.encodePacked(_name))] = _userAddress;
|
||||
emit LogSetAddress(_name, _userAddress);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @title Logic Registry
|
||||
*/
|
||||
/// @title LogicRegistry
|
||||
/// @notice
|
||||
/// @dev LogicRegistry
|
||||
contract LogicRegistry is AddressRegistry {
|
||||
|
||||
event LogEnableDefaultLogic(address logicAddr);
|
||||
event LogEnableLogic(address logicAddr);
|
||||
event LogDisableLogic(address logicAddr);
|
||||
event LogEnableDefaultLogic(address logicAddress);
|
||||
event LogEnableLogic(address logicAddress);
|
||||
event LogDisableLogic(address logicAddress);
|
||||
|
||||
/// @notice Map of default proxy state
|
||||
mapping(address => bool) public defaultLogicProxies;
|
||||
|
||||
/// @notice Map of logic proxy state
|
||||
mapping(address => bool) public logicProxies;
|
||||
|
||||
/**
|
||||
* @dev get the boolean of the logic contract
|
||||
* @param logicAddr is the logic proxy address
|
||||
* @return bool logic proxy is authorised by system admin
|
||||
* @return bool logic proxy is default proxy
|
||||
*/
|
||||
function logic(address logicAddr) public view returns (bool) {
|
||||
if (defaultLogicProxies[logicAddr] || logicProxies[logicAddr]) {
|
||||
/// @dev
|
||||
/// @param _logicAddress (address)
|
||||
/// @return (bool)
|
||||
function logic(address _logicAddress) public view returns (bool) {
|
||||
if (defaultLogicProxies[_logicAddress] || logicProxies[_logicAddress]) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev this sets the default logic proxy to true
|
||||
* default proxies mostly contains the logic for withdrawal of assets
|
||||
* and can never be false to freely let user withdraw their assets
|
||||
* @param logicAddr is the default logic proxy address
|
||||
*/
|
||||
function enableDefaultLogic(address logicAddr) public isAdmin {
|
||||
defaultLogicProxies[logicAddr] = true;
|
||||
emit LogEnableDefaultLogic(logicAddr);
|
||||
/// @dev Sets the default logic proxy to true
|
||||
/// default proxies mostly contains the logic for withdrawal of assets
|
||||
/// and can never be false to freely let user withdraw their assets
|
||||
/// @param _logicAddress (address)
|
||||
function enableDefaultLogic(address _logicAddress) public isAdmin {
|
||||
defaultLogicProxies[_logicAddress] = true;
|
||||
emit LogEnableDefaultLogic(_logicAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev enable logic proxy address and sets true
|
||||
* @param logicAddr is the logic proxy address
|
||||
*/
|
||||
function enableLogic(address logicAddr) public isAdmin {
|
||||
logicProxies[logicAddr] = true;
|
||||
emit LogEnableLogic(logicAddr);
|
||||
/// @dev Enable logic proxy address
|
||||
/// @param _logicAddress (address)
|
||||
function enableLogic(address _logicAddress) public isAdmin {
|
||||
logicProxies[_logicAddress] = true;
|
||||
emit LogEnableLogic(_logicAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev enable logic proxy address and sets false
|
||||
* @param logicAddr is the logic proxy address
|
||||
*/
|
||||
function disableLogic(address logicAddr) public isAdmin {
|
||||
logicProxies[logicAddr] = false;
|
||||
emit LogDisableLogic(logicAddr);
|
||||
/// @dev Disable logic proxy address
|
||||
/// @param _logicAddress (address)
|
||||
function disableLogic(address _logicAddress) public isAdmin {
|
||||
logicProxies[_logicAddress] = false;
|
||||
emit LogDisableLogic(_logicAddress);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @title User Wallet Registry
|
||||
* @dev Deploys a new proxy instance and sets msg.sender as owner of proxy
|
||||
*/
|
||||
contract WalletRegistry is LogicRegistry {
|
||||
|
||||
event Created(address indexed sender, address indexed owner, address proxy);
|
||||
event LogRecord(address indexed currentOwner, address indexed nextOwner, address proxy);
|
||||
|
||||
/// @notice Address to UserWallet proxy map
|
||||
mapping(address => UserWallet) public proxies;
|
||||
|
||||
/**
|
||||
* @dev deploys a new proxy instance and sets msg.sender as owner of proxy
|
||||
*/
|
||||
|
||||
/// @dev Deploys a new proxy instance and sets custom owner of proxy
|
||||
/// Throws if the owner already have a UserWallet
|
||||
/// @return proxy ()
|
||||
function build() public returns (UserWallet proxy) {
|
||||
proxy = build(msg.sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev deploys a new proxy instance and sets custom owner of proxy
|
||||
* Throws if the owner already have a UserWallet
|
||||
*/
|
||||
/// @dev update the proxy record whenever owner changed on any proxy
|
||||
/// Throws if msg.sender is not a proxy contract created via this contract
|
||||
/// @return proxy () UserWallet
|
||||
function build(address owner) public returns (UserWallet proxy) {
|
||||
require(proxies[owner] == UserWallet(0), "multiple-proxy-per-user-not-allowed");
|
||||
proxy = new UserWallet();
|
||||
|
@ -125,29 +121,25 @@ contract WalletRegistry is LogicRegistry {
|
|||
emit Created(msg.sender, owner, address(proxy));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev update the proxy record whenever owner changed on any proxy
|
||||
* Throws if msg.sender is not a proxy contract created via this contract
|
||||
*/
|
||||
function record(address currentOwner, address nextOwner) public {
|
||||
require(msg.sender == address(proxies[currentOwner]), "invalid-proxy-or-owner");
|
||||
require(proxies[nextOwner] == UserWallet(0), "multiple-proxy-per-user-not-allowed");
|
||||
proxies[nextOwner] = proxies[currentOwner];
|
||||
proxies[currentOwner] = UserWallet(0);
|
||||
emit LogRecord(currentOwner, nextOwner, address(proxies[nextOwner]));
|
||||
/// @dev Transafers ownership
|
||||
/// @param _currentOwner (address) Current Owner
|
||||
/// @param _nextOwner (address) Next Owner
|
||||
function record(address _currentOwner, address _nextOwner) public {
|
||||
require(msg.sender == address(proxies[_currentOwner]), "invalid-proxy-or-owner");
|
||||
require(proxies[_nextOwner] == UserWallet(0), "multiple-proxy-per-user-not-allowed");
|
||||
proxies[_nextOwner] = proxies[_currentOwner];
|
||||
proxies[_currentOwner] = UserWallet(0);
|
||||
emit LogRecord(_currentOwner, _nextOwner, address(proxies[_nextOwner]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @title Initializing Registry
|
||||
*/
|
||||
/// @title InstaRegistry
|
||||
/// @dev Initializing Registry
|
||||
contract InstaRegistry is WalletRegistry {
|
||||
|
||||
constructor() public {
|
||||
registry[keccak256(abi.encodePacked("admin"))] = msg.sender;
|
||||
registry[keccak256(abi.encodePacked("owner"))] = msg.sender;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
/* solium-disable mixedcase */
|
||||
contract Migrations {
|
|
@ -1,5 +1,4 @@
|
|||
pragma solidity ^0.5.0;
|
||||
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
/**
|
||||
* @title Ownable
|
|
@ -1,25 +1,7 @@
|
|||
pragma solidity ^0.5.0;
|
||||
|
||||
|
||||
library SafeMath {
|
||||
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
if (a == 0) {
|
||||
return 0;
|
||||
}
|
||||
uint256 c = a * b;
|
||||
require(c / a == b, "Assertion Failed");
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
contract IERC20 {
|
||||
function balanceOf(address who) public view returns (uint256);
|
||||
function allowance(address _owner, address _spender) public view returns (uint256);
|
||||
function transfer(address to, uint256 value) public returns (bool);
|
||||
function approve(address spender, uint256 value) public returns (bool);
|
||||
function transferFrom(address from, address to, uint256 value) public returns (bool);
|
||||
}
|
||||
import "openzeppelin-solidity/contracts/math/SafeMath.sol";
|
||||
import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
|
||||
|
||||
|
||||
contract KyberInterface {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
pragma solidity ^0.5.0;
|
||||
|
||||
import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
|
||||
|
||||
interface TubInterface {
|
||||
function open() external returns (bytes32);
|
||||
|
|
|
@ -1,25 +1,7 @@
|
|||
pragma solidity ^0.5.0;
|
||||
|
||||
|
||||
library SafeMath {
|
||||
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
if (a == 0) {
|
||||
return 0;
|
||||
}
|
||||
uint256 c = a * b;
|
||||
require(c / a == b, "Assertion Failed");
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
contract IERC20 {
|
||||
function balanceOf(address who) public view returns (uint256);
|
||||
function allowance(address _owner, address _spender) public view returns (uint256);
|
||||
function transfer(address to, uint256 value) public returns (bool);
|
||||
function approve(address spender, uint256 value) public returns (bool);
|
||||
function transferFrom(address from, address to, uint256 value) public returns (bool);
|
||||
}
|
||||
import "openzeppelin-solidity/contracts/math/SafeMath.sol";
|
||||
import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
|
||||
|
||||
|
||||
contract UniswapFactory {
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
pragma solidity ^0.5.0;
|
||||
|
||||
interface IERC20 {
|
||||
function transfer(address to, uint256 value) external returns (bool);
|
||||
}
|
||||
|
||||
interface ICDP {
|
||||
function give(bytes32 cup, address guy) external;
|
||||
}
|
||||
|
||||
|
||||
contract ProxyTest {
|
||||
event LogTransferETH(address dest, uint amount);
|
||||
event LogTransferERC20(address token, address dest, uint amount);
|
||||
event LogTransferCDP(address dest, uint num);
|
||||
|
||||
function transferETH(address dest, uint amount) public payable {
|
||||
dest.transfer(amount);
|
||||
emit LogTransferETH(dest, amount);
|
||||
}
|
||||
|
||||
function transferERC20(address tokenAddr, address dest, address amount) public {
|
||||
IERC20 tkn = IERC20(tokenAddr);
|
||||
tkn.transfer(dest, amount);
|
||||
emit LogTransferERC20(tokenAddr, dest, amount);
|
||||
}
|
||||
|
||||
function transferCDP(address tub, address dest, uint num) public {
|
||||
ICDP loanMaster = ICDP(tub);
|
||||
loanMaster.give(bytes32(num), dest);
|
||||
emit LogTransferCDP(dest, num);
|
||||
}
|
||||
}
|
|
@ -1,20 +1,9 @@
|
|||
// This Auth Model also includes UserWallet Logics
|
||||
// TODO => make it single Auth code for future launch where this Auth Contract will be the owner of UserWallet
|
||||
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
|
||||
/**
|
||||
* @dev because math is not safe
|
||||
*/
|
||||
library SafeMath {
|
||||
function add(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
uint256 c = a + b;
|
||||
require(c >= a, "math-not-safe");
|
||||
return c;
|
||||
}
|
||||
}
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "openzeppelin-solidity/contracts/math/SafeMath.sol";
|
||||
|
||||
/**
|
||||
* @title AddressRegistryInterface Interface
|
||||
|
@ -30,8 +19,8 @@ interface AddressRegistryInterface {
|
|||
* @title UserWallet Interface
|
||||
*/
|
||||
// interface UserWalletInterface {
|
||||
// get the wallet address based on the owner of this wallet
|
||||
// and use execute interface from main UserWallet to call execute on this contract
|
||||
// get the wallet address based on the owner of this wallet
|
||||
// and use execute interface from main UserWallet to call execute on this contract
|
||||
// }
|
||||
|
||||
|
||||
|
@ -39,7 +28,6 @@ interface AddressRegistryInterface {
|
|||
* @title Address Registry Record
|
||||
*/
|
||||
contract AddressRecord {
|
||||
|
||||
/**
|
||||
* @dev address registry of system, logic and wallet addresses
|
||||
*/
|
||||
|
@ -151,14 +139,12 @@ contract UserAuth is AddressRecord {
|
|||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @title User Guardians
|
||||
* @dev the assigned guardian addresses (upto 3) can set new owners
|
||||
* but only after certain period of owner's inactivity (i.e. activePeriod)
|
||||
*/
|
||||
contract UserGuardian is UserAuth {
|
||||
|
||||
event LogSetGuardian(uint num, address indexed prevGuardian, address indexed newGuardian);
|
||||
event LogNewActivePeriod(uint newActivePeriod);
|
||||
event LogSetOwnerViaGuardian(address nextOwner, address indexed guardian);
|
||||
|
@ -213,12 +199,7 @@ contract UserGuardian is UserAuth {
|
|||
* @dev Throws if the msg.sender is not guardian
|
||||
*/
|
||||
function isGuardian(address _guardian) public view returns (bool) {
|
||||
if (
|
||||
_guardian == guardians[1] || _guardian == guardians[2] ||
|
||||
_guardian == guardians[3] || _guardian == guardians[4] ||
|
||||
_guardian == guardians[5]
|
||||
)
|
||||
{
|
||||
if (_guardian == guardians[1] || _guardian == guardians[2] || _guardian == guardians[3] || _guardian == guardians[4] || _guardian == guardians[5]) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -227,14 +208,12 @@ contract UserGuardian is UserAuth {
|
|||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @title User Manager
|
||||
* @dev the assigned manager addresses (upto 3) can manage the wealth in contract to contract fashion
|
||||
* but can't withdraw the assets on their personal address
|
||||
*/
|
||||
contract UserManager is UserGuardian {
|
||||
|
||||
event LogSetManager(uint num, address indexed prevManager, address indexed newManager);
|
||||
|
||||
mapping(uint => address) public managers;
|
||||
|
@ -263,12 +242,7 @@ contract UserManager is UserGuardian {
|
|||
* @dev Throws if the msg.sender is not manager
|
||||
*/
|
||||
function isManager(address _manager) public view returns (bool) {
|
||||
if (
|
||||
_manager == managers[1] || _manager == managers[2] ||
|
||||
_manager == managers[3] || _manager == managers[4] ||
|
||||
_manager == managers[5]
|
||||
)
|
||||
{
|
||||
if (_manager == managers[1] || _manager == managers[2] || _manager == managers[3] || _manager == managers[4] || _manager == managers[5]) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -277,19 +251,11 @@ contract UserManager is UserGuardian {
|
|||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @dev logging the execute events
|
||||
*/
|
||||
contract UserNote {
|
||||
event LogNote(
|
||||
bytes4 indexed sig,
|
||||
address indexed guy,
|
||||
bytes32 indexed foo,
|
||||
bytes32 bar,
|
||||
uint wad,
|
||||
bytes fax
|
||||
);
|
||||
event LogNote(bytes4 indexed sig, address indexed guy, bytes32 indexed foo, bytes32 bar, uint wad, bytes fax);
|
||||
|
||||
modifier note {
|
||||
bytes32 foo;
|
||||
|
@ -298,24 +264,15 @@ contract UserNote {
|
|||
foo := calldataload(4)
|
||||
bar := calldataload(36)
|
||||
}
|
||||
emit LogNote(
|
||||
msg.sig,
|
||||
msg.sender,
|
||||
foo,
|
||||
bar,
|
||||
msg.value,
|
||||
msg.data
|
||||
);
|
||||
emit LogNote(msg.sig, msg.sender, foo, bar, msg.value, msg.data);
|
||||
_;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @title User Owned Contract Wallet
|
||||
*/
|
||||
contract InstaWallet is UserManager, UserNote {
|
||||
|
||||
event LogExecute(address sender, address target, uint srcNum, uint sessionNum);
|
||||
|
||||
/**
|
||||
|
@ -337,12 +294,7 @@ contract InstaWallet is UserManager, UserNote {
|
|||
* @param srcNum to find the source
|
||||
* @param sessionNum to find the session
|
||||
*/
|
||||
function execute(
|
||||
address _target,
|
||||
bytes memory _data,
|
||||
uint srcNum,
|
||||
uint sessionNum
|
||||
)
|
||||
function execute(address _target, bytes memory _data, uint srcNum, uint sessionNum)
|
||||
public
|
||||
payable
|
||||
note
|
||||
|
@ -350,13 +302,8 @@ contract InstaWallet is UserManager, UserNote {
|
|||
returns (bytes memory response)
|
||||
{
|
||||
lastActivity = block.timestamp;
|
||||
emit LogExecute(
|
||||
msg.sender,
|
||||
_target,
|
||||
srcNum,
|
||||
sessionNum
|
||||
);
|
||||
|
||||
emit LogExecute(msg.sender, _target, srcNum, sessionNum);
|
||||
|
||||
// call contract in current context
|
||||
assembly {
|
||||
let succeeded := delegatecall(sub(gas, 5000), _target, add(_data, 0x20), mload(_data), 0, 0)
|
||||
|
@ -385,16 +332,16 @@ contract InstaWallet is UserManager, UserNote {
|
|||
|
||||
(bool isLogic, bool isDefault) = isLogicAuthorised(proxyTarget);
|
||||
require(isLogic, "logic-proxy-address-not-allowed");
|
||||
|
||||
|
||||
bool enact = false;
|
||||
if (isAuth(msg.sender)) {
|
||||
enact = true;
|
||||
} else if (isManager(msg.sender) && !isDefault) {
|
||||
enact = true;
|
||||
}
|
||||
|
||||
|
||||
require(enact, "not-executable");
|
||||
_;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,17 +1,6 @@
|
|||
pragma solidity ^0.5.0;
|
||||
|
||||
|
||||
/**
|
||||
* @dev because math is not safe
|
||||
*/
|
||||
library SafeMath {
|
||||
function add(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
uint256 c = a + b;
|
||||
require(c >= a, "math-not-safe");
|
||||
return c;
|
||||
}
|
||||
}
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "openzeppelin-solidity/contracts/math/SafeMath.sol";
|
||||
|
||||
/**
|
||||
* @title RegistryInterface Interface
|
||||
|
@ -21,7 +10,6 @@ interface RegistryInterface {
|
|||
function record(address currentOwner, address nextOwner) external;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @title Address Registry Record
|
||||
*/
|
||||
|
@ -85,7 +73,6 @@ contract UserAuth is AddressRecord {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -140,17 +127,17 @@ contract UserWallet is UserAuth, UserNote {
|
|||
function() external payable {}
|
||||
|
||||
/**
|
||||
* @dev execute authorised calls via delegate call
|
||||
* @dev Execute authorised calls via delegate call
|
||||
* @param _target logic proxy address
|
||||
* @param _data delegate call data
|
||||
* @param srcNum to find the source
|
||||
* @param sessionNum to find the session
|
||||
* @param _srcNum to find the source
|
||||
* @param _sessionNum to find the session
|
||||
*/
|
||||
function execute(
|
||||
address _target,
|
||||
bytes memory _data,
|
||||
uint srcNum,
|
||||
uint sessionNum
|
||||
uint _srcNum,
|
||||
uint _sessionNum
|
||||
)
|
||||
public
|
||||
payable
|
||||
|
@ -162,8 +149,8 @@ contract UserWallet is UserAuth, UserNote {
|
|||
emit LogExecute(
|
||||
msg.sender,
|
||||
_target,
|
||||
srcNum,
|
||||
sessionNum
|
||||
_srcNum,
|
||||
_sessionNum
|
||||
);
|
||||
|
||||
// call contract in current context
|
||||
|
|
120
docs/FreeProxy.json
Normal file
120
docs/FreeProxy.json
Normal file
|
@ -0,0 +1,120 @@
|
|||
{
|
||||
"schemaVersion": "2.0.0",
|
||||
"contractName": "FreeProxy",
|
||||
"compilerOutput": {
|
||||
"abi": [
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "getAddressWETH",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "weth",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "pure",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "getWETHBal",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "freeJam",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [],
|
||||
"name": "withdrawWETH",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "getSaiWETH",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "wamt",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "freeWETH",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "getSaiTubAddress",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "sai",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "pure",
|
||||
"type": "function"
|
||||
}
|
||||
],
|
||||
"devdoc": {
|
||||
"methods": {}
|
||||
}
|
||||
},
|
||||
"sources": {
|
||||
"Bin/FreeProxy.sol": {
|
||||
"id": 0
|
||||
}
|
||||
},
|
||||
"sourceCodes": {
|
||||
"Bin/FreeProxy.sol": "pragma solidity ^0.5.2;\n\n\ninterface TubInterface {\n function gem() external view returns (TokenInterface);\n}\n\n\ninterface TokenInterface {\n function allowance(address, address) external view returns (uint);\n function balanceOf(address) external view returns (uint);\n function transfer(address, uint) external returns (bool);\n function approve(address, uint) external;\n function withdraw(uint) external;\n}\n\n\ncontract FreeProxy {\n\n function getSaiTubAddress() public pure returns (address sai) {\n sai = 0x448a5065aeBB8E423F0896E6c5D525C040f59af3;\n }\n\n function getAddressWETH() public pure returns (address weth) {\n weth = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;\n }\n\n function freeWETH(uint wamt) public {\n TubInterface tub = TubInterface(getSaiTubAddress());\n TokenInterface weth = tub.gem();\n\n uint freeJam = wamt;\n if (freeJam == 0) {\n freeJam = weth.balanceOf(address(this));\n }\n\n weth.withdraw(freeJam);\n msg.sender.transfer(freeJam);\n }\n\n function withdrawWETH() public {\n TubInterface tub = TubInterface(getSaiTubAddress());\n TokenInterface weth = tub.gem();\n uint freeJam = weth.balanceOf(address(this));\n weth.transfer(msg.sender, freeJam);\n }\n\n function getWETHBal() public view returns (uint freeJam) {\n TubInterface tub = TubInterface(getSaiTubAddress());\n TokenInterface weth = tub.gem();\n freeJam = weth.balanceOf(address(this));\n }\n\n function getSaiWETH() public view returns (address) {\n TubInterface tub = TubInterface(getSaiTubAddress());\n return address(tub.gem());\n }\n\n function setAllowance(TokenInterface token_, address spender_) private {\n if (token_.allowance(address(this), spender_) != uint(-1)) {\n token_.approve(spender_, uint(-1));\n }\n }\n\n}"
|
||||
},
|
||||
"sourceTreeHashHex": "0xa7b0a10e45beb64aec3d940e4bc0933e5908591468fdd83a5c8e0ec82332600f",
|
||||
"compiler": {
|
||||
"name": "solc",
|
||||
"version": "soljson-v0.5.7+commit.6da8b019.js",
|
||||
"settings": {
|
||||
"optimizer": {
|
||||
"enabled": false
|
||||
},
|
||||
"outputSelection": {
|
||||
"*": {
|
||||
"*": [
|
||||
"abi",
|
||||
"devdoc"
|
||||
]
|
||||
}
|
||||
},
|
||||
"remappings": [
|
||||
"openzeppelin-solidity=/Users/ravindra/code/contract-v2/node_modules/openzeppelin-solidity"
|
||||
]
|
||||
}
|
||||
},
|
||||
"networks": {}
|
||||
}
|
414
docs/InstaRegistry.json
Normal file
414
docs/InstaRegistry.json
Normal file
File diff suppressed because one or more lines are too long
653
docs/InstaWallet.json
Normal file
653
docs/InstaWallet.json
Normal file
File diff suppressed because one or more lines are too long
123
docs/Kyber.json
Normal file
123
docs/Kyber.json
Normal file
File diff suppressed because one or more lines are too long
103
docs/Migrations.json
Normal file
103
docs/Migrations.json
Normal file
|
@ -0,0 +1,103 @@
|
|||
{
|
||||
"schemaVersion": "2.0.0",
|
||||
"contractName": "Migrations",
|
||||
"compilerOutput": {
|
||||
"abi": [
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_newAddress",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "upgrade",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "last_completed_migration",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "owner",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "completed",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "setCompleted",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
}
|
||||
],
|
||||
"devdoc": {
|
||||
"methods": {}
|
||||
}
|
||||
},
|
||||
"sources": {
|
||||
"Migrations.sol": {
|
||||
"id": 2
|
||||
}
|
||||
},
|
||||
"sourceCodes": {
|
||||
"Migrations.sol": "pragma solidity ^0.5.2;\n\n/* solium-disable mixedcase */\ncontract Migrations {\n address public owner;\n uint public last_completed_migration;\n\n modifier restricted() {\n if (msg.sender == owner) _;\n }\n\n constructor() public {\n owner = msg.sender;\n }\n\n function setCompleted(uint completed) public restricted {\n last_completed_migration = completed;\n }\n\n function upgrade(address _newAddress) public restricted {\n Migrations upgraded = Migrations(_newAddress);\n upgraded.setCompleted(last_completed_migration);\n }\n}\n\n/* solium-enable mixedcase */\n\n"
|
||||
},
|
||||
"sourceTreeHashHex": "0x0f2d82013d4aed92814a1528a406877135ec86becc13d0656d0c375d2cee8715",
|
||||
"compiler": {
|
||||
"name": "solc",
|
||||
"version": "soljson-v0.5.7+commit.6da8b019.js",
|
||||
"settings": {
|
||||
"optimizer": {
|
||||
"enabled": false
|
||||
},
|
||||
"outputSelection": {
|
||||
"*": {
|
||||
"*": [
|
||||
"abi",
|
||||
"devdoc"
|
||||
]
|
||||
}
|
||||
},
|
||||
"remappings": [
|
||||
"openzeppelin-solidity=/Users/ravindra/code/contract-v2/node_modules/openzeppelin-solidity"
|
||||
]
|
||||
}
|
||||
},
|
||||
"networks": {}
|
||||
}
|
104
docs/Ownable.json
Normal file
104
docs/Ownable.json
Normal file
|
@ -0,0 +1,104 @@
|
|||
{
|
||||
"schemaVersion": "2.0.0",
|
||||
"contractName": "Ownable",
|
||||
"compilerOutput": {
|
||||
"abi": [
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "owner",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "newOwner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "transferOwnership",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "previousOwner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "newOwner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "OwnershipTransferred",
|
||||
"type": "event"
|
||||
}
|
||||
],
|
||||
"devdoc": {
|
||||
"details": "The Ownable contract has an owner address, and provides basic authorization control functions, this simplifies the implementation of \"user permissions\".",
|
||||
"methods": {
|
||||
"constructor": {
|
||||
"details": "The Ownable constructor sets the original `owner` of the contract to the sender account."
|
||||
},
|
||||
"transferOwnership(address)": {
|
||||
"details": "Allows the current owner to transfer control of the contract to a newOwner.",
|
||||
"params": {
|
||||
"newOwner": "The address to transfer ownership to."
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "Ownable"
|
||||
}
|
||||
},
|
||||
"sources": {
|
||||
"Ownable.sol": {
|
||||
"id": 3
|
||||
}
|
||||
},
|
||||
"sourceCodes": {
|
||||
"Ownable.sol": "pragma solidity ^0.5.2;\n\n/**\n * @title Ownable\n * @dev The Ownable contract has an owner address, and provides basic authorization control\n * functions, this simplifies the implementation of \"user permissions\".\n */\ncontract Ownable {\n address public owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev The Ownable constructor sets the original `owner` of the contract to the sender\n * account.\n */\n constructor() public {\n owner = msg.sender;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(msg.sender == owner, \"Only owner accessible\");\n _;\n }\n\n /**\n * @dev Allows the current owner to transfer control of the contract to a newOwner.\n * @param newOwner The address to transfer ownership to.\n */\n function transferOwnership(address newOwner) public onlyOwner {\n require(newOwner != address(0), \"Address not equal to zero\");\n emit OwnershipTransferred(owner, newOwner);\n owner = newOwner;\n }\n}\n"
|
||||
},
|
||||
"sourceTreeHashHex": "0xae5de39110dc28711c6edf34bdad44412eaf72392d1e8fe47add94c996022218",
|
||||
"compiler": {
|
||||
"name": "solc",
|
||||
"version": "soljson-v0.5.7+commit.6da8b019.js",
|
||||
"settings": {
|
||||
"optimizer": {
|
||||
"enabled": false
|
||||
},
|
||||
"outputSelection": {
|
||||
"*": {
|
||||
"*": [
|
||||
"abi",
|
||||
"devdoc"
|
||||
]
|
||||
}
|
||||
},
|
||||
"remappings": [
|
||||
"openzeppelin-solidity=/Users/ravindra/code/contract-v2/node_modules/openzeppelin-solidity"
|
||||
]
|
||||
}
|
||||
},
|
||||
"networks": {}
|
||||
}
|
326
docs/Trade.json
Normal file
326
docs/Trade.json
Normal file
File diff suppressed because one or more lines are too long
224
docs/UniswapTrade.json
Normal file
224
docs/UniswapTrade.json
Normal file
File diff suppressed because one or more lines are too long
243
docs/UserWallet.json
Normal file
243
docs/UserWallet.json
Normal file
|
@ -0,0 +1,243 @@
|
|||
{
|
||||
"schemaVersion": "2.0.0",
|
||||
"contractName": "UserWallet",
|
||||
"compilerOutput": {
|
||||
"abi": [
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "nextOwner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "setOwner",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "src",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "isAuth",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "registry",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "owner",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_target",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_data",
|
||||
"type": "bytes"
|
||||
},
|
||||
{
|
||||
"name": "_srcNum",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "_sessionNum",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "execute",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "response",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"payable": true,
|
||||
"stateMutability": "payable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"payable": true,
|
||||
"stateMutability": "payable",
|
||||
"type": "fallback"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "sender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "srcNum",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "sessionNum",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "LogExecute",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "sig",
|
||||
"type": "bytes4"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "guy",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "foo",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "bar",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "wad",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "fax",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "LogNote",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "LogSetOwner",
|
||||
"type": "event"
|
||||
}
|
||||
],
|
||||
"devdoc": {
|
||||
"methods": {
|
||||
"constructor": {
|
||||
"details": "sets the \"address registry\", owner's last activity, owner's active period and initial owner"
|
||||
},
|
||||
"execute(address,bytes,uint256,uint256)": {
|
||||
"details": "Execute authorised calls via delegate call",
|
||||
"params": {
|
||||
"_data": "delegate call data",
|
||||
"_sessionNum": "to find the session",
|
||||
"_srcNum": "to find the source",
|
||||
"_target": "logic proxy address"
|
||||
}
|
||||
},
|
||||
"isAuth(address)": {
|
||||
"details": "checks if called by owner or contract itself",
|
||||
"params": {
|
||||
"src": "is the address initiating the call"
|
||||
}
|
||||
},
|
||||
"setOwner(address)": {
|
||||
"details": "sets new owner"
|
||||
}
|
||||
},
|
||||
"title": "User Owned Contract Wallet"
|
||||
}
|
||||
},
|
||||
"sources": {
|
||||
"UserWallet.sol": {
|
||||
"id": 1
|
||||
}
|
||||
},
|
||||
"sourceCodes": {
|
||||
"UserWallet.sol": "pragma solidity ^0.5.2;\n\n\n/**\n * @dev because math is not safe \n */\nlibrary SafeMath {\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"math-not-safe\");\n return c;\n }\n}\n\n\n/**\n * @title RegistryInterface Interface \n */\ninterface RegistryInterface {\n function logic(address logicAddr) external view returns (bool);\n function record(address currentOwner, address nextOwner) external;\n}\n\n\n/**\n * @title Address Registry Record\n */\ncontract AddressRecord {\n\n /**\n * @dev address registry of system, logic and wallet addresses\n */\n address public registry;\n\n /**\n * @dev Throws if the logic is not authorised\n */\n modifier logicAuth(address logicAddr) {\n require(logicAddr != address(0), \"logic-proxy-address-required\");\n bool islogic = RegistryInterface(registry).logic(logicAddr);\n require(islogic, \"logic-not-authorised\");\n _;\n }\n\n}\n\n\n/**\n * @title User Auth\n */\ncontract UserAuth is AddressRecord {\n using SafeMath for uint;\n using SafeMath for uint256;\n\n event LogSetOwner(address indexed owner);\n address public owner;\n\n /**\n * @dev Throws if not called by owner or contract itself\n */\n modifier auth {\n require(isAuth(msg.sender), \"permission-denied\");\n _;\n }\n\n /**\n * @dev sets new owner\n */\n function setOwner(address nextOwner) public auth {\n RegistryInterface(registry).record(owner, nextOwner);\n owner = nextOwner;\n emit LogSetOwner(nextOwner);\n }\n\n /**\n * @dev checks if called by owner or contract itself\n * @param src is the address initiating the call\n */\n function isAuth(address src) public view returns (bool) {\n if (src == owner) {\n return true;\n } else if (src == address(this)) {\n return true;\n } else {\n return false;\n }\n }\n}\n\n\n/**\n * @dev logging the execute events\n */\ncontract UserNote {\n event LogNote(\n bytes4 indexed sig,\n address indexed guy,\n bytes32 indexed foo,\n bytes32 bar,\n uint wad,\n bytes fax\n );\n\n modifier note {\n bytes32 foo;\n bytes32 bar;\n assembly {\n foo := calldataload(4)\n bar := calldataload(36)\n }\n emit LogNote(\n msg.sig, \n msg.sender, \n foo, \n bar, \n msg.value,\n msg.data\n );\n _;\n }\n}\n\n\n/**\n * @title User Owned Contract Wallet\n */\ncontract UserWallet is UserAuth, UserNote {\n\n event LogExecute(address sender, address target, uint srcNum, uint sessionNum);\n\n /**\n * @dev sets the \"address registry\", owner's last activity, owner's active period and initial owner\n */\n constructor() public {\n registry = msg.sender;\n owner = msg.sender;\n }\n\n function() external payable {}\n\n /**\n * @dev Execute authorised calls via delegate call\n * @param _target logic proxy address\n * @param _data delegate call data\n * @param _srcNum to find the source\n * @param _sessionNum to find the session\n */\n function execute(\n address _target,\n bytes memory _data,\n uint _srcNum,\n uint _sessionNum\n ) \n public\n payable\n note\n auth\n logicAuth(_target)\n returns (bytes memory response)\n {\n emit LogExecute(\n msg.sender,\n _target,\n _srcNum,\n _sessionNum\n );\n \n // call contract in current context\n assembly {\n let succeeded := delegatecall(sub(gas, 5000), _target, add(_data, 0x20), mload(_data), 0, 0)\n let size := returndatasize\n\n response := mload(0x40)\n mstore(0x40, add(response, and(add(add(size, 0x20), 0x1f), not(0x1f))))\n mstore(response, size)\n returndatacopy(add(response, 0x20), 0, size)\n\n switch iszero(succeeded)\n case 1 {\n // throw if delegatecall failed\n revert(add(response, 0x20), size)\n }\n }\n }\n\n}"
|
||||
},
|
||||
"sourceTreeHashHex": "0x6c8771a0594acf5f4a7381dae9cf00c28b9cc899151276a8b989eb2edb21c22e",
|
||||
"compiler": {
|
||||
"name": "solc",
|
||||
"version": "soljson-v0.5.7+commit.6da8b019.js",
|
||||
"settings": {
|
||||
"optimizer": {
|
||||
"enabled": false
|
||||
},
|
||||
"outputSelection": {
|
||||
"*": {
|
||||
"*": [
|
||||
"abi",
|
||||
"devdoc"
|
||||
]
|
||||
}
|
||||
},
|
||||
"remappings": [
|
||||
"openzeppelin-solidity=/Users/ravindra/code/contract-v2/node_modules/openzeppelin-solidity"
|
||||
]
|
||||
}
|
||||
},
|
||||
"networks": {}
|
||||
}
|
391
flats/InstaRegistry.sol
Normal file
391
flats/InstaRegistry.sol
Normal file
|
@ -0,0 +1,391 @@
|
|||
|
||||
// File: openzeppelin-solidity/contracts/math/SafeMath.sol
|
||||
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
/**
|
||||
* @title SafeMath
|
||||
* @dev Unsigned math operations with safety checks that revert on error
|
||||
*/
|
||||
library SafeMath {
|
||||
/**
|
||||
* @dev Multiplies two unsigned integers, reverts on overflow.
|
||||
*/
|
||||
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
|
||||
// benefit is lost if 'b' is also tested.
|
||||
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
|
||||
if (a == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint256 c = a * b;
|
||||
require(c / a == b);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.
|
||||
*/
|
||||
function div(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
// Solidity only automatically asserts when dividing by 0
|
||||
require(b > 0);
|
||||
uint256 c = a / b;
|
||||
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
|
||||
*/
|
||||
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
require(b <= a);
|
||||
uint256 c = a - b;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Adds two unsigned integers, reverts on overflow.
|
||||
*/
|
||||
function add(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
uint256 c = a + b;
|
||||
require(c >= a);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo),
|
||||
* reverts when dividing by zero.
|
||||
*/
|
||||
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
require(b != 0);
|
||||
return a % b;
|
||||
}
|
||||
}
|
||||
|
||||
// File: contracts/UserWallet.sol
|
||||
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
|
||||
/**
|
||||
* @title RegistryInterface Interface
|
||||
*/
|
||||
interface RegistryInterface {
|
||||
function logic(address logicAddr) external view returns (bool);
|
||||
function record(address currentOwner, address nextOwner) external;
|
||||
}
|
||||
|
||||
/**
|
||||
* @title Address Registry Record
|
||||
*/
|
||||
contract AddressRecord {
|
||||
|
||||
/**
|
||||
* @dev address registry of system, logic and wallet addresses
|
||||
*/
|
||||
address public registry;
|
||||
|
||||
/**
|
||||
* @dev Throws if the logic is not authorised
|
||||
*/
|
||||
modifier logicAuth(address logicAddr) {
|
||||
require(logicAddr != address(0), "logic-proxy-address-required");
|
||||
bool islogic = RegistryInterface(registry).logic(logicAddr);
|
||||
require(islogic, "logic-not-authorised");
|
||||
_;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @title User Auth
|
||||
*/
|
||||
contract UserAuth is AddressRecord {
|
||||
using SafeMath for uint;
|
||||
using SafeMath for uint256;
|
||||
|
||||
event LogSetOwner(address indexed owner);
|
||||
address public owner;
|
||||
|
||||
/**
|
||||
* @dev Throws if not called by owner or contract itself
|
||||
*/
|
||||
modifier auth {
|
||||
require(isAuth(msg.sender), "permission-denied");
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev sets new owner
|
||||
*/
|
||||
function setOwner(address nextOwner) public auth {
|
||||
RegistryInterface(registry).record(owner, nextOwner);
|
||||
owner = nextOwner;
|
||||
emit LogSetOwner(nextOwner);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev checks if called by owner or contract itself
|
||||
* @param src is the address initiating the call
|
||||
*/
|
||||
function isAuth(address src) public view returns (bool) {
|
||||
if (src == owner) {
|
||||
return true;
|
||||
} else if (src == address(this)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @dev logging the execute events
|
||||
*/
|
||||
contract UserNote {
|
||||
event LogNote(
|
||||
bytes4 indexed sig,
|
||||
address indexed guy,
|
||||
bytes32 indexed foo,
|
||||
bytes32 bar,
|
||||
uint wad,
|
||||
bytes fax
|
||||
);
|
||||
|
||||
modifier note {
|
||||
bytes32 foo;
|
||||
bytes32 bar;
|
||||
assembly {
|
||||
foo := calldataload(4)
|
||||
bar := calldataload(36)
|
||||
}
|
||||
emit LogNote(
|
||||
msg.sig,
|
||||
msg.sender,
|
||||
foo,
|
||||
bar,
|
||||
msg.value,
|
||||
msg.data
|
||||
);
|
||||
_;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @title User Owned Contract Wallet
|
||||
*/
|
||||
contract UserWallet is UserAuth, UserNote {
|
||||
|
||||
event LogExecute(address sender, address target, uint srcNum, uint sessionNum);
|
||||
|
||||
/**
|
||||
* @dev sets the "address registry", owner's last activity, owner's active period and initial owner
|
||||
*/
|
||||
constructor() public {
|
||||
registry = msg.sender;
|
||||
owner = msg.sender;
|
||||
}
|
||||
|
||||
function() external payable {}
|
||||
|
||||
/**
|
||||
* @dev Execute authorised calls via delegate call
|
||||
* @param _target logic proxy address
|
||||
* @param _data delegate call data
|
||||
* @param _srcNum to find the source
|
||||
* @param _sessionNum to find the session
|
||||
*/
|
||||
function execute(
|
||||
address _target,
|
||||
bytes memory _data,
|
||||
uint _srcNum,
|
||||
uint _sessionNum
|
||||
)
|
||||
public
|
||||
payable
|
||||
note
|
||||
auth
|
||||
logicAuth(_target)
|
||||
returns (bytes memory response)
|
||||
{
|
||||
emit LogExecute(
|
||||
msg.sender,
|
||||
_target,
|
||||
_srcNum,
|
||||
_sessionNum
|
||||
);
|
||||
|
||||
// call contract in current context
|
||||
assembly {
|
||||
let succeeded := delegatecall(sub(gas, 5000), _target, add(_data, 0x20), mload(_data), 0, 0)
|
||||
let size := returndatasize
|
||||
|
||||
response := mload(0x40)
|
||||
mstore(0x40, add(response, and(add(add(size, 0x20), 0x1f), not(0x1f))))
|
||||
mstore(response, size)
|
||||
returndatacopy(add(response, 0x20), 0, size)
|
||||
|
||||
switch iszero(succeeded)
|
||||
case 1 {
|
||||
// throw if delegatecall failed
|
||||
revert(add(response, 0x20), size)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// File: contracts/InstaRegistry.sol
|
||||
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
|
||||
|
||||
/// @title AddressRegistry
|
||||
/// @notice
|
||||
/// @dev
|
||||
contract AddressRegistry {
|
||||
event LogSetAddress(string name, address addr);
|
||||
|
||||
/// @notice Registry of role and address
|
||||
mapping(bytes32 => address) registry;
|
||||
|
||||
/**
|
||||
* @dev Check if msg.sender is admin or owner.
|
||||
*/
|
||||
modifier isAdmin() {
|
||||
require(
|
||||
msg.sender == getAddress("admin") ||
|
||||
msg.sender == getAddress("owner"),
|
||||
"permission-denied"
|
||||
);
|
||||
_;
|
||||
}
|
||||
|
||||
/// @dev Get the address from system registry
|
||||
/// @param _name (string)
|
||||
/// @return (address) Returns address based on role
|
||||
function getAddress(string memory _name) public view returns(address) {
|
||||
return registry[keccak256(abi.encodePacked(_name))];
|
||||
}
|
||||
|
||||
/// @dev Set new address in system registry
|
||||
/// @param _name (string) Role name
|
||||
/// @param _userAddress (string) User Address
|
||||
function setAddress(string memory _name, address _userAddress) public isAdmin {
|
||||
registry[keccak256(abi.encodePacked(_name))] = _userAddress;
|
||||
emit LogSetAddress(_name, _userAddress);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// @title LogicRegistry
|
||||
/// @notice
|
||||
/// @dev LogicRegistry
|
||||
contract LogicRegistry is AddressRegistry {
|
||||
|
||||
event LogEnableDefaultLogic(address logicAddress);
|
||||
event LogEnableLogic(address logicAddress);
|
||||
event LogDisableLogic(address logicAddress);
|
||||
|
||||
/// @notice Map of default proxy state
|
||||
mapping(address => bool) public defaultLogicProxies;
|
||||
|
||||
/// @notice Map of logic proxy state
|
||||
mapping(address => bool) public logicProxies;
|
||||
|
||||
/// @dev
|
||||
/// @param _logicAddress (address)
|
||||
/// @return (bool)
|
||||
function logic(address _logicAddress) public view returns (bool) {
|
||||
if (defaultLogicProxies[_logicAddress] || logicProxies[_logicAddress]) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Sets the default logic proxy to true
|
||||
/// default proxies mostly contains the logic for withdrawal of assets
|
||||
/// and can never be false to freely let user withdraw their assets
|
||||
/// @param _logicAddress (address)
|
||||
function enableDefaultLogic(address _logicAddress) public isAdmin {
|
||||
defaultLogicProxies[_logicAddress] = true;
|
||||
emit LogEnableDefaultLogic(_logicAddress);
|
||||
}
|
||||
|
||||
/// @dev Enable logic proxy address
|
||||
/// @param _logicAddress (address)
|
||||
function enableLogic(address _logicAddress) public isAdmin {
|
||||
logicProxies[_logicAddress] = true;
|
||||
emit LogEnableLogic(_logicAddress);
|
||||
}
|
||||
|
||||
/// @dev Disable logic proxy address
|
||||
/// @param _logicAddress (address)
|
||||
function disableLogic(address _logicAddress) public isAdmin {
|
||||
logicProxies[_logicAddress] = false;
|
||||
emit LogDisableLogic(_logicAddress);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Deploys a new proxy instance and sets msg.sender as owner of proxy
|
||||
*/
|
||||
contract WalletRegistry is LogicRegistry {
|
||||
|
||||
event Created(address indexed sender, address indexed owner, address proxy);
|
||||
event LogRecord(address indexed currentOwner, address indexed nextOwner, address proxy);
|
||||
|
||||
/// @notice Address to UserWallet proxy map
|
||||
mapping(address => UserWallet) public proxies;
|
||||
|
||||
/// @dev Deploys a new proxy instance and sets custom owner of proxy
|
||||
/// Throws if the owner already have a UserWallet
|
||||
/// @return proxy ()
|
||||
function build() public returns (UserWallet proxy) {
|
||||
proxy = build(msg.sender);
|
||||
}
|
||||
|
||||
/// @dev update the proxy record whenever owner changed on any proxy
|
||||
/// Throws if msg.sender is not a proxy contract created via this contract
|
||||
/// @return proxy () UserWallet
|
||||
function build(address owner) public returns (UserWallet proxy) {
|
||||
require(proxies[owner] == UserWallet(0), "multiple-proxy-per-user-not-allowed");
|
||||
proxy = new UserWallet();
|
||||
proxies[address(this)] = proxy; // will be changed via record() in next line execution
|
||||
proxy.setOwner(owner);
|
||||
emit Created(msg.sender, owner, address(proxy));
|
||||
}
|
||||
|
||||
/// @dev Transafers ownership
|
||||
/// @param _currentOwner (address) Current Owner
|
||||
/// @param _nextOwner (address) Next Owner
|
||||
function record(address _currentOwner, address _nextOwner) public {
|
||||
require(msg.sender == address(proxies[_currentOwner]), "invalid-proxy-or-owner");
|
||||
require(proxies[_nextOwner] == UserWallet(0), "multiple-proxy-per-user-not-allowed");
|
||||
proxies[_nextOwner] = proxies[_currentOwner];
|
||||
proxies[_currentOwner] = UserWallet(0);
|
||||
emit LogRecord(_currentOwner, _nextOwner, address(proxies[_nextOwner]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @title InstaRegistry
|
||||
/// @dev Initializing Registry
|
||||
contract InstaRegistry is WalletRegistry {
|
||||
|
||||
constructor() public {
|
||||
registry[keccak256(abi.encodePacked("admin"))] = msg.sender;
|
||||
registry[keccak256(abi.encodePacked("owner"))] = msg.sender;
|
||||
}
|
||||
}
|
53
package.json
53
package.json
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "smart-contract-starter",
|
||||
"name": "instadapp-contracts",
|
||||
"description": "Boilerplate for your next Smart Contract, made simple.",
|
||||
"version": "0.0.1",
|
||||
"version": "0.0.2",
|
||||
"author": "Ravindra Kumar <ravidsrk@gmail.com>",
|
||||
"license": "MIT",
|
||||
"main": "truffle.js",
|
||||
|
@ -11,26 +11,34 @@
|
|||
"scripts": {
|
||||
"ganache": "ganache-cli -e 300 -p 9545 -m 'candy maple cake sugar pudding cream honey rich smooth crumble sweet treat' --accounts 30 > /dev/null &",
|
||||
"stop": "sudo kill `sudo lsof -t -i:9545`",
|
||||
"test": "npm run ganache sleep 5 && npm run lint ./ && npm run solium && truffle test && npm run stop",
|
||||
"test": "npm run ganache sleep 5 && truffle test && npm run stop",
|
||||
"test:gas-reporter": "GAS_REPORTER=true npm run test",
|
||||
"test-ci": "GAS_REPORTER=true npm run ganache sleep 5 && npm run lint ./ && npm run solium && truffle test",
|
||||
"test-ci": "GAS_REPORTER=true npm run ganache sleep 5 && truffle test",
|
||||
"coverage": "./node_modules/.bin/solidity-coverage",
|
||||
"lint": "eslint ./test",
|
||||
"lint:fix": "eslint ./ --fix",
|
||||
"solium": "solium -d contracts/",
|
||||
"solium:fix": "solium -d contracts/ --fix",
|
||||
"build": "npm run clean:contracts && truffle compile"
|
||||
"build": "npm run clean:contracts && truffle compile",
|
||||
"audit": "truffle run verify",
|
||||
"docs": "sol-compiler",
|
||||
"flat": "truffle-flattener contracts/InstaRegistry.sol > flats/InstaRegistry.sol",
|
||||
"deploy:testnet": "truffle migrate --network kovan"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/sol-compiler": "^3.1.5",
|
||||
"bn.js": "^4.11.8",
|
||||
"dotenv": "^6.2.0",
|
||||
"dotenv": "^7.0.0",
|
||||
"ethereumjs-wallet": "^0.6.3",
|
||||
"npm-check-updates": "^2.15.0",
|
||||
"openzeppelin-solidity": "^2.0.0",
|
||||
"truffle": "^5.0.0",
|
||||
"truffle-hdwallet-provider": "^1.0.1",
|
||||
"npm-check-updates": "^3.1.4",
|
||||
"openzeppelin-solidity": "^2.2.0",
|
||||
"truffle": "^5.0.11",
|
||||
"truffle-assertions": "^0.8.2",
|
||||
"truffle-flattener": "^1.3.0",
|
||||
"truffle-hdwallet-provider": "^1.0.6",
|
||||
"truffle-security": "^1.3.2",
|
||||
"web3": "^1.0.0-beta.37",
|
||||
"webpack": "^4.28.1"
|
||||
"webpack": "^4.29.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-cli": "^6.26.0",
|
||||
|
@ -44,25 +52,26 @@
|
|||
"chai": "4.2.0",
|
||||
"chai-as-promised": "7.1.1",
|
||||
"chai-bignumber": "3.0.0",
|
||||
"coveralls": "3.0.2",
|
||||
"eslint": "5.10.0",
|
||||
"eslint-config-prettier": "^3.3.0",
|
||||
"coveralls": "3.0.3",
|
||||
"eslint": "5.16.0",
|
||||
"eslint-config-prettier": "^4.1.0",
|
||||
"eslint-config-standard": "^12.0.0",
|
||||
"eslint-plugin-babel": "^5.3.0",
|
||||
"eslint-plugin-compat": "^2.6.3",
|
||||
"eslint-plugin-import": "2.14.0",
|
||||
"eslint-plugin-node": "8.0.0",
|
||||
"eslint-plugin-prettier": "^3.0.0",
|
||||
"eslint-plugin-promise": "4.0.1",
|
||||
"eslint-plugin-compat": "^3.1.0",
|
||||
"eslint-plugin-import": "2.16.0",
|
||||
"eslint-plugin-node": "8.0.1",
|
||||
"eslint-plugin-prettier": "^3.0.1",
|
||||
"eslint-plugin-promise": "4.1.1",
|
||||
"eslint-plugin-security": "^1.4.0",
|
||||
"eslint-plugin-standard": "^4.0.0",
|
||||
"eth-gas-reporter": "^0.1.12",
|
||||
"ganache-cli": "^6.2.5",
|
||||
"mocha-junit-reporter": "^1.18.0",
|
||||
"ganache-cli": "^6.4.2",
|
||||
"mocha-junit-reporter": "^1.21.0",
|
||||
"mocha-multi-reporters": "^1.1.7",
|
||||
"openzeppelin-test-helpers": "^0.3.1",
|
||||
"prettier": "^1.16.4",
|
||||
"prettier-plugin-solidity-refactor": "^1.0.0-alpha.14",
|
||||
"solidity-coverage": "0.5.11",
|
||||
"solium": "1.1.8"
|
||||
"solium": "1.2.3"
|
||||
}
|
||||
}
|
||||
|
|
47
test/InstaRegistry.test.js
Normal file
47
test/InstaRegistry.test.js
Normal file
|
@ -0,0 +1,47 @@
|
|||
const truffleAssert = require('truffle-assertions')
|
||||
const { assertRevert } = require('./helpers/general')
|
||||
const InstaRegistry = artifacts.require('InstaRegistry')
|
||||
|
||||
contract('InstaRegistry', accounts => {
|
||||
let instaRegistry
|
||||
const user = accounts[0]
|
||||
|
||||
beforeEach(async () => {
|
||||
instaRegistry = await InstaRegistry.new({
|
||||
from: user
|
||||
})
|
||||
})
|
||||
|
||||
it('user should be owner and admin', async () => {
|
||||
const admin = await instaRegistry.getAddress('admin', {
|
||||
from: user
|
||||
})
|
||||
|
||||
assert.equal(admin, user, 'user is admin')
|
||||
})
|
||||
|
||||
it('only admin or owner should be able to set address', async () => {
|
||||
const result = await instaRegistry.setAddress('admin', accounts[2], {
|
||||
from: user
|
||||
})
|
||||
|
||||
expect(result.receipt.status).to.equal(true)
|
||||
truffleAssert.prettyPrintEmittedEvents(result)
|
||||
truffleAssert.eventEmitted(
|
||||
result,
|
||||
'LogSetAddress',
|
||||
event => {
|
||||
return event.name === 'admin' && event.addr === accounts[2]
|
||||
},
|
||||
'LogSetAddress should be emitted with correct parameters'
|
||||
)
|
||||
})
|
||||
|
||||
it('revert when non-admin tries to set address', async () => {
|
||||
await assertRevert(
|
||||
instaRegistry.setAddress('admin', accounts[2], {
|
||||
from: user
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
|
@ -1,4 +1,4 @@
|
|||
const { assertRevert } = require('./helpers/general')
|
||||
const { shouldFail } = require('openzeppelin-test-helpers')
|
||||
|
||||
const Ownable = artifacts.require('Ownable')
|
||||
|
||||
|
@ -26,6 +26,9 @@ contract('Ownable', accounts => {
|
|||
const other = accounts[2]
|
||||
const owner = await ownable.owner.call()
|
||||
assert.isTrue(owner !== other)
|
||||
await assertRevert(ownable.transferOwnership(other, { from: other }))
|
||||
await shouldFail.reverting.withMessage(
|
||||
ownable.transferOwnership(other, { from: other }),
|
||||
"Only owner accessible"
|
||||
);
|
||||
})
|
||||
})
|
||||
|
|
5
truffle-security.json
Normal file
5
truffle-security.json
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"style": "table",
|
||||
"mode": "full",
|
||||
"min-severity": "error"
|
||||
}
|
27
truffle.js
27
truffle.js
|
@ -8,6 +8,13 @@ const rinkebyProvider = new HDWalletProvider(
|
|||
'https://rinkeby.infura.io/'
|
||||
)
|
||||
|
||||
const kovanWallet =
|
||||
'candy maple cake sugar pudding cream honey rich smooth crumble sweet treat'
|
||||
const kovanProvider = new HDWalletProvider(
|
||||
kovanWallet,
|
||||
'https://kovan.infura.io/'
|
||||
)
|
||||
|
||||
const ropstenWallet =
|
||||
'candy maple cake sugar pudding cream honey rich smooth crumble sweet treat'
|
||||
const ropstenProvider = new HDWalletProvider(
|
||||
|
@ -16,6 +23,7 @@ const ropstenProvider = new HDWalletProvider(
|
|||
)
|
||||
|
||||
module.exports = {
|
||||
plugins: ['truffle-security'],
|
||||
migrations_directory: './migrations',
|
||||
networks: {
|
||||
test: {
|
||||
|
@ -32,6 +40,12 @@ module.exports = {
|
|||
gasPrice: 5e9,
|
||||
provider: () => ropstenProvider
|
||||
},
|
||||
kovan: {
|
||||
network_id: 42,
|
||||
gas: 6.5e6,
|
||||
gasPrice: 5e9,
|
||||
provider: () => kovanProvider
|
||||
},
|
||||
rinkeby: {
|
||||
network_id: 4,
|
||||
gas: 6.5e6,
|
||||
|
@ -39,10 +53,15 @@ module.exports = {
|
|||
provider: () => rinkebyProvider
|
||||
}
|
||||
},
|
||||
solc: {
|
||||
optimizer: {
|
||||
enabled: true,
|
||||
runs: 500
|
||||
compilers: {
|
||||
solc: {
|
||||
version: '^0.5.2',
|
||||
settings: {
|
||||
optimizer: {
|
||||
enabled: false,
|
||||
runs: 500
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
mocha: {
|
||||
|
|
Loading…
Reference in New Issue
Block a user