Latest 25 from a total of 16,124 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Process | 11863121 | 1854 days ago | IN | 0 ETH | 0.2611319 | ||||
| Process | 10803602 | 2017 days ago | IN | 0 ETH | 0.51171652 | ||||
| Process | 10794329 | 2018 days ago | IN | 0 ETH | 0.00843269 | ||||
| Process | 10794320 | 2018 days ago | IN | 0 ETH | 0.00843269 | ||||
| Process | 10794320 | 2018 days ago | IN | 0 ETH | 0.00843269 | ||||
| Process | 10790382 | 2019 days ago | IN | 0 ETH | 0.00773304 | ||||
| Process | 10790382 | 2019 days ago | IN | 0 ETH | 0.00776986 | ||||
| Process | 10790382 | 2019 days ago | IN | 0 ETH | 0.33300674 | ||||
| Repay | 10623871 | 2045 days ago | IN | 0 ETH | 0.01223044 | ||||
| Repay | 10623652 | 2045 days ago | IN | 0 ETH | 0.01454634 | ||||
| Process | 10594565 | 2049 days ago | IN | 0 ETH | 0.08395267 | ||||
| Repay | 10593429 | 2049 days ago | IN | 0 ETH | 0.01192693 | ||||
| Repay | 10593429 | 2049 days ago | IN | 0 ETH | 0.01192734 | ||||
| Repay | 10591972 | 2049 days ago | IN | 0 ETH | 0.01354854 | ||||
| Repay | 10591972 | 2049 days ago | IN | 0 ETH | 0.01442487 | ||||
| Create Order | 10575979 | 2052 days ago | IN | 0 ETH | 0.02604411 | ||||
| Create Order | 10543218 | 2057 days ago | IN | 0 ETH | 0.00517176 | ||||
| Create Order | 10543217 | 2057 days ago | IN | 0 ETH | 0.00517176 | ||||
| Create Order | 10543217 | 2057 days ago | IN | 0 ETH | 0.00516792 | ||||
| Create Order | 10543199 | 2057 days ago | IN | 0 ETH | 0.00516888 | ||||
| Create Order | 10543172 | 2057 days ago | IN | 0 ETH | 0.03972776 | ||||
| Repay | 10537458 | 2058 days ago | IN | 0 ETH | 0.01005057 | ||||
| Repay | 10518662 | 2061 days ago | IN | 0 ETH | 0.01091097 | ||||
| Create Order | 10516585 | 2061 days ago | IN | 0 ETH | 0.0430964 | ||||
| Create Order | 10510782 | 2062 days ago | IN | 0 ETH | 0.02791899 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
Kernel
Compiler Version
v0.4.24+commit.e67f0147
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2019-04-17
*/
pragma solidity 0.4.24;
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);
}
// custom : not in original DSMath, putting it here for consistency, copied from SafeMath
function div(uint x, uint y) internal pure returns (uint z) {
z = x / y;
}
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);
}
}
}
}
interface ERC20 {
function name() external view returns(string);
function symbol() external view returns(string);
function decimals() external view returns(uint8);
function totalSupply() external view returns (uint);
function balanceOf(address tokenOwner) external view returns (uint balance);
function allowance(address tokenOwner, address spender) external view returns (uint remaining);
function transfer(address to, uint tokens) external returns (bool success);
function approve(address spender, uint tokens) external returns (bool success);
function transferFrom(address from, address to, uint tokens) external returns (bool success);
event Transfer(address indexed from, address indexed to, uint tokens);
event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
}
contract Utils {
modifier addressValid(address _address) {
require(_address != address(0), "Utils::_ INVALID_ADDRESS");
_;
}
}
contract ErrorUtils {
event LogError(string methodSig, string errMsg);
event LogErrorWithHintBytes32(bytes32 indexed bytes32Value, string methodSig, string errMsg);
event LogErrorWithHintAddress(address indexed addressValue, string methodSig, string errMsg);
}
contract DSAuthority {
function canCall(address src, address dst, bytes4 sig) public view returns (bool);
}
contract DSAuthEvents {
event LogSetAuthority (address indexed authority);
event LogSetOwner (address indexed owner);
}
contract DSAuth is DSAuthEvents {
DSAuthority public authority;
address public owner;
constructor() public {
owner = msg.sender;
emit LogSetOwner(msg.sender);
}
function setOwner(address owner_)
public
auth
{
owner = owner_;
emit LogSetOwner(owner);
}
function setAuthority(DSAuthority authority_)
public
auth
{
authority = authority_;
emit LogSetAuthority(authority);
}
modifier auth {
require(isAuthorized(msg.sender, msg.sig), "DSAuth::_ SENDER_NOT_AUTHORIZED");
_;
}
function isAuthorized(address src, bytes4 sig) internal view returns (bool) {
if (src == address(this)) {
return true;
} else if (src == owner) {
return true;
} else if (authority == DSAuthority(0)) {
return false;
} else {
return authority.canCall(src, this, sig);
}
}
}
contract DSNote {
event LogNote(
bytes4 indexed sig,
address indexed guy,
bytes32 indexed foo,
bytes32 indexed bar,
uint wad,
bytes fax
) anonymous;
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);
_;
}
}
contract SelfAuthorized {
modifier authorized() {
require(msg.sender == address(this), "Method can only be called from this contract");
_;
}
}
contract DateTime {
/*
* Date and Time utilities for ethereum contracts
*
*/
struct _DateTime {
uint16 year;
uint8 month;
uint8 day;
uint8 hour;
uint8 minute;
uint8 second;
uint8 weekday;
}
uint constant DAY_IN_SECONDS = 86400;
uint constant YEAR_IN_SECONDS = 31536000;
uint constant LEAP_YEAR_IN_SECONDS = 31622400;
uint constant HOUR_IN_SECONDS = 3600;
uint constant MINUTE_IN_SECONDS = 60;
uint16 constant ORIGIN_YEAR = 1970;
function isLeapYear(uint16 year) public pure returns (bool) {
if (year % 4 != 0) {
return false;
}
if (year % 100 != 0) {
return true;
}
if (year % 400 != 0) {
return false;
}
return true;
}
function leapYearsBefore(uint year) public pure returns (uint) {
year -= 1;
return year / 4 - year / 100 + year / 400;
}
function getDaysInMonth(uint8 month, uint16 year) public pure returns (uint8) {
if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
return 31;
}
else if (month == 4 || month == 6 || month == 9 || month == 11) {
return 30;
}
else if (isLeapYear(year)) {
return 29;
}
else {
return 28;
}
}
function parseTimestamp(uint timestamp) internal pure returns (_DateTime dt) {
uint secondsAccountedFor = 0;
uint buf;
uint8 i;
// Year
dt.year = getYear(timestamp);
buf = leapYearsBefore(dt.year) - leapYearsBefore(ORIGIN_YEAR);
secondsAccountedFor += LEAP_YEAR_IN_SECONDS * buf;
secondsAccountedFor += YEAR_IN_SECONDS * (dt.year - ORIGIN_YEAR - buf);
// Month
uint secondsInMonth;
for (i = 1; i <= 12; i++) {
secondsInMonth = DAY_IN_SECONDS * getDaysInMonth(i, dt.year);
if (secondsInMonth + secondsAccountedFor > timestamp) {
dt.month = i;
break;
}
secondsAccountedFor += secondsInMonth;
}
// Day
for (i = 1; i <= getDaysInMonth(dt.month, dt.year); i++) {
if (DAY_IN_SECONDS + secondsAccountedFor > timestamp) {
dt.day = i;
break;
}
secondsAccountedFor += DAY_IN_SECONDS;
}
// Hour
dt.hour = getHour(timestamp);
// Minute
dt.minute = getMinute(timestamp);
// Second
dt.second = getSecond(timestamp);
// Day of week.
dt.weekday = getWeekday(timestamp);
}
function getYear(uint timestamp) public pure returns (uint16) {
uint secondsAccountedFor = 0;
uint16 year;
uint numLeapYears;
// Year
year = uint16(ORIGIN_YEAR + timestamp / YEAR_IN_SECONDS);
numLeapYears = leapYearsBefore(year) - leapYearsBefore(ORIGIN_YEAR);
secondsAccountedFor += LEAP_YEAR_IN_SECONDS * numLeapYears;
secondsAccountedFor += YEAR_IN_SECONDS * (year - ORIGIN_YEAR - numLeapYears);
while (secondsAccountedFor > timestamp) {
if (isLeapYear(uint16(year - 1))) {
secondsAccountedFor -= LEAP_YEAR_IN_SECONDS;
}
else {
secondsAccountedFor -= YEAR_IN_SECONDS;
}
year -= 1;
}
return year;
}
function getMonth(uint timestamp) public pure returns (uint8) {
return parseTimestamp(timestamp).month;
}
function getDay(uint timestamp) public pure returns (uint8) {
return parseTimestamp(timestamp).day;
}
function getHour(uint timestamp) public pure returns (uint8) {
return uint8((timestamp / 60 / 60) % 24);
}
function getMinute(uint timestamp) public pure returns (uint8) {
return uint8((timestamp / 60) % 60);
}
function getSecond(uint timestamp) public pure returns (uint8) {
return uint8(timestamp % 60);
}
function getWeekday(uint timestamp) public pure returns (uint8) {
return uint8((timestamp / DAY_IN_SECONDS + 4) % 7);
}
function toTimestamp(uint16 year, uint8 month, uint8 day) public pure returns (uint timestamp) {
return toTimestamp(year, month, day, 0, 0, 0);
}
function toTimestamp(uint16 year, uint8 month, uint8 day, uint8 hour) public pure returns (uint timestamp) {
return toTimestamp(year, month, day, hour, 0, 0);
}
function toTimestamp(uint16 year, uint8 month, uint8 day, uint8 hour, uint8 minute) public pure returns (uint timestamp) {
return toTimestamp(year, month, day, hour, minute, 0);
}
function toTimestamp(uint16 year, uint8 month, uint8 day, uint8 hour, uint8 minute, uint8 second) public pure returns (uint timestamp) {
uint16 i;
// Year
for (i = ORIGIN_YEAR; i < year; i++) {
if (isLeapYear(i)) {
timestamp += LEAP_YEAR_IN_SECONDS;
}
else {
timestamp += YEAR_IN_SECONDS;
}
}
// Month
uint8[12] memory monthDayCounts;
monthDayCounts[0] = 31;
if (isLeapYear(year)) {
monthDayCounts[1] = 29;
}
else {
monthDayCounts[1] = 28;
}
monthDayCounts[2] = 31;
monthDayCounts[3] = 30;
monthDayCounts[4] = 31;
monthDayCounts[5] = 30;
monthDayCounts[6] = 31;
monthDayCounts[7] = 31;
monthDayCounts[8] = 30;
monthDayCounts[9] = 31;
monthDayCounts[10] = 30;
monthDayCounts[11] = 31;
for (i = 1; i < month; i++) {
timestamp += DAY_IN_SECONDS * monthDayCounts[i - 1];
}
// Day
timestamp += DAY_IN_SECONDS * (day - 1);
// Hour
timestamp += HOUR_IN_SECONDS * (hour);
// Minute
timestamp += MINUTE_IN_SECONDS * (minute);
// Second
timestamp += second;
return timestamp;
}
}
contract WETH9 {
string public name = "Wrapped Ether";
string public symbol = "WETH";
uint8 public decimals = 18;
event Approval(address indexed _owner, address indexed _spender, uint _value);
event Transfer(address indexed _from, address indexed _to, uint _value);
event Deposit(address indexed _owner, uint _value);
event Withdrawal(address indexed _owner, uint _value);
mapping (address => uint) public balanceOf;
mapping (address => mapping (address => uint)) public allowance;
function() public payable {
deposit();
}
function deposit() public payable {
balanceOf[msg.sender] += msg.value;
Deposit(msg.sender, msg.value);
}
function withdraw(uint wad) public {
require(balanceOf[msg.sender] >= wad);
balanceOf[msg.sender] -= wad;
msg.sender.transfer(wad);
Withdrawal(msg.sender, wad);
}
function totalSupply() public view returns (uint) {
return this.balance;
}
function approve(address guy, uint wad) public returns (bool) {
allowance[msg.sender][guy] = wad;
Approval(msg.sender, guy, wad);
return true;
}
function transfer(address dst, uint wad) public returns (bool) {
return transferFrom(msg.sender, dst, wad);
}
function transferFrom(address src, address dst, uint wad)
public
returns (bool)
{
require(balanceOf[src] >= wad);
if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) {
require(allowance[src][msg.sender] >= wad);
allowance[src][msg.sender] -= wad;
}
balanceOf[src] -= wad;
balanceOf[dst] += wad;
Transfer(src, dst, wad);
return true;
}
}
contract Proxy {
// masterCopy always needs to be first declared variable, to ensure that it is at the same location in the contracts to which calls are delegated.
address masterCopy;
/// @dev Constructor function sets address of master copy contract.
/// @param _masterCopy Master copy address.
constructor(address _masterCopy)
public
{
require(_masterCopy != 0, "Invalid master copy address provided");
masterCopy = _masterCopy;
}
/// @dev Fallback function forwards all transactions and returns all received return data.
function ()
external
payable
{
// solium-disable-next-line security/no-inline-assembly
assembly {
let masterCopy := and(sload(0), 0xffffffffffffffffffffffffffffffffffffffff)
calldatacopy(0, 0, calldatasize())
let success := delegatecall(gas, masterCopy, 0, calldatasize(), 0, 0)
returndatacopy(0, 0, returndatasize())
if eq(success, 0) { revert(0, returndatasize()) }
return(0, returndatasize())
}
}
function implementation()
public
view
returns (address)
{
return masterCopy;
}
function proxyType()
public
pure
returns (uint256)
{
return 2;
}
}
contract DSStop is DSNote, DSAuth {
bool public stopped = false;
modifier whenNotStopped {
require(!stopped, "DSStop::_ FEATURE_STOPPED");
_;
}
modifier whenStopped {
require(stopped, "DSStop::_ FEATURE_NOT_STOPPED");
_;
}
function stop() public auth note {
stopped = true;
}
function start() public auth note {
stopped = false;
}
}
interface KyberNetworkProxy {
function maxGasPrice() external view returns(uint);
function getUserCapInWei(address user) external view returns(uint);
function getUserCapInTokenWei(address user, ERC20 token) external view returns(uint);
function enabled() external view returns(bool);
function info(bytes32 id) external view returns(uint);
function swapTokenToToken(ERC20 src, uint srcAmount, ERC20 dest, uint minConversionRate) external returns(uint);
function swapEtherToToken(ERC20 token, uint minConversionRate) external payable returns(uint);
function swapTokenToEther(ERC20 token, uint srcAmount, uint minConversionRate) external returns(uint);
function getExpectedRate
(
ERC20 src,
ERC20 dest,
uint srcQty
)
external
view
returns
(
uint expectedRate,
uint slippageRate
);
function tradeWithHint
(
ERC20 src,
uint srcAmount,
ERC20 dest,
address destAddress,
uint maxDestAmount,
uint minConversionRate,
address walletId,
bytes hint
)
external
payable
returns(uint);
}
library ECRecovery {
function recover(bytes32 _hash, bytes _sig)
internal
pure
returns (address)
{
bytes32 r;
bytes32 s;
uint8 v;
if (_sig.length != 65) {
return (address(0));
}
assembly {
r := mload(add(_sig, 32))
s := mload(add(_sig, 64))
v := byte(0, mload(add(_sig, 96)))
}
if (v < 27) {
v += 27;
}
if (v != 27 && v != 28) {
return (address(0));
} else {
return ecrecover(_hash, v, r, s);
}
}
function toEthSignedMessageHash(bytes32 _hash)
internal
pure
returns (bytes32)
{
return keccak256(
abi.encodePacked("\x19Ethereum Signed Message:\n32", _hash)
);
}
}
contract Utils2 {
using ECRecovery for bytes32;
function _recoverSigner(bytes32 _hash, bytes _signature)
internal
pure
returns(address _signer)
{
return _hash.toEthSignedMessageHash().recover(_signature);
}
}
contract DSThing is DSNote, DSAuth, DSMath {
function S(string s) internal pure returns (bytes4) {
return bytes4(keccak256(s));
}
}
contract MasterCopy is SelfAuthorized {
// masterCopy always needs to be first declared variable, to ensure that it is at the same location as in the Proxy contract.
// It should also always be ensured that the address is stored alone (uses a full word)
address masterCopy;
/// @dev Allows to upgrade the contract. This can only be done via a Safe transaction.
/// @param _masterCopy New contract address.
function changeMasterCopy(address _masterCopy)
public
authorized
{
// Master copy address cannot be null.
require(_masterCopy != 0, "Invalid master copy address provided");
masterCopy = _masterCopy;
}
}
contract Config is DSNote, DSAuth, Utils {
WETH9 public weth9;
mapping (address => bool) public isAccountHandler;
mapping (address => bool) public isAdmin;
address[] public admins;
bool public disableAdminControl = false;
event LogAdminAdded(address indexed _admin, address _by);
event LogAdminRemoved(address indexed _admin, address _by);
constructor() public {
admins.push(msg.sender);
isAdmin[msg.sender] = true;
}
modifier onlyAdmin(){
require(isAdmin[msg.sender], "Config::_ SENDER_NOT_AUTHORIZED");
_;
}
function setWETH9
(
address _weth9
)
public
auth
note
addressValid(_weth9)
{
weth9 = WETH9(_weth9);
}
function setAccountHandler
(
address _accountHandler,
bool _isAccountHandler
)
public
auth
note
addressValid(_accountHandler)
{
isAccountHandler[_accountHandler] = _isAccountHandler;
}
function toggleAdminsControl()
public
auth
note
{
disableAdminControl = !disableAdminControl;
}
function isAdminValid(address _admin)
public
view
returns (bool)
{
if(disableAdminControl) {
return true;
} else {
return isAdmin[_admin];
}
}
function getAllAdmins()
public
view
returns(address[])
{
return admins;
}
function addAdmin
(
address _admin
)
external
note
onlyAdmin
addressValid(_admin)
{
require(!isAdmin[_admin], "Config::addAdmin ADMIN_ALREADY_EXISTS");
admins.push(_admin);
isAdmin[_admin] = true;
emit LogAdminAdded(_admin, msg.sender);
}
function removeAdmin
(
address _admin
)
external
note
onlyAdmin
addressValid(_admin)
{
require(isAdmin[_admin], "Config::removeAdmin ADMIN_DOES_NOT_EXIST");
require(msg.sender != _admin, "Config::removeAdmin ADMIN_NOT_AUTHORIZED");
isAdmin[_admin] = false;
for (uint i = 0; i < admins.length - 1; i++) {
if (admins[i] == _admin) {
admins[i] = admins[admins.length - 1];
admins.length -= 1;
break;
}
}
emit LogAdminRemoved(_admin, msg.sender);
}
}
contract Account is MasterCopy, DSNote, Utils, Utils2, ErrorUtils {
address[] public users;
mapping (address => bool) public isUser;
mapping (bytes32 => bool) public actionCompleted;
WETH9 public weth9;
Config public config;
bool public isInitialized = false;
event LogTransferBySystem(address indexed token, address indexed to, uint value, address by);
event LogTransferByUser(address indexed token, address indexed to, uint value, address by);
event LogUserAdded(address indexed user, address by);
event LogUserRemoved(address indexed user, address by);
event LogImplChanged(address indexed newImpl, address indexed oldImpl);
modifier initialized() {
require(isInitialized, "Account::_ ACCOUNT_NOT_INITIALIZED");
_;
}
modifier notInitialized() {
require(!isInitialized, "Account::_ ACCOUNT_ALREADY_INITIALIZED");
_;
}
modifier userExists(address _user) {
require(isUser[_user], "Account::_ INVALID_USER");
_;
}
modifier userDoesNotExist(address _user) {
require(!isUser[_user], "Account::_ USER_DOES_NOT_EXISTS");
_;
}
modifier onlyAdmin() {
require(config.isAdminValid(msg.sender), "Account::_ INVALID_ADMIN_ACCOUNT");
_;
}
modifier onlyHandler(){
require(config.isAccountHandler(msg.sender), "Account::_ INVALID_ACC_HANDLER");
_;
}
function init(address _user, address _config)
public
notInitialized
{
users.push(_user);
isUser[_user] = true;
config = Config(_config);
weth9 = config.weth9();
isInitialized = true;
}
function getAllUsers() public view returns (address[]) {
return users;
}
function balanceFor(address _token) public view returns (uint _balance){
_balance = ERC20(_token).balanceOf(this);
}
function transferBySystem
(
address _token,
address _to,
uint _value
)
external
onlyHandler
note
initialized
{
require(ERC20(_token).balanceOf(this) >= _value, "Account::transferBySystem INSUFFICIENT_BALANCE_IN_ACCOUNT");
ERC20(_token).transfer(_to, _value);
emit LogTransferBySystem(_token, _to, _value, msg.sender);
}
function transferByUser
(
address _token,
address _to,
uint _value,
uint _salt,
bytes _signature
)
external
addressValid(_to)
note
initialized
onlyAdmin
{
bytes32 actionHash = _getTransferActionHash(_token, _to, _value, _salt);
if(actionCompleted[actionHash]) {
emit LogError("Account::transferByUser", "ACTION_ALREADY_PERFORMED");
return;
}
if(ERC20(_token).balanceOf(this) < _value){
emit LogError("Account::transferByUser", "INSUFFICIENT_BALANCE_IN_ACCOUNT");
return;
}
address signer = _recoverSigner(actionHash, _signature);
if(!isUser[signer]) {
emit LogError("Account::transferByUser", "SIGNER_NOT_AUTHORIZED_WITH_ACCOUNT");
return;
}
actionCompleted[actionHash] = true;
if (_token == address(weth9)) {
weth9.withdraw(_value);
_to.transfer(_value);
} else {
require(ERC20(_token).transfer(_to, _value), "Account::transferByUser TOKEN_TRANSFER_FAILED");
}
emit LogTransferByUser(_token, _to, _value, signer);
}
function addUser
(
address _user,
uint _salt,
bytes _signature
)
external
note
addressValid(_user)
userDoesNotExist(_user)
initialized
onlyAdmin
{
bytes32 actionHash = _getUserActionHash(_user, "ADD_USER", _salt);
if(actionCompleted[actionHash])
{
emit LogError("Account::addUser", "ACTION_ALREADY_PERFORMED");
return;
}
address signer = _recoverSigner(actionHash, _signature);
if(!isUser[signer]) {
emit LogError("Account::addUser", "SIGNER_NOT_AUTHORIZED_WITH_ACCOUNT");
return;
}
actionCompleted[actionHash] = true;
users.push(_user);
isUser[_user] = true;
emit LogUserAdded(_user, signer);
}
function removeUser
(
address _user,
uint _salt,
bytes _signature
)
external
note
userExists(_user)
initialized
onlyAdmin
{
bytes32 actionHash = _getUserActionHash(_user, "REMOVE_USER", _salt);
if(actionCompleted[actionHash]) {
emit LogError("Account::removeUser", "ACTION_ALREADY_PERFORMED");
return;
}
address signer = _recoverSigner(actionHash, _signature);
if(users.length == 1){
emit LogError("Account::removeUser", "ACC_SHOULD_HAVE_ATLEAST_ONE_USER");
return;
}
if(!isUser[signer]){
emit LogError("Account::removeUser", "SIGNER_NOT_AUTHORIZED_WITH_ACCOUNT");
return;
}
actionCompleted[actionHash] = true;
// should delete value from isUser map? delete isUser[_user]?
isUser[_user] = false;
for (uint i = 0; i < users.length - 1; i++) {
if (users[i] == _user) {
users[i] = users[users.length - 1];
users.length -= 1;
break;
}
}
emit LogUserRemoved(_user, signer);
}
function _getTransferActionHash
(
address _token,
address _to,
uint _value,
uint _salt
)
internal
view
returns (bytes32)
{
return keccak256(
abi.encodePacked(
address(this),
_token,
_to,
_value,
_salt
)
);
}
function _getUserActionHash
(
address _user,
string _action,
uint _salt
)
internal
view
returns (bytes32)
{
return keccak256(
abi.encodePacked(
address(this),
_user,
_action,
_salt
)
);
}
// to directly send ether to contract
function() external payable {
require(msg.data.length == 0 && msg.value > 0, "Account::fallback INVALID_ETHER_TRANSFER");
if(msg.sender != address(weth9)){
weth9.deposit.value(msg.value)();
}
}
function changeImpl
(
address _to,
uint _salt,
bytes _signature
)
external
note
addressValid(_to)
initialized
onlyAdmin
{
bytes32 actionHash = _getUserActionHash(_to, "CHANGE_ACCOUNT_IMPLEMENTATION", _salt);
if(actionCompleted[actionHash])
{
emit LogError("Account::changeImpl", "ACTION_ALREADY_PERFORMED");
return;
}
address signer = _recoverSigner(actionHash, _signature);
if(!isUser[signer]) {
emit LogError("Account::changeImpl", "SIGNER_NOT_AUTHORIZED_WITH_ACCOUNT");
return;
}
actionCompleted[actionHash] = true;
address oldImpl = masterCopy;
this.changeMasterCopy(_to);
emit LogImplChanged(_to, oldImpl);
}
}
contract AccountFactory is DSStop, Utils {
Config public config;
mapping (address => bool) public isAccount;
mapping (address => address[]) public userToAccounts;
address[] public accounts;
address public accountMaster;
constructor
(
Config _config,
address _accountMaster
)
public
{
config = _config;
accountMaster = _accountMaster;
}
event LogAccountCreated(address indexed user, address indexed account, address by);
modifier onlyAdmin() {
require(config.isAdminValid(msg.sender), "AccountFactory::_ INVALID_ADMIN_ACCOUNT");
_;
}
function setConfig(Config _config) external note auth addressValid(_config) {
config = _config;
}
function setAccountMaster(address _accountMaster) external note auth addressValid(_accountMaster) {
accountMaster = _accountMaster;
}
function newAccount(address _user)
public
note
onlyAdmin
addressValid(config)
addressValid(accountMaster)
whenNotStopped
returns
(
Account _account
)
{
address proxy = new Proxy(accountMaster);
_account = Account(proxy);
_account.init(_user, config);
accounts.push(_account);
userToAccounts[_user].push(_account);
isAccount[_account] = true;
emit LogAccountCreated(_user, _account, msg.sender);
}
function batchNewAccount(address[] _users) public note onlyAdmin {
for (uint i = 0; i < _users.length; i++) {
newAccount(_users[i]);
}
}
function getAllAccounts() public view returns (address[]) {
return accounts;
}
function getAccountsForUser(address _user) public view returns (address[]) {
return userToAccounts[_user];
}
}
contract Escrow is DSNote, DSAuth {
event LogTransfer(address indexed token, address indexed to, uint value);
event LogTransferFromAccount(address indexed account, address indexed token, address indexed to, uint value);
function transfer
(
address _token,
address _to,
uint _value
)
public
note
auth
{
require(ERC20(_token).transfer(_to, _value), "Escrow::transfer TOKEN_TRANSFER_FAILED");
emit LogTransfer(_token, _to, _value);
}
function transferFromAccount
(
address _account,
address _token,
address _to,
uint _value
)
public
note
auth
{
Account(_account).transferBySystem(_token, _to, _value);
emit LogTransferFromAccount(_account, _token, _to, _value);
}
}
// issue with deploying multiple instances of same type in truffle, hence the following two contracts
contract KernelEscrow is Escrow {
}
contract ReserveEscrow is Escrow {
}
interface ExchangeConnector {
function tradeWithInputFixed
(
Escrow _escrow,
address _srcToken,
address _destToken,
uint _srcTokenValue
)
external
returns (uint _destTokenValue, uint _srcTokenValueLeft);
function tradeWithOutputFixed
(
Escrow _escrow,
address _srcToken,
address _destToken,
uint _srcTokenValue,
uint _maxDestTokenValue
)
external
returns (uint _destTokenValue, uint _srcTokenValueLeft);
function getExpectedRate(address _srcToken, address _destToken, uint _srcTokenValue)
external
view
returns(uint _expectedRate, uint _slippageRate);
function isTradeFeasible(address _srcToken, address _destToken, uint _srcTokenValue)
external
view
returns(bool);
}
contract Reserve is DSStop, DSThing, Utils, Utils2, ErrorUtils {
Escrow public escrow;
AccountFactory public accountFactory;
DateTime public dateTime;
Config public config;
uint public deployTimestamp;
string constant public VERSION = "1.0.0";
uint public TIME_INTERVAL = 1 days;
//uint public TIME_INTERVAL = 1 hours;
constructor
(
Escrow _escrow,
AccountFactory _accountFactory,
DateTime _dateTime,
Config _config
)
public
{
escrow = _escrow;
accountFactory = _accountFactory;
dateTime = _dateTime;
config = _config;
deployTimestamp = now - (4 * TIME_INTERVAL);
}
function setEscrow(Escrow _escrow)
public
note
auth
addressValid(_escrow)
{
escrow = _escrow;
}
function setAccountFactory(AccountFactory _accountFactory)
public
note
auth
addressValid(_accountFactory)
{
accountFactory = _accountFactory;
}
function setDateTime(DateTime _dateTime)
public
note
auth
addressValid(_dateTime)
{
dateTime = _dateTime;
}
function setConfig(Config _config)
public
note
auth
addressValid(_config)
{
config = _config;
}
struct Order {
address account;
address token;
address byUser;
uint value;
uint duration;
uint expirationTimestamp;
uint salt;
uint createdTimestamp;
bytes32 orderHash;
}
bytes32[] public orders;
mapping (bytes32 => Order) public hashToOrder;
mapping (bytes32 => bool) public isOrder;
mapping (address => bytes32[]) public accountToOrders;
mapping (bytes32 => bool) public cancelledOrders;
// per day
mapping (uint => mapping(address => uint)) public deposits;
mapping (uint => mapping(address => uint)) public withdrawals;
mapping (uint => mapping(address => uint)) public profits;
mapping (uint => mapping(address => uint)) public losses;
mapping (uint => mapping(address => uint)) public reserves;
mapping (address => uint) public lastReserveRuns;
mapping (address => mapping(address => uint)) public surplus;
mapping (bytes32 => CumulativeRun) public orderToCumulative;
struct CumulativeRun {
uint timestamp;
uint value;
}
modifier onlyAdmin() {
require(config.isAdminValid(msg.sender), "Reserve::_ INVALID_ADMIN_ACCOUNT");
_;
}
event LogOrderCreated(
bytes32 indexed orderHash,
address indexed account,
address indexed token,
address byUser,
uint value,
uint expirationTimestamp
);
event LogOrderCancelled(
bytes32 indexed orderHash,
address indexed by
);
event LogReserveValuesUpdated(
address indexed token,
uint indexed updatedTill,
uint reserve,
uint profit,
uint loss
);
event LogOrderCumulativeUpdated(
bytes32 indexed orderHash,
uint updatedTill,
uint value
);
event LogRelease(
address indexed token,
address indexed to,
uint value,
address by
);
event LogLock(
address indexed token,
address indexed from,
uint value,
uint profit,
uint loss,
address by
);
event LogLockSurplus(
address indexed forToken,
address indexed token,
address from,
uint value
);
event LogTransferSurplus(
address indexed forToken,
address indexed token,
address to,
uint value
);
function createOrder
(
address[3] _orderAddresses,
uint[3] _orderValues,
bytes _signature
)
public
note
onlyAdmin
whenNotStopped
{
Order memory order = _composeOrder(_orderAddresses, _orderValues);
address signer = _recoverSigner(order.orderHash, _signature);
if(signer != order.byUser){
emit LogErrorWithHintBytes32(order.orderHash, "Reserve::createOrder", "SIGNER_NOT_ORDER_CREATOR");
return;
}
if(isOrder[order.orderHash]){
emit LogErrorWithHintBytes32(order.orderHash, "Reserve::createOrder", "ORDER_ALREADY_EXISTS");
return;
}
if(!accountFactory.isAccount(order.account)){
emit LogErrorWithHintBytes32(order.orderHash, "Reserve::createOrder", "INVALID_ORDER_ACCOUNT");
return;
}
if(!Account(order.account).isUser(signer)){
emit LogErrorWithHintBytes32(order.orderHash, "Reserve::createOrder", "SIGNER_NOT_AUTHORIZED_WITH_ACCOUNT");
return;
}
if(!_isOrderValid(order)) {
emit LogErrorWithHintBytes32(order.orderHash, "Reserve::createOrder", "INVALID_ORDER_PARAMETERS");
return;
}
if(ERC20(order.token).balanceOf(order.account) < order.value){
emit LogErrorWithHintBytes32(order.orderHash, "Reserve::createOrder", "INSUFFICIENT_BALANCE_IN_ACCOUNT");
return;
}
escrow.transferFromAccount(order.account, order.token, address(escrow), order.value);
orders.push(order.orderHash);
hashToOrder[order.orderHash] = order;
isOrder[order.orderHash] = true;
accountToOrders[order.account].push(order.orderHash);
uint dateTimestamp = _getDateTimestamp(now);
deposits[dateTimestamp][order.token] = add(deposits[dateTimestamp][order.token], order.value);
orderToCumulative[order.orderHash].timestamp = _getDateTimestamp(order.createdTimestamp);
orderToCumulative[order.orderHash].value = order.value;
emit LogOrderCreated(
order.orderHash,
order.account,
order.token,
order.byUser,
order.value,
order.expirationTimestamp
);
}
function cancelOrder
(
bytes32 _orderHash,
bytes _signature
)
external
note
onlyAdmin
{
if(!isOrder[_orderHash]) {
emit LogErrorWithHintBytes32(_orderHash,"Reserve::createOrder", "ORDER_DOES_NOT_EXIST");
return;
}
if(cancelledOrders[_orderHash]){
emit LogErrorWithHintBytes32(_orderHash,"Reserve::createOrder", "ORDER_ALREADY_CANCELLED");
return;
}
Order memory order = hashToOrder[_orderHash];
bytes32 cancelOrderHash = _generateActionOrderHash(_orderHash, "CANCEL_RESERVE_ORDER");
address signer = _recoverSigner(cancelOrderHash, _signature);
if(!Account(order.account).isUser(signer)){
emit LogErrorWithHintBytes32(_orderHash,"Reserve::createOrder", "SIGNER_NOT_AUTHORIZED_WITH_ACCOUNT");
return;
}
doCancelOrder(order);
}
function processOrder
(
bytes32 _orderHash
)
external
note
onlyAdmin
{
if(!isOrder[_orderHash]) {
emit LogErrorWithHintBytes32(_orderHash,"Reserve::processOrder", "ORDER_DOES_NOT_EXIST");
return;
}
if(cancelledOrders[_orderHash]){
emit LogErrorWithHintBytes32(_orderHash,"Reserve::processOrder", "ORDER_ALREADY_CANCELLED");
return;
}
Order memory order = hashToOrder[_orderHash];
if(now > _getDateTimestamp(order.expirationTimestamp)) {
doCancelOrder(order);
} else {
emit LogErrorWithHintBytes32(order.orderHash, "Reserve::processOrder", "ORDER_NOT_EXPIRED");
}
}
function doCancelOrder(Order _order)
internal
{
uint valueToTransfer = orderToCumulative[_order.orderHash].value;
if(ERC20(_order.token).balanceOf(escrow) < valueToTransfer){
emit LogErrorWithHintBytes32(_order.orderHash, "Reserve::doCancel", "INSUFFICIENT_BALANCE_IN_ESCROW");
return;
}
uint nowDateTimestamp = _getDateTimestamp(now);
cancelledOrders[_order.orderHash] = true;
withdrawals[nowDateTimestamp][_order.token] = add(withdrawals[nowDateTimestamp][_order.token], valueToTransfer);
escrow.transfer(_order.token, _order.account, valueToTransfer);
emit LogOrderCancelled(_order.orderHash, msg.sender);
}
function release(address _token, address _to, uint _value)
external
note
auth
{
require(ERC20(_token).balanceOf(escrow) >= _value, "Reserve::release INSUFFICIENT_BALANCE_IN_ESCROW");
escrow.transfer(_token, _to, _value);
emit LogRelease(_token, _to, _value, msg.sender);
}
// _value includes profit/loss as well
function lock(address _token, address _from, uint _value, uint _profit, uint _loss)
external
note
auth
{
require(!(_profit == 0 && _loss == 0), "Reserve::lock INVALID_PROFIT_LOSS_VALUES");
require(ERC20(_token).balanceOf(_from) >= _value, "Reserve::lock INSUFFICIENT_BALANCE");
if(accountFactory.isAccount(_from)) {
escrow.transferFromAccount(_from, _token, address(escrow), _value);
} else {
Escrow(_from).transfer(_token, address(escrow), _value);
}
uint dateTimestamp = _getDateTimestamp(now);
if (_profit > 0){
profits[dateTimestamp][_token] = add(profits[dateTimestamp][_token], _profit);
} else if (_loss > 0) {
losses[dateTimestamp][_token] = add(losses[dateTimestamp][_token], _loss);
}
emit LogLock(_token, _from, _value, _profit, _loss, msg.sender);
}
// to lock collateral if cannot be liquidated e.g. not enough reserves in kyber
function lockSurplus(address _from, address _forToken, address _token, uint _value)
external
note
auth
{
require(ERC20(_token).balanceOf(_from) >= _value, "Reserve::lockSurplus INSUFFICIENT_BALANCE_IN_ESCROW");
Escrow(_from).transfer(_token, address(escrow), _value);
surplus[_forToken][_token] = add(surplus[_forToken][_token], _value);
emit LogLockSurplus(_forToken, _token, _from, _value);
}
// to transfer surplus collateral out of the system to trade on other platforms and put back in terms of
// principal to reserve manually using an account or surplus escrow
// should work in tandem with lock method when transferring back principal
function transferSurplus(address _to, address _forToken, address _token, uint _value)
external
note
auth
{
require(ERC20(_token).balanceOf(escrow) >= _value, "Reserve::transferSurplus INSUFFICIENT_BALANCE_IN_ESCROW");
require(surplus[_forToken][_token] >= _value, "Reserve::transferSurplus INSUFFICIENT_SURPLUS");
surplus[_forToken][_token] = sub(surplus[_forToken][_token], _value);
escrow.transfer(_token, _to, _value);
emit LogTransferSurplus(_forToken, _token, _to, _value);
}
function updateReserveValues(address _token, uint _forDays)
public
note
onlyAdmin
{
uint lastReserveRun = lastReserveRuns[_token];
if (lastReserveRun == 0) {
lastReserveRun = _getDateTimestamp(deployTimestamp) - TIME_INTERVAL;
}
uint nowDateTimestamp = _getDateTimestamp(now);
uint updatesLeft = ((nowDateTimestamp - TIME_INTERVAL) - lastReserveRun) / TIME_INTERVAL;
if(updatesLeft == 0) {
emit LogErrorWithHintAddress(_token, "Reserve::updateReserveValues", "RESERVE_VALUES_UP_TO_DATE");
return;
}
uint counter = updatesLeft;
if(updatesLeft > _forDays && _forDays > 0) {
counter = _forDays;
}
for (uint i = 0; i < counter; i++) {
reserves[lastReserveRun + TIME_INTERVAL][_token] = sub(
sub(
add(
add(
reserves[lastReserveRun][_token],
deposits[lastReserveRun + TIME_INTERVAL][_token]
),
profits[lastReserveRun + TIME_INTERVAL][_token]
),
losses[lastReserveRun + TIME_INTERVAL][_token]
),
withdrawals[lastReserveRun + TIME_INTERVAL][_token]
);
lastReserveRuns[_token] = lastReserveRun + TIME_INTERVAL;
lastReserveRun = lastReserveRuns[_token];
emit LogReserveValuesUpdated(
_token,
lastReserveRun,
reserves[lastReserveRun][_token],
profits[lastReserveRun][_token],
losses[lastReserveRun][_token]
);
}
}
function updateOrderCumulativeValueBatch(bytes32[] _orderHashes, uint[] _forDays)
public
note
onlyAdmin
{
if(_orderHashes.length != _forDays.length) {
emit LogError("Reserve::updateOrderCumulativeValueBatch", "ARGS_ARRAYLENGTH_MISMATCH");
return;
}
for(uint i = 0; i < _orderHashes.length; i++) {
updateOrderCumulativeValue(_orderHashes[i], _forDays[i]);
}
}
function updateOrderCumulativeValue
(
bytes32 _orderHash,
uint _forDays
)
public
note
onlyAdmin
{
if(!isOrder[_orderHash]) {
emit LogErrorWithHintBytes32(_orderHash, "Reserve::updateOrderCumulativeValue", "ORDER_DOES_NOT_EXIST");
return;
}
if(cancelledOrders[_orderHash]) {
emit LogErrorWithHintBytes32(_orderHash, "Reserve::updateOrderCumulativeValue", "ORDER_ALREADY_CANCELLED");
return;
}
Order memory order = hashToOrder[_orderHash];
CumulativeRun storage cumulativeRun = orderToCumulative[_orderHash];
uint profitsAccrued = 0;
uint lossesAccrued = 0;
uint cumulativeValue = 0;
uint counter = 0;
uint lastOrderRun = cumulativeRun.timestamp;
uint nowDateTimestamp = _getDateTimestamp(now);
uint updatesLeft = ((nowDateTimestamp - TIME_INTERVAL) - lastOrderRun) / TIME_INTERVAL;
if(updatesLeft == 0) {
emit LogErrorWithHintBytes32(_orderHash, "Reserve::updateOrderCumulativeValue", "ORDER_VALUES_UP_TO_DATE");
return;
}
counter = updatesLeft;
if(updatesLeft > _forDays && _forDays > 0) {
counter = _forDays;
}
for (uint i = 0; i < counter; i++){
cumulativeValue = cumulativeRun.value;
lastOrderRun = cumulativeRun.timestamp;
if(lastReserveRuns[order.token] < lastOrderRun) {
emit LogErrorWithHintBytes32(_orderHash, "Reserve::updateOrderCumulativeValue", "RESERVE_VALUES_NOT_UPDATED");
emit LogOrderCumulativeUpdated(_orderHash, cumulativeRun.timestamp, cumulativeRun.value);
return;
}
profitsAccrued = div(
mul(profits[lastOrderRun + TIME_INTERVAL][order.token], cumulativeValue),
reserves[lastOrderRun][order.token]
);
lossesAccrued = div(
mul(losses[lastOrderRun + TIME_INTERVAL][order.token], cumulativeValue),
reserves[lastOrderRun][order.token]
);
cumulativeValue = sub(add(cumulativeValue, profitsAccrued), lossesAccrued);
cumulativeRun.timestamp = lastOrderRun + TIME_INTERVAL;
cumulativeRun.value = cumulativeValue;
}
emit LogOrderCumulativeUpdated(_orderHash, cumulativeRun.timestamp, cumulativeRun.value);
}
function getAllOrders()
public
view
returns
(
bytes32[]
)
{
return orders;
}
function getOrdersForAccount(address _account)
public
view
returns
(
bytes32[]
)
{
return accountToOrders[_account];
}
function getOrder(bytes32 _orderHash)
public
view
returns
(
address _account,
address _token,
address _byUser,
uint _value,
uint _expirationTimestamp,
uint _salt,
uint _createdTimestamp
)
{
Order memory order = hashToOrder[_orderHash];
return (
order.account,
order.token,
order.byUser,
order.value,
order.expirationTimestamp,
order.salt,
order.createdTimestamp
);
}
function _isOrderValid(Order _order)
internal
view
returns (bool)
{
if(_order.account == address(0) || _order.byUser == address(0)
|| _order.value <= 0
|| _order.expirationTimestamp <= _order.createdTimestamp || _order.salt <= 0) {
return false;
}
if(isOrder[_order.orderHash]) {
return false;
}
if(cancelledOrders[_order.orderHash]) {
return false;
}
return true;
}
function _composeOrder(address[3] _orderAddresses, uint[3] _orderValues)
internal
view
returns (Order _order)
{
Order memory order = Order({
account: _orderAddresses[0],
token: _orderAddresses[1],
byUser: _orderAddresses[2],
value: _orderValues[0],
createdTimestamp: now,
duration: _orderValues[1],
expirationTimestamp: add(now, _orderValues[1]),
salt: _orderValues[2],
orderHash: bytes32(0)
});
order.orderHash = _generateCreateOrderHash(order);
return order;
}
function _generateCreateOrderHash(Order _order)
internal
pure //view
returns (bytes32 _orderHash)
{
return keccak256(
abi.encodePacked(
// address(this),
_order.account,
_order.token,
_order.value,
_order.duration,
_order.salt
)
);
}
function _generateActionOrderHash
(
bytes32 _orderHash,
string _action
)
internal
pure //view
returns (bytes32 _repayOrderHash)
{
return keccak256(
abi.encodePacked(
// address(this),
_orderHash,
_action
)
);
}
function _getDateTimestamp(uint _timestamp)
internal
view
returns (uint)
{
// 1 day
return dateTime.toTimestamp(dateTime.getYear(_timestamp), dateTime.getMonth(_timestamp), dateTime.getDay(_timestamp));
// 1 hour
//return dateTime.toTimestamp(dateTime.getYear(_timestamp), dateTime.getMonth(_timestamp), dateTime.getDay(_timestamp), dateTime.getHour(_timestamp));
}
}
contract KyberConnector is ExchangeConnector, DSThing, Utils {
KyberNetworkProxy public kyber;
address public feeWallet;
uint constant internal KYBER_MAX_QTY = (10**28);
constructor(KyberNetworkProxy _kyber, address _feeWallet) public {
kyber = _kyber;
feeWallet = _feeWallet;
}
function setKyber(KyberNetworkProxy _kyber)
public
auth
addressValid(_kyber)
{
kyber = _kyber;
}
function setFeeWallet(address _feeWallet)
public
note
auth
addressValid(_feeWallet)
{
feeWallet = _feeWallet;
}
event LogTrade
(
address indexed _from,
address indexed _srcToken,
address indexed _destToken,
uint _srcTokenValue,
uint _maxDestTokenValue,
uint _destTokenValue,
uint _srcTokenValueLeft,
uint _exchangeRate
);
function tradeWithInputFixed
(
Escrow _escrow,
address _srcToken,
address _destToken,
uint _srcTokenValue
)
public
note
auth
returns (uint _destTokenValue, uint _srcTokenValueLeft)
{
return tradeWithOutputFixed(_escrow, _srcToken, _destToken, _srcTokenValue, KYBER_MAX_QTY);
}
function tradeWithOutputFixed
(
Escrow _escrow,
address _srcToken,
address _destToken,
uint _srcTokenValue,
uint _maxDestTokenValue
)
public
note
auth
returns (uint _destTokenValue, uint _srcTokenValueLeft)
{
require(_srcToken != _destToken, "KyberConnector::tradeWithOutputFixed TOKEN_ADDRS_SHOULD_NOT_MATCH");
uint _slippageRate;
(, _slippageRate) = getExpectedRate(_srcToken, _destToken, _srcTokenValue);
uint initialSrcTokenBalance = ERC20(_srcToken).balanceOf(this);
require(ERC20(_srcToken).balanceOf(_escrow) >= _srcTokenValue, "KyberConnector::tradeWithOutputFixed INSUFFICIENT_BALANCE_IN_ESCROW");
_escrow.transfer(_srcToken, this, _srcTokenValue);
require(ERC20(_srcToken).approve(kyber, 0), "KyberConnector::tradeWithOutputFixed SRC_APPROVAL_FAILED");
require(ERC20(_srcToken).approve(kyber, _srcTokenValue), "KyberConnector::tradeWithOutputFixed SRC_APPROVAL_FAILED");
_destTokenValue = kyber.tradeWithHint(
ERC20(_srcToken),
_srcTokenValue,
ERC20(_destToken),
this,
_maxDestTokenValue,
_slippageRate, // no min coversation rate
feeWallet,
new bytes(0)
);
_srcTokenValueLeft = sub(ERC20(_srcToken).balanceOf(this), initialSrcTokenBalance);
require(_transfer(_destToken, _escrow, _destTokenValue), "KyberConnector::tradeWithOutputFixed DEST_TOKEN_TRANSFER_FAILED");
if(_srcTokenValueLeft > 0) {
require(_transfer(_srcToken, _escrow, _srcTokenValueLeft), "KyberConnector::tradeWithOutputFixed SRC_TOKEN_TRANSFER_FAILED");
}
emit LogTrade(_escrow, _srcToken, _destToken, _srcTokenValue, _maxDestTokenValue, _destTokenValue, _srcTokenValueLeft, _slippageRate);
}
function getExpectedRate(address _srcToken, address _destToken, uint _srcTokenValue)
public
view
returns(uint _expectedRate, uint _slippageRate)
{
(_expectedRate, _slippageRate) = kyber.getExpectedRate(ERC20(_srcToken), ERC20(_destToken), _srcTokenValue);
}
function isTradeFeasible(address _srcToken, address _destToken, uint _srcTokenValue)
public
view
returns(bool)
{
uint slippageRate;
(, slippageRate) = getExpectedRate(
_srcToken,
_destToken,
_srcTokenValue
);
return slippageRate != 0;
}
function _transfer
(
address _token,
address _to,
uint _value
)
internal
returns (bool)
{
return ERC20(_token).transfer(_to, _value);
}
}
contract Kernel is DSStop, DSThing, Utils, Utils2, ErrorUtils {
Escrow public escrow;
AccountFactory public accountFactory;
Reserve public reserve;
address public feeWallet;
Config public config;
KyberConnector public kyberConnector;
string constant public VERSION = "1.0.0";
constructor
(
Escrow _escrow,
AccountFactory _accountFactory,
Reserve _reserve,
address _feeWallet,
Config _config,
KyberConnector _kyberConnector
)
public
{
escrow = _escrow;
accountFactory = _accountFactory;
reserve = _reserve;
feeWallet = _feeWallet;
config = _config;
kyberConnector = _kyberConnector;
}
function setEscrow(Escrow _escrow)
public
note
auth
addressValid(_escrow)
{
escrow = _escrow;
}
function setAccountFactory(AccountFactory _accountFactory)
public
note
auth
addressValid(_accountFactory)
{
accountFactory = _accountFactory;
}
function setReserve(Reserve _reserve)
public
note
auth
addressValid(_reserve)
{
reserve = _reserve;
}
function setConfig(Config _config)
public
note
auth
addressValid(_config)
{
config = _config;
}
function setKyberConnector(KyberConnector _kyberConnector)
public
note
auth
addressValid(_kyberConnector)
{
kyberConnector = _kyberConnector;
}
function setFeeWallet(address _feeWallet)
public
note
auth
addressValid(_feeWallet)
{
feeWallet = _feeWallet;
}
event LogOrderCreated(
bytes32 indexed orderHash,
address indexed account,
address indexed principalToken,
address collateralToken,
address byUser,
uint principalAmount,
uint collateralAmount,
uint premium, // should be in wad?
uint expirationTimestamp,
uint fee
);
event LogOrderRepaid(
bytes32 indexed orderHash,
uint valueRepaid
);
event LogOrderDefaulted(
bytes32 indexed orderHash,
string reason
);
struct Order {
address account;
address byUser;
address principalToken;
address collateralToken;
uint principalAmount;
uint collateralAmount;
uint premium;
uint duration;
uint expirationTimestamp;
uint salt;
uint fee;
uint createdTimestamp;
bytes32 orderHash;
}
bytes32[] public orders;
mapping (bytes32 => Order) public hashToOrder;
mapping (bytes32 => bool) public isOrder;
mapping (address => bytes32[]) public accountToOrders;
mapping (bytes32 => bool) public isRepaid;
mapping (bytes32 => bool) public isDefaulted;
modifier onlyAdmin() {
require(config.isAdminValid(msg.sender), "Kernel::_ INVALID_ADMIN_ACCOUNT");
_;
}
// add price to check collateralisation ratio?
function createOrder
(
address[4] _orderAddresses,
uint[6] _orderValues,
bytes _signature
)
external
note
onlyAdmin
whenNotStopped
{
Order memory order = _composeOrder(_orderAddresses, _orderValues);
address signer = _recoverSigner(order.orderHash, _signature);
if(signer != order.byUser) {
emit LogErrorWithHintBytes32(order.orderHash, "Kernel::createOrder","SIGNER_NOT_ORDER_CREATOR");
return;
}
if(isOrder[order.orderHash]){
emit LogErrorWithHintBytes32(order.orderHash, "Kernel::createOrder","ORDER_ALREADY_EXISTS");
return;
}
if(!accountFactory.isAccount(order.account)){
emit LogErrorWithHintBytes32(order.orderHash, "Kernel::createOrder","INVALID_ORDER_ACCOUNT");
return;
}
if(!Account(order.account).isUser(signer)) {
emit LogErrorWithHintBytes32(order.orderHash, "Kernel::createOrder","SIGNER_NOT_AUTHORIZED_WITH_ACCOUNT");
return;
}
if(!_isOrderValid(order)){
emit LogErrorWithHintBytes32(order.orderHash, "Kernel::createOrder","INVALID_ORDER_PARAMETERS");
return;
}
if(ERC20(order.collateralToken).balanceOf(order.account) < order.collateralAmount){
emit LogErrorWithHintBytes32(order.orderHash, "Kernel::createOrder","INSUFFICIENT_COLLATERAL_IN_ACCOUNT");
return;
}
if(ERC20(order.principalToken).balanceOf(reserve.escrow()) < order.principalAmount){
emit LogErrorWithHintBytes32(order.orderHash, "Kernel::createOrder","INSUFFICIENT_FUNDS_IN_RESERVE");
return;
}
orders.push(order.orderHash);
hashToOrder[order.orderHash] = order;
isOrder[order.orderHash] = true;
accountToOrders[order.account].push(order.orderHash);
escrow.transferFromAccount(order.account, order.collateralToken, address(escrow), order.collateralAmount);
reserve.release(order.principalToken, order.account, order.principalAmount);
emit LogOrderCreated(
order.orderHash,
order.account,
order.principalToken,
order.collateralToken,
order.byUser,
order.principalAmount,
order.collateralAmount,
order.premium,
order.expirationTimestamp,
order.fee
);
}
function getExpectedRepayValue(bytes32 _orderHash)
public
view
returns (uint)
{
Order memory order = hashToOrder[_orderHash];
uint profits = sub(div(mul(order.principalAmount, order.premium), WAD), order.fee);
uint valueToRepay = add(order.principalAmount, profits);
return valueToRepay;
}
function repay
(
bytes32 _orderHash,
uint _value,
bytes _signature
)
external
note
onlyAdmin
{
if(!isOrder[_orderHash]){
emit LogErrorWithHintBytes32(_orderHash, "Kernel::repay","ORDER_DOES_NOT_EXIST");
return;
}
if(isRepaid[_orderHash]){
emit LogErrorWithHintBytes32(_orderHash, "Kernel::repay","ORDER_ALREADY_REPAID");
return;
}
if(isDefaulted[_orderHash]){
emit LogErrorWithHintBytes32(_orderHash, "Kernel::repay","ORDER_ALREADY_DEFAULTED");
return;
}
bytes32 repayOrderHash = _generateRepayOrderHash(_orderHash, _value);
address signer = _recoverSigner(repayOrderHash, _signature);
Order memory order = hashToOrder[_orderHash];
if(!Account(order.account).isUser(signer)){
emit LogErrorWithHintBytes32(_orderHash, "Kernel::repay","SIGNER_NOT_AUTHORIZED_WITH_ACCOUNT");
return;
}
if(ERC20(order.principalToken).balanceOf(order.account) < _value){
emit LogErrorWithHintBytes32(_orderHash, "Kernel::repay","INSUFFICIENT_BALANCE_IN_ACCOUNT");
return;
}
uint profits = sub(div(mul(order.principalAmount, order.premium), WAD), order.fee);
uint valueToRepay = add(order.principalAmount, profits);
if(valueToRepay > _value){
emit LogErrorWithHintBytes32(_orderHash, "Kernel::repay","INSUFFICIENT_REPAYMENT");
return;
}
if(order.fee > 0) {
escrow.transferFromAccount(order.account, order.principalToken, feeWallet, order.fee);
}
reserve.lock(order.principalToken, order.account, valueToRepay, profits, 0);
escrow.transfer(order.collateralToken, order.account, order.collateralAmount);
isRepaid[order.orderHash] = true;
emit LogOrderRepaid(
order.orderHash,
_value
);
}
function process
(
bytes32 _orderHash,
uint _principalPerCollateral // in WAD
)
external
note
onlyAdmin
{
if(!isOrder[_orderHash]){
emit LogErrorWithHintBytes32(_orderHash, "Kernel::process","ORDER_DOES_NOT_EXIST");
return;
}
if(isRepaid[_orderHash]){
emit LogErrorWithHintBytes32(_orderHash, "Kernel::process","ORDER_ALREADY_REPAID");
return;
}
if(isDefaulted[_orderHash]){
emit LogErrorWithHintBytes32(_orderHash, "Kernel::process","ORDER_ALREADY_DEFAULTED");
return;
}
Order memory order = hashToOrder[_orderHash];
bool isDefault = false;
string memory reason = "";
if(now > order.expirationTimestamp) {
isDefault = true;
reason = "DUE_DATE_PASSED";
} else if (!_isCollateralizationSafe(order, _principalPerCollateral)) {
isDefault = true;
reason = "COLLATERAL_UNSAFE";
}
isDefaulted[_orderHash] = isDefault;
if(isDefault) {
_performLiquidation(order);
emit LogOrderDefaulted(order.orderHash, reason);
}
}
function _performLiquidation(Order _order)
internal
{
uint premiumValue = div(mul(_order.principalAmount, _order.premium), WAD);
uint valueToRepay = add(_order.principalAmount, premiumValue);
uint principalFromCollateral;
uint collateralLeft;
(principalFromCollateral, collateralLeft) = kyberConnector.tradeWithOutputFixed(
escrow,
ERC20(_order.collateralToken),
ERC20(_order.principalToken),
_order.collateralAmount,
valueToRepay
);
if (principalFromCollateral >= valueToRepay) {
if(_order.fee > 0) {
escrow.transfer(_order.principalToken, feeWallet, _order.fee);
}
reserve.lock(
_order.principalToken,
escrow,
sub(principalFromCollateral, _order.fee),
sub(sub(principalFromCollateral,_order.principalAmount), _order.fee),
0
);
escrow.transfer(_order.collateralToken, _order.account, collateralLeft);
} else if((principalFromCollateral < valueToRepay) && (principalFromCollateral >= _order.principalAmount)) {
reserve.lock(
_order.principalToken,
escrow,
principalFromCollateral,
sub(principalFromCollateral, _order.principalAmount),
0
);
} else {
reserve.lock(
_order.principalToken,
escrow,
principalFromCollateral,
0,
sub(_order.principalAmount, principalFromCollateral)
);
}
}
function _isCollateralizationSafe(Order _order, uint _principalPerCollateral)
internal
pure
returns (bool)
{
uint totalCollateralValueInPrincipal = div(
mul(_order.collateralAmount, _principalPerCollateral),
WAD);
uint premiumValue = div(mul(_order.principalAmount, _order.premium), WAD);
uint premiumValueBuffer = div(mul(premiumValue, 3), 100); // hardcoded -> can be passed through order?
uint valueToRepay = add(add(_order.principalAmount, premiumValue), premiumValueBuffer);
if (totalCollateralValueInPrincipal < valueToRepay) {
return false;
}
return true;
}
function _generateRepayOrderHash
(
bytes32 _orderHash,
uint _value
)
internal
view
returns (bytes32 _repayOrderHash)
{
return keccak256(
abi.encodePacked(
address(this),
_orderHash,
_value
)
);
}
function _isOrderValid(Order _order)
internal
pure
returns (bool)
{
if(_order.account == address(0) || _order.byUser == address(0)
|| _order.principalToken == address(0) || _order.collateralToken == address(0)
|| (_order.collateralToken == _order.principalToken)
|| _order.principalAmount <= 0 || _order.collateralAmount <= 0
|| _order.premium <= 0
|| _order.expirationTimestamp <= _order.createdTimestamp || _order.salt <= 0) {
return false;
}
return true;
}
function _composeOrder
(
address[4] _orderAddresses,
uint[6] _orderValues
)
internal
view
returns (Order _order)
{
Order memory order = Order({
account: _orderAddresses[0],
byUser: _orderAddresses[1],
principalToken: _orderAddresses[2],
collateralToken: _orderAddresses[3],
principalAmount: _orderValues[0],
collateralAmount: _orderValues[1],
premium: _orderValues[2],
duration: _orderValues[3],
expirationTimestamp: add(now, _orderValues[3]),
salt: _orderValues[4],
fee: _orderValues[5],
createdTimestamp: now,
orderHash: bytes32(0)
});
order.orderHash = _generateOrderHash(order);
return order;
}
function _generateOrderHash(Order _order)
internal
view
returns (bytes32 _orderHash)
{
return keccak256(
abi.encodePacked(
address(this),
_order.account,
_order.principalToken,
_order.collateralToken,
_order.principalAmount,
_order.collateralAmount,
_order.premium,
_order.duration,
_order.salt,
_order.fee
)
);
}
function getAllOrders()
public
view
returns
(
bytes32[]
)
{
return orders;
}
function getOrder(bytes32 _orderHash)
public
view
returns
(
address _account,
address _byUser,
address _principalToken,
address _collateralToken,
uint _principalAmount,
uint _collateralAmount,
uint _premium,
uint _expirationTimestamp,
uint _salt,
uint _fee,
uint _createdTimestamp
)
{
Order memory order = hashToOrder[_orderHash];
return (
order.account,
order.byUser,
order.principalToken,
order.collateralToken,
order.principalAmount,
order.collateralAmount,
order.premium,
order.expirationTimestamp,
order.salt,
order.fee,
order.createdTimestamp
);
}
function getOrdersForAccount(address _account)
public
view
returns
(
bytes32[]
)
{
return accountToOrders[_account];
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"constant":false,"inputs":[],"name":"stop","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orderHash","type":"bytes32"},{"name":"_value","type":"uint256"},{"name":"_signature","type":"bytes"}],"name":"repay","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"owner_","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_orderHash","type":"bytes32"}],"name":"getExpectedRepayValue","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_config","type":"address"}],"name":"setConfig","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"kyberConnector","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"isDefaulted","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_account","type":"address"}],"name":"getOrdersForAccount","outputs":[{"name":"","type":"bytes32[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_orderHash","type":"bytes32"}],"name":"getOrder","outputs":[{"name":"_account","type":"address"},{"name":"_byUser","type":"address"},{"name":"_principalToken","type":"address"},{"name":"_collateralToken","type":"address"},{"name":"_principalAmount","type":"uint256"},{"name":"_collateralAmount","type":"uint256"},{"name":"_premium","type":"uint256"},{"name":"_expirationTimestamp","type":"uint256"},{"name":"_salt","type":"uint256"},{"name":"_fee","type":"uint256"},{"name":"_createdTimestamp","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"accountFactory","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_kyberConnector","type":"address"}],"name":"setKyberConnector","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"uint256"}],"name":"accountToOrders","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"stopped","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"config","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"authority_","type":"address"}],"name":"setAuthority","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getAllOrders","outputs":[{"name":"","type":"bytes32[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"isRepaid","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"isOrder","outputs":[{"name":"","type":"bool"}],"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":"_feeWallet","type":"address"}],"name":"setFeeWallet","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_reserve","type":"address"}],"name":"setReserve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"orders","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_orderHash","type":"bytes32"},{"name":"_principalPerCollateral","type":"uint256"}],"name":"process","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_accountFactory","type":"address"}],"name":"setAccountFactory","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"start","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"authority","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_orderAddresses","type":"address[4]"},{"name":"_orderValues","type":"uint256[6]"},{"name":"_signature","type":"bytes"}],"name":"createOrder","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_escrow","type":"address"}],"name":"setEscrow","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"hashToOrder","outputs":[{"name":"account","type":"address"},{"name":"byUser","type":"address"},{"name":"principalToken","type":"address"},{"name":"collateralToken","type":"address"},{"name":"principalAmount","type":"uint256"},{"name":"collateralAmount","type":"uint256"},{"name":"premium","type":"uint256"},{"name":"duration","type":"uint256"},{"name":"expirationTimestamp","type":"uint256"},{"name":"salt","type":"uint256"},{"name":"fee","type":"uint256"},{"name":"createdTimestamp","type":"uint256"},{"name":"orderHash","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"reserve","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"escrow","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"feeWallet","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"VERSION","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_escrow","type":"address"},{"name":"_accountFactory","type":"address"},{"name":"_reserve","type":"address"},{"name":"_feeWallet","type":"address"},{"name":"_config","type":"address"},{"name":"_kyberConnector","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"orderHash","type":"bytes32"},{"indexed":true,"name":"account","type":"address"},{"indexed":true,"name":"principalToken","type":"address"},{"indexed":false,"name":"collateralToken","type":"address"},{"indexed":false,"name":"byUser","type":"address"},{"indexed":false,"name":"principalAmount","type":"uint256"},{"indexed":false,"name":"collateralAmount","type":"uint256"},{"indexed":false,"name":"premium","type":"uint256"},{"indexed":false,"name":"expirationTimestamp","type":"uint256"},{"indexed":false,"name":"fee","type":"uint256"}],"name":"LogOrderCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"orderHash","type":"bytes32"},{"indexed":false,"name":"valueRepaid","type":"uint256"}],"name":"LogOrderRepaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"orderHash","type":"bytes32"},{"indexed":false,"name":"reason","type":"string"}],"name":"LogOrderDefaulted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"methodSig","type":"string"},{"indexed":false,"name":"errMsg","type":"string"}],"name":"LogError","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"bytes32Value","type":"bytes32"},{"indexed":false,"name":"methodSig","type":"string"},{"indexed":false,"name":"errMsg","type":"string"}],"name":"LogErrorWithHintBytes32","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"addressValue","type":"address"},{"indexed":false,"name":"methodSig","type":"string"},{"indexed":false,"name":"errMsg","type":"string"}],"name":"LogErrorWithHintAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"authority","type":"address"}],"name":"LogSetAuthority","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"}],"name":"LogSetOwner","type":"event"},{"anonymous":true,"inputs":[{"indexed":true,"name":"sig","type":"bytes4"},{"indexed":true,"name":"guy","type":"address"},{"indexed":true,"name":"foo","type":"bytes32"},{"indexed":true,"name":"bar","type":"bytes32"},{"indexed":false,"name":"wad","type":"uint256"},{"indexed":false,"name":"fax","type":"bytes"}],"name":"LogNote","type":"event"}]Contract Creation Code
60806040526001805460a060020a60ff021916905534801561002057600080fd5b5060405160c080613f6183398101604081815282516020840151918401516060850151608086015160a09096015160018054600160a060020a03191633908117909155939694959294919391929091907fce241d7ca1f669fee44b6fc00b8eba2df3bb514eed0f6f668f8f89096e81ed9490600090a260028054600160a060020a0319908116600160a060020a0398891617909155600380548216968816969096179095556004805486169487169490941790935560058054851692861692909217909155600680548416918516919091179055600780549092169216919091179055613e4f806101126000396000f3006080604052600436106101875763ffffffff60e060020a60003504166307da68f5811461018c5780630b7e2e97146101a357806313af4035146101cb57806320cd1649146101ec57806320e3dbd4146102165780632b612988146102375780632fcdb8dd14610268578063359abaed146102945780635778472a14610305578063687cd9c1146103855780636d8a7b9d1461039a5780636dec3260146103bb57806375f12b21146103df57806379502c55146103f45780637a9e5e4b146104095780637bea0d1c1461042a578063817671551461043f5780638723555e146104575780638da5cb5b1461046f57806390d49b9d146104845780639cecc80a146104a5578063a85c38ef146104c6578063acfd6ce6146104de578063addc1a76146104f9578063be9a65551461051a578063bf7e214f1461052f578063c086504214610544578063c10c354614610569578063c559f6861461058a578063cd3293de14610619578063e2fdcc171461062e578063f25f4b5614610643578063ffa1ad7414610658575b600080fd5b34801561019857600080fd5b506101a16106e2565b005b3480156101af57600080fd5b506101a1600480359060248035916044359182019101356107c6565b3480156101d757600080fd5b506101a1600160a060020a03600435166110fd565b3480156101f857600080fd5b506102046004356111a7565b60408051918252519081900360200190f35b34801561022257600080fd5b506101a1600160a060020a03600435166112a0565b34801561024357600080fd5b5061024c6113c0565b60408051600160a060020a039092168252519081900360200190f35b34801561027457600080fd5b506102806004356113cf565b604080519115158252519081900360200190f35b3480156102a057600080fd5b506102b5600160a060020a03600435166113e4565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156102f15781810151838201526020016102d9565b505050509050019250505060405180910390f35b34801561031157600080fd5b5061031d600435611452565b60408051600160a060020a039c8d1681529a8c1660208c0152988b168a8a0152969099166060890152608088019490945260a087019290925260c086015260e08501526101008401526101208301939093526101408201929092529051908190036101600190f35b34801561039157600080fd5b5061024c611614565b3480156103a657600080fd5b506101a1600160a060020a0360043516611623565b3480156103c757600080fd5b50610204600160a060020a0360043516602435611743565b3480156103eb57600080fd5b50610280611773565b34801561040057600080fd5b5061024c611794565b34801561041557600080fd5b506101a1600160a060020a03600435166117a3565b34801561043657600080fd5b506102b5611849565b34801561044b57600080fd5b506102806004356118a2565b34801561046357600080fd5b506102806004356118b7565b34801561047b57600080fd5b5061024c6118cc565b34801561049057600080fd5b506101a1600160a060020a03600435166118db565b3480156104b157600080fd5b506101a1600160a060020a03600435166119fb565b3480156104d257600080fd5b50610204600435611b1b565b3480156104ea57600080fd5b506101a1600435602435611b3a565b34801561050557600080fd5b506101a1600160a060020a036004351661208c565b34801561052657600080fd5b506101a16121ac565b34801561053b57600080fd5b5061024c612279565b34801561055057600080fd5b506101a160046084610144356024810190830135612288565b34801561057557600080fd5b506101a1600160a060020a0360043516612ff5565b34801561059657600080fd5b506105a2600435613115565b60408051600160a060020a039e8f1681529c8e1660208e01529a8d168c8c015298909b1660608b015260808a019690965260a089019490945260c088019290925260e08701526101008601526101208501526101408401526101608301939093526101808201929092529051908190036101a00190f35b34801561062557600080fd5b5061024c61318d565b34801561063a57600080fd5b5061024c61319c565b34801561064f57600080fd5b5061024c6131ab565b34801561066457600080fd5b5061066d6131ba565b6040805160208082528351818301528351919283929083019185019080838360005b838110156106a757818101518382015260200161068f565b50505050905090810190601f1680156106d45780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6106f833600035600160e060020a0319166131f1565b151561073c576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020613da4833981519152604482015290519081900360640190fd5b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a450506001805474ff0000000000000000000000000000000000000000191674010000000000000000000000000000000000000000179055565b6000806107d1613cf3565b6040805134808252602082018381523693830184905260009384936004359360243593849386933393600160e060020a03198a35169390928a929091606082018484808284376040519201829003965090945050505050a4600654604080517f9c14ee290000000000000000000000000000000000000000000000000000000081523360048201529051600160a060020a0390921691639c14ee29916024808201926020929091908290030181600087803b15801561088f57600080fd5b505af11580156108a3573d6000803e3d6000fd5b505050506040513d60208110156108b957600080fd5b50511515610911576040805160e560020a62461bcd02815260206004820152601f60248201527f4b65726e656c3a3a5f20494e56414c49445f41444d494e5f4143434f554e5400604482015290519081900360640190fd5b60008b8152600a602052604090205460ff1615156109a15760408051818152600d81830152600080516020613d8483398151915260608201526080602082018190526014908201527f4f524445525f444f45535f4e4f545f455849535400000000000000000000000060a082015290518c91600080516020613dc4833981519152919081900360c00190a26110f0565b60008b8152600c602052604090205460ff1615610a305760408051818152600d81830152600080516020613d8483398151915260608201526080602082018190526014908201527f4f524445525f414c52454144595f52455041494400000000000000000000000060a082015290518c91600080516020613dc4833981519152919081900360c00190a26110f0565b60008b8152600d602052604090205460ff1615610abf5760408051818152600d81830152600080516020613d8483398151915260608201526080602082018190526017908201527f4f524445525f414c52454144595f44454641554c54454400000000000000000060a082015290518c91600080516020613dc4833981519152919081900360c00190a26110f0565b610ac98b8b6132fa565b9650610b05878a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284375061339b945050505050565b60008c815260096020818152604080842081516101a0810183528154600160a060020a03908116808352600184015482168387015260028401548216838601526003840154821660608401526004808501546080850152600585015460a0850152600685015460c0850152600785015460e0850152600885015461010085015296840154610120840152600a840154610140840152600b840154610160840152600c9093015461018083015283517f4209fff1000000000000000000000000000000000000000000000000000000008152908816958101959095529151959b5090995093634209fff1936024808501948390030190829087803b158015610c0b57600080fd5b505af1158015610c1f573d6000803e3d6000fd5b505050506040513d6020811015610c3557600080fd5b50511515610cdb5760408051818152600d81830152600080516020613d8483398151915260608201526080602082018190526022908201527f5349474e45525f4e4f545f415554484f52495a45445f574954485f4143434f5560a08201527f4e5400000000000000000000000000000000000000000000000000000000000060c082015290518c91600080516020613dc4833981519152919081900360e00190a26110f0565b898560400151600160a060020a03166370a0823187600001516040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b158015610d3f57600080fd5b505af1158015610d53573d6000803e3d6000fd5b505050506040513d6020811015610d6957600080fd5b50511015610de95760408051818152600d81830152600080516020613d848339815191526060820152608060208201819052601f908201527f494e53554646494349454e545f42414c414e43455f494e5f4143434f554e540060a082015290518c91600080516020613dc4833981519152919081900360c00190a26110f0565b610e1a610e0f610e0187608001518860c001516133bd565b670de0b6b3a76400006133e5565b8661014001516133fa565b9350610e2a85608001518561340a565b925089831115610eac5760408051818152600d81830152600080516020613d8483398151915260608201526080602082018190526016908201527f494e53554646494349454e545f52455041594d454e540000000000000000000060a082015290518c91600080516020613dc4833981519152919081900360c00190a26110f0565b60008561014001511115610f5e5760025485516040808801516005546101408a015183517f5e61e1c8000000000000000000000000000000000000000000000000000000008152600160a060020a03958616600482015292851660248401529084166044830152606482015290519190921691635e61e1c891608480830192600092919082900301818387803b158015610f4557600080fd5b505af1158015610f59573d6000803e3d6000fd5b505050505b60048054604080880151885182517f106689a5000000000000000000000000000000000000000000000000000000008152600160a060020a0392831695810195909552811660248501526044840187905260648401889052600060848501819052915192169263106689a59260a4808301939282900301818387803b158015610fe657600080fd5b505af1158015610ffa573d6000803e3d6000fd5b50506002546060880151885160a08a0151604080517fbeabacc8000000000000000000000000000000000000000000000000000000008152600160a060020a039485166004820152928416602484015260448301919091525191909216935063beabacc89250606480830192600092919082900301818387803b15801561108057600080fd5b505af1158015611094573d6000803e3d6000fd5b50505050610180850180516000908152600c6020908152604091829020805460ff19166001179055915181518d8152915190927f2d538ae573a2661798539a62b24b14e263cf75f5597027ac2ecfc44ba8ddf9e3928290030190a25b5050505050505050505050565b61111333600035600160e060020a0319166131f1565b1515611157576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020613da4833981519152604482015290519081900360640190fd5b60018054600160a060020a031916600160a060020a0383811691909117918290556040519116907fce241d7ca1f669fee44b6fc00b8eba2df3bb514eed0f6f668f8f89096e81ed9490600090a250565b60006111b1613cf3565b50600082815260096020818152604080842081516101a0810183528154600160a060020a0390811682526001830154811694820194909452600282015484169281019290925260038101549092166060820152600482015460808201819052600583015460a0830152600683015460c08301819052600784015460e0840152600884015461010084015293830154610120830152600a830154610140830152600b830154610160830152600c90920154610180820152929182916112879161127c91610e01916133bd565b8461014001516133fa565b915061129783608001518361340a565b95945050505050565b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a461130733600035600160e060020a0319166131f1565b151561134b576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020613da4833981519152604482015290519081900360640190fd5b82600160a060020a038116151561139a576040805160e560020a62461bcd0281526020600482015260186024820152600080516020613e04833981519152604482015290519081900360640190fd5b505060068054600160a060020a031916600160a060020a03939093169290921790915550565b600754600160a060020a031681565b600d6020526000908152604090205460ff1681565b600160a060020a0381166000908152600b602090815260409182902080548351818402810184019094528084526060939283018282801561144557602002820191906000526020600020905b81548152600190910190602001808311611430575b505050505090505b919050565b600080600080600080600080600080600061146b613cf3565b600960008e600019166000191681526020019081526020016000206101a060405190810160405290816000820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016001820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016002820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016003820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a03168152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201546000191660001916815250509050806000015181602001518260400151836060015184608001518560a001518660c001518761010001518861012001518961014001518a61016001519b509b509b509b509b509b509b509b509b509b509b505091939597999b90929496989a50565b600354600160a060020a031681565b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a461168a33600035600160e060020a0319166131f1565b15156116ce576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020613da4833981519152604482015290519081900360640190fd5b82600160a060020a038116151561171d576040805160e560020a62461bcd0281526020600482015260186024820152600080516020613e04833981519152604482015290519081900360640190fd5b505060078054600160a060020a031916600160a060020a03939093169290921790915550565b600b6020528160005260406000208181548110151561175e57fe5b90600052602060002001600091509150505481565b60015474010000000000000000000000000000000000000000900460ff1681565b600654600160a060020a031681565b6117b933600035600160e060020a0319166131f1565b15156117fd576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020613da4833981519152604482015290519081900360640190fd5b60008054600160a060020a031916600160a060020a03838116919091178083556040519116917f1abebea81bfa2637f28358c371278fb15ede7ea8dd28d2e03b112ff6d936ada491a250565b6060600880548060200260200160405190810160405280929190818152602001828054801561189857602002820191906000526020600020905b81548152600190910190602001808311611883575b5050505050905090565b600c6020526000908152604090205460ff1681565b600a6020526000908152604090205460ff1681565b600154600160a060020a031681565b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a461194233600035600160e060020a0319166131f1565b1515611986576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020613da4833981519152604482015290519081900360640190fd5b82600160a060020a03811615156119d5576040805160e560020a62461bcd0281526020600482015260186024820152600080516020613e04833981519152604482015290519081900360640190fd5b505060058054600160a060020a031916600160a060020a03939093169290921790915550565b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a4611a6233600035600160e060020a0319166131f1565b1515611aa6576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020613da4833981519152604482015290519081900360640190fd5b82600160a060020a0381161515611af5576040805160e560020a62461bcd0281526020600482015260186024820152600080516020613e04833981519152604482015290519081900360640190fd5b505060048054600160a060020a031916600160a060020a03939093169290921790915550565b6008805482908110611b2957fe5b600091825260209091200154905081565b611b42613cf3565b604080513480825260208201838152369383018490526000936060936004359360243593849386933393600160e060020a03198b35169390928b929091818c018484808284376040519201829003965090945050505050a4600654604080517f9c14ee290000000000000000000000000000000000000000000000000000000081523360048201529051600160a060020a0390921691639c14ee29916024808201926020929091908290030181600087803b158015611c0057600080fd5b505af1158015611c14573d6000803e3d6000fd5b505050506040513d6020811015611c2a57600080fd5b50511515611c82576040805160e560020a62461bcd02815260206004820152601f60248201527f4b65726e656c3a3a5f20494e56414c49445f41444d494e5f4143434f554e5400604482015290519081900360640190fd5b6000878152600a602052604090205460ff161515611d245760408051818152600f818301527f4b65726e656c3a3a70726f63657373000000000000000000000000000000000060608201526080602082018190526014908201527f4f524445525f444f45535f4e4f545f455849535400000000000000000000000060a082015290518891600080516020613dc4833981519152919081900360c00190a2612083565b6000878152600c602052604090205460ff1615611dc55760408051818152600f818301527f4b65726e656c3a3a70726f63657373000000000000000000000000000000000060608201526080602082018190526014908201527f4f524445525f414c52454144595f52455041494400000000000000000000000060a082015290518891600080516020613dc4833981519152919081900360c00190a2612083565b6000878152600d602052604090205460ff1615611e665760408051818152600f818301527f4b65726e656c3a3a70726f63657373000000000000000000000000000000000060608201526080602082018190526017908201527f4f524445525f414c52454144595f44454641554c54454400000000000000000060a082015290518891600080516020613dc4833981519152919081900360c00190a2612083565b600087815260096020818152604080842081516101a0810183528154600160a060020a03908116825260018301548116828601526002830154811682850152600383015416606082015260048201546080820152600582015460a0820152600682015460c0820152600782015460e08201526008820154610100820190815294820154610120820152600a820154610140820152600b820154610160820152600c9091015461018082015281519283019091528382529151919750919550909350421115611f6d5760408051808201909152600f81527f4455455f444154455f50415353454400000000000000000000000000000000006020820152600194509250611fb8565b611f77858761341a565b1515611fb85760408051808201909152601181527f434f4c4c41544552414c5f554e5341464500000000000000000000000000000060208201526001945092505b6000878152600d60205260409020805460ff1916851580159190911790915561208357611fe48561349c565b61018085015160408051602080825286518183015286517f98e393d0760ecfe8e3907134d357e8a4fa5b37e364c3baeb0b059a98317638c4938893928392918301919085019080838360005b83811015612048578181015183820152602001612030565b50505050905090810190601f1680156120755780820380516001836020036101000a031916815260200191505b509250505060405180910390a25b50505050505050565b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a46120f333600035600160e060020a0319166131f1565b1515612137576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020613da4833981519152604482015290519081900360640190fd5b82600160a060020a0381161515612186576040805160e560020a62461bcd0281526020600482015260186024820152600080516020613e04833981519152604482015290519081900360640190fd5b505060038054600160a060020a031916600160a060020a03939093169290921790915550565b6121c233600035600160e060020a0319166131f1565b1515612206576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020613da4833981519152604482015290519081900360640190fd5b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a450506001805474ff000000000000000000000000000000000000000019169055565b600054600160a060020a031681565b612290613cf3565b604080513480825260208201838152369383018490526000936004359360243593849386933393600160e060020a03198a351693928a929190606082018484808284376040519201829003965090945050505050a4600654604080517f9c14ee290000000000000000000000000000000000000000000000000000000081523360048201529051600160a060020a0390921691639c14ee29916024808201926020929091908290030181600087803b15801561234b57600080fd5b505af115801561235f573d6000803e3d6000fd5b505050506040513d602081101561237557600080fd5b505115156123cd576040805160e560020a62461bcd02815260206004820152601f60248201527f4b65726e656c3a3a5f20494e56414c49445f41444d494e5f4143434f554e5400604482015290519081900360640190fd5b60015474010000000000000000000000000000000000000000900460ff1615612440576040805160e560020a62461bcd02815260206004820152601960248201527f445353746f703a3a5f20464541545552455f53544f5050454400000000000000604482015290519081900360640190fd5b604080516080818101909252612487918a90600490839083908082843750506040805160c081810190925293508c9250600691508390839080828437506138fe9350505050565b93506124c884610180015187878080601f0160208091040260200160405190810160405280939291908181526020018383808284375061339b945050505050565b92508360200151600160a060020a031683600160a060020a03161415156125645761018084015160408051818152601381830152600080516020613de483398151915260608201526080602082018190526018908201527f5349474e45525f4e4f545f4f524445525f43524541544f52000000000000000060a08201529051600080516020613dc48339815191529181900360c00190a2612feb565b6101808401516000908152600a602052604090205460ff16156125fc5761018084015160408051818152601381830152600080516020613de483398151915260608201526080602082018190526014908201527f4f524445525f414c52454144595f45584953545300000000000000000000000060a08201529051600080516020613dc48339815191529181900360c00190a2612feb565b6003548451604080517f25ca4c9c000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152905191909216916325ca4c9c9160248083019260209291908290030181600087803b15801561266657600080fd5b505af115801561267a573d6000803e3d6000fd5b505050506040513d602081101561269057600080fd5b505115156127135761018084015160408051818152601381830152600080516020613de483398151915260608201526080602082018190526015908201527f494e56414c49445f4f524445525f4143434f554e54000000000000000000000060a08201529051600080516020613dc48339815191529181900360c00190a2612feb565b8360000151600160a060020a0316634209fff1846040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b15801561277257600080fd5b505af1158015612786573d6000803e3d6000fd5b505050506040513d602081101561279c57600080fd5b505115156128455761018084015160408051818152601381830152600080516020613de483398151915260608201526080602082018190526022908201527f5349474e45525f4e4f545f415554484f52495a45445f574954485f4143434f5560a08201527f4e5400000000000000000000000000000000000000000000000000000000000060c08201529051600080516020613dc48339815191529181900360e00190a2612feb565b61284e846139b9565b15156128cf5761018084015160408051818152601381830152600080516020613de483398151915260608201526080602082018190526018908201527f494e56414c49445f4f524445525f504152414d4554455253000000000000000060a08201529051600080516020613dc48339815191529181900360c00190a2612feb565b8360a001518460600151600160a060020a03166370a0823186600001516040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b15801561293757600080fd5b505af115801561294b573d6000803e3d6000fd5b505050506040513d602081101561296157600080fd5b50511015612a0a5761018084015160408051818152601381830152600080516020613de483398151915260608201526080602082018190526022908201527f494e53554646494349454e545f434f4c4c41544552414c5f494e5f4143434f5560a08201527f4e5400000000000000000000000000000000000000000000000000000000000060c08201529051600080516020613dc48339815191529181900360e00190a2612feb565b83608001518460400151600160a060020a03166370a08231600460009054906101000a9004600160a060020a0316600160a060020a031663e2fdcc176040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015612a7557600080fd5b505af1158015612a89573d6000803e3d6000fd5b505050506040513d6020811015612a9f57600080fd5b50516040805160e060020a63ffffffff8516028152600160a060020a0390921660048301525160248083019260209291908290030181600087803b158015612ae657600080fd5b505af1158015612afa573d6000803e3d6000fd5b505050506040513d6020811015612b1057600080fd5b50511015612b935761018084015160408051818152601381830152600080516020613de48339815191526060820152608060208201819052601d908201527f494e53554646494349454e545f46554e44535f494e5f5245534552564500000060a08201529051600080516020613dc48339815191529181900360c00190a2612feb565b6008846101800151908060018154018082558091505090600182039060005260206000200160009091929091909150906000191690555083600960008661018001516000191660001916815260200190815260200160002060008201518160000160006101000a815481600160a060020a030219169083600160a060020a0316021790555060208201518160010160006101000a815481600160a060020a030219169083600160a060020a0316021790555060408201518160020160006101000a815481600160a060020a030219169083600160a060020a0316021790555060608201518160030160006101000a815481600160a060020a030219169083600160a060020a031602179055506080820151816004015560a0820151816005015560c0820151816006015560e082015181600701556101008201518160080155610120820151816009015561014082015181600a015561016082015181600b015561018082015181600c01906000191690559050506001600a60008661018001516000191660001916815260200190815260200160002060006101000a81548160ff021916908315150217905550600b60008560000151600160a060020a0316600160a060020a031681526020019081526020016000208461018001519080600181540180825580915050906001820390600052602060002001600090919290919091509060001916905550600260009054906101000a9004600160a060020a0316600160a060020a0316635e61e1c885600001518660600151600260009054906101000a9004600160a060020a03168860a001516040518563ffffffff1660e060020a0281526004018085600160a060020a0316600160a060020a0316815260200184600160a060020a0316600160a060020a0316815260200183600160a060020a0316600160a060020a03168152602001828152602001945050505050600060405180830381600087803b158015612e6b57600080fd5b505af1158015612e7f573d6000803e3d6000fd5b505060048054604080890151895160808b015183517f8bfb07c9000000000000000000000000000000000000000000000000000000008152600160a060020a039384169681019690965290821660248601526044850152905191169350638bfb07c99250606480830192600092919082900301818387803b158015612f0357600080fd5b505af1158015612f17573d6000803e3d6000fd5b505050508360400151600160a060020a03168460000151600160a060020a0316856101800151600019167f42436fe8b8c5070e5a6cb3c26e7bc2e889f99c1857c1a1323c54b13fedc655f68760600151886020015189608001518a60a001518b60c001518c61010001518d61014001516040518088600160a060020a0316600160a060020a0316815260200187600160a060020a0316600160a060020a0316815260200186815260200185815260200184815260200183815260200182815260200197505050505050505060405180910390a45b5050505050505050565b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a461305c33600035600160e060020a0319166131f1565b15156130a0576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020613da4833981519152604482015290519081900360640190fd5b82600160a060020a03811615156130ef576040805160e560020a62461bcd0281526020600482015260186024820152600080516020613e04833981519152604482015290519081900360640190fd5b505060028054600160a060020a031916600160a060020a03939093169290921790915550565b600960208190526000918252604090912080546001820154600283015460038401546004850154600586015460068701546007880154600889015499890154600a8a0154600b8b0154600c909b0154600160a060020a039a8b169c998b169b988b169a9097169895979496939592949293919290918d565b600454600160a060020a031681565b600254600160a060020a031681565b600554600160a060020a031681565b60408051808201909152600581527f312e302e30000000000000000000000000000000000000000000000000000000602082015281565b6000600160a060020a03831630141561320c575060016132f4565b600154600160a060020a038481169116141561322a575060016132f4565b600054600160a060020a03161515613244575060006132f4565b60008054604080517fb7009613000000000000000000000000000000000000000000000000000000008152600160a060020a038781166004830152306024830152600160e060020a0319871660448301529151919092169263b700961392606480820193602093909283900390910190829087803b1580156132c557600080fd5b505af11580156132d9573d6000803e3d6000fd5b505050506040513d60208110156132ef57600080fd5b505190505b92915050565b604080516c010000000000000000000000003002602080830191909152603482018590526054808301859052835180840390910181526074909201928390528151600093918291908401908083835b602083106133685780518252601f199092019160209182019101613349565b5181516020939093036101000a600019018019909116921691909117905260405192018290039091209695505050505050565b60006133b6826133aa85613a99565b9063ffffffff613b4316565b9392505050565b60008115806133da5750508082028282828115156133d757fe5b04145b15156132f457600080fd5b600081838115156133f257fe5b049392505050565b808203828111156132f457600080fd5b808201828110156132f457600080fd5b6000806000806000613433610e018860a00151886133bd565b935061344a610e0188608001518960c001516133bd565b925061346161345a8460036133bd565b60646133e5565b915061347a61347488608001518561340a565b8361340a565b90508084101561348d5760009450613492565b600194505b5050505092915050565b6000806000806134b7610e0186608001518760c001516133bd565b93506134c785608001518561340a565b60075460025460608801516040808a015160a08b015182517fc83ec89d000000000000000000000000000000000000000000000000000000008152600160a060020a039586166004820152938516602485015290841660448401526064830152608482018590528051949750919092169263c83ec89d9260a48082019392918290030181600087803b15801561355c57600080fd5b505af1158015613570573d6000803e3d6000fd5b505050506040513d604081101561358657600080fd5b50805160209091015190925090508282106137a057600085610140015111156136425760025460408087015160055461014089015183517fbeabacc8000000000000000000000000000000000000000000000000000000008152600160a060020a03938416600482015291831660248301526044820152915192169163beabacc89160648082019260009290919082900301818387803b15801561362957600080fd5b505af115801561363d573d6000803e3d6000fd5b505050505b6004546040860151600254610140880151600160a060020a039384169363106689a5939216906136739087906133fa565b61368f613684888c608001516133fa565b8b61014001516133fa565b6040805160e060020a63ffffffff8816028152600160a060020a03958616600482015293909416602484015260448301919091526064820152600060848201819052915160a4808301939282900301818387803b1580156136ef57600080fd5b505af1158015613703573d6000803e3d6000fd5b505060025460608801518851604080517fbeabacc8000000000000000000000000000000000000000000000000000000008152600160a060020a0393841660048201529183166024830152604482018790525191909216935063beabacc89250606480830192600092919082900301818387803b15801561378357600080fd5b505af1158015613797573d6000803e3d6000fd5b505050506138f7565b82821080156137b3575084608001518210155b1561384a5760045460408601516002546080880151600160a060020a039384169363106689a59392169086906137ea9082906133fa565b6040805160e060020a63ffffffff8816028152600160a060020a03958616600482015293909416602484015260448301919091526064820152600060848201819052915160a4808301939282900301818387803b15801561378357600080fd5b60045460408601516002546080880151600160a060020a039384169363106689a593921690869060009061387e90836133fa565b6040805160e060020a63ffffffff8916028152600160a060020a039687166004820152949095166024850152604484019290925260648301526084820152905160a480830192600092919082900301818387803b1580156138de57600080fd5b505af11580156138f2573d6000803e3d6000fd5b505050505b5050505050565b613906613cf3565b61390e613cf3565b604080516101a0810182528551600160a060020a03908116825260208088015182168184015287840151821683850152606080890151909216828401528651608084015286015160a08301529185015160c0820152908401805160e08301525161010082019061397f90429061340a565b8152608080860151602083015260a08601516040830152426060830152600091015290506139ac81613c18565b6101808201529392505050565b8051600090600160a060020a031615806139de57506020820151600160a060020a0316155b806139f457506040820151600160a060020a0316155b80613a0a57506060820151600160a060020a0316155b80613a2e57508160400151600160a060020a03168260600151600160a060020a0316145b80613a3e57506000826080015111155b80613a4e575060008260a0015111155b80613a5e575060008260c0015111155b80613a73575081610160015182610100015111155b80613a845750600082610120015111155b15613a915750600061144d565b506001919050565b604080517f19457468657265756d205369676e6564204d6573736167653a0a333200000000602080830191909152603c80830185905283518084039091018152605c909201928390528151600093918291908401908083835b60208310613b115780518252601f199092019160209182019101613af2565b5181516020939093036101000a6000190180199091169216919091179052604051920182900390912095945050505050565b60008060008084516041141515613b5d5760009350613c0f565b50505060208201516040830151606084015160001a601b60ff82161015613b8257601b015b8060ff16601b14158015613b9a57508060ff16601c14155b15613ba85760009350613c0f565b60408051600080825260208083018085528a905260ff8516838501526060830187905260808301869052925160019360a0808501949193601f19840193928390039091019190865af1158015613c02573d6000803e3d6000fd5b5050506020604051035193505b50505092915050565b80516040808301516060840151608085015160a086015160c087015160e08801516101208901516101408a015188516c01000000000000000000000000308102602080840191909152600160a060020a039c8d1682026034840152998c16810260488301529a909716909902605c8701526070860194909452609085019290925260b084015260d083015260f0820152610110808201949094528251808203909401845261013001918290528251600093929182919084019080838360208310613b115780518252601f199092019160209182019101613af2565b6101a0604051908101604052806000600160a060020a031681526020016000600160a060020a031681526020016000600160a060020a031681526020016000600160a060020a03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008019168152509056004b65726e656c3a3a7265706179000000000000000000000000000000000000004453417574683a3a5f2053454e4445525f4e4f545f415554484f52495a454400db0b341562703a7cbd47efa0b024b1ed2e3c68e2d313e46d276db9a46d8a6f804b65726e656c3a3a6372656174654f72646572000000000000000000000000005574696c733a3a5f20494e56414c49445f414444524553530000000000000000a165627a7a7230582081a021c80837ae0518b8c3e2b233a2e8b17c0a3182f3058e9aa43ada0691d9290029000000000000000000000000af38668f4719ecf9452dc0300be3f6c83cbf37210000000000000000000000004e9d7f37eadc6fef64b5f5dccc4deb622466767700000000000000000000000064d14595152b430cf6940da15c6e39545c7c5b7e0000000000000000000000003e990e787a88cd4426fb3af9b90dd1d951e2cb87000000000000000000000000431f429035a1e3059d5c6a9a83208c6d3143d925000000000000000000000000521550e569bc80f1b4957c4f3fd3d677d9ca31f1
Deployed Bytecode
0x6080604052600436106101875763ffffffff60e060020a60003504166307da68f5811461018c5780630b7e2e97146101a357806313af4035146101cb57806320cd1649146101ec57806320e3dbd4146102165780632b612988146102375780632fcdb8dd14610268578063359abaed146102945780635778472a14610305578063687cd9c1146103855780636d8a7b9d1461039a5780636dec3260146103bb57806375f12b21146103df57806379502c55146103f45780637a9e5e4b146104095780637bea0d1c1461042a578063817671551461043f5780638723555e146104575780638da5cb5b1461046f57806390d49b9d146104845780639cecc80a146104a5578063a85c38ef146104c6578063acfd6ce6146104de578063addc1a76146104f9578063be9a65551461051a578063bf7e214f1461052f578063c086504214610544578063c10c354614610569578063c559f6861461058a578063cd3293de14610619578063e2fdcc171461062e578063f25f4b5614610643578063ffa1ad7414610658575b600080fd5b34801561019857600080fd5b506101a16106e2565b005b3480156101af57600080fd5b506101a1600480359060248035916044359182019101356107c6565b3480156101d757600080fd5b506101a1600160a060020a03600435166110fd565b3480156101f857600080fd5b506102046004356111a7565b60408051918252519081900360200190f35b34801561022257600080fd5b506101a1600160a060020a03600435166112a0565b34801561024357600080fd5b5061024c6113c0565b60408051600160a060020a039092168252519081900360200190f35b34801561027457600080fd5b506102806004356113cf565b604080519115158252519081900360200190f35b3480156102a057600080fd5b506102b5600160a060020a03600435166113e4565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156102f15781810151838201526020016102d9565b505050509050019250505060405180910390f35b34801561031157600080fd5b5061031d600435611452565b60408051600160a060020a039c8d1681529a8c1660208c0152988b168a8a0152969099166060890152608088019490945260a087019290925260c086015260e08501526101008401526101208301939093526101408201929092529051908190036101600190f35b34801561039157600080fd5b5061024c611614565b3480156103a657600080fd5b506101a1600160a060020a0360043516611623565b3480156103c757600080fd5b50610204600160a060020a0360043516602435611743565b3480156103eb57600080fd5b50610280611773565b34801561040057600080fd5b5061024c611794565b34801561041557600080fd5b506101a1600160a060020a03600435166117a3565b34801561043657600080fd5b506102b5611849565b34801561044b57600080fd5b506102806004356118a2565b34801561046357600080fd5b506102806004356118b7565b34801561047b57600080fd5b5061024c6118cc565b34801561049057600080fd5b506101a1600160a060020a03600435166118db565b3480156104b157600080fd5b506101a1600160a060020a03600435166119fb565b3480156104d257600080fd5b50610204600435611b1b565b3480156104ea57600080fd5b506101a1600435602435611b3a565b34801561050557600080fd5b506101a1600160a060020a036004351661208c565b34801561052657600080fd5b506101a16121ac565b34801561053b57600080fd5b5061024c612279565b34801561055057600080fd5b506101a160046084610144356024810190830135612288565b34801561057557600080fd5b506101a1600160a060020a0360043516612ff5565b34801561059657600080fd5b506105a2600435613115565b60408051600160a060020a039e8f1681529c8e1660208e01529a8d168c8c015298909b1660608b015260808a019690965260a089019490945260c088019290925260e08701526101008601526101208501526101408401526101608301939093526101808201929092529051908190036101a00190f35b34801561062557600080fd5b5061024c61318d565b34801561063a57600080fd5b5061024c61319c565b34801561064f57600080fd5b5061024c6131ab565b34801561066457600080fd5b5061066d6131ba565b6040805160208082528351818301528351919283929083019185019080838360005b838110156106a757818101518382015260200161068f565b50505050905090810190601f1680156106d45780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6106f833600035600160e060020a0319166131f1565b151561073c576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020613da4833981519152604482015290519081900360640190fd5b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a450506001805474ff0000000000000000000000000000000000000000191674010000000000000000000000000000000000000000179055565b6000806107d1613cf3565b6040805134808252602082018381523693830184905260009384936004359360243593849386933393600160e060020a03198a35169390928a929091606082018484808284376040519201829003965090945050505050a4600654604080517f9c14ee290000000000000000000000000000000000000000000000000000000081523360048201529051600160a060020a0390921691639c14ee29916024808201926020929091908290030181600087803b15801561088f57600080fd5b505af11580156108a3573d6000803e3d6000fd5b505050506040513d60208110156108b957600080fd5b50511515610911576040805160e560020a62461bcd02815260206004820152601f60248201527f4b65726e656c3a3a5f20494e56414c49445f41444d494e5f4143434f554e5400604482015290519081900360640190fd5b60008b8152600a602052604090205460ff1615156109a15760408051818152600d81830152600080516020613d8483398151915260608201526080602082018190526014908201527f4f524445525f444f45535f4e4f545f455849535400000000000000000000000060a082015290518c91600080516020613dc4833981519152919081900360c00190a26110f0565b60008b8152600c602052604090205460ff1615610a305760408051818152600d81830152600080516020613d8483398151915260608201526080602082018190526014908201527f4f524445525f414c52454144595f52455041494400000000000000000000000060a082015290518c91600080516020613dc4833981519152919081900360c00190a26110f0565b60008b8152600d602052604090205460ff1615610abf5760408051818152600d81830152600080516020613d8483398151915260608201526080602082018190526017908201527f4f524445525f414c52454144595f44454641554c54454400000000000000000060a082015290518c91600080516020613dc4833981519152919081900360c00190a26110f0565b610ac98b8b6132fa565b9650610b05878a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284375061339b945050505050565b60008c815260096020818152604080842081516101a0810183528154600160a060020a03908116808352600184015482168387015260028401548216838601526003840154821660608401526004808501546080850152600585015460a0850152600685015460c0850152600785015460e0850152600885015461010085015296840154610120840152600a840154610140840152600b840154610160840152600c9093015461018083015283517f4209fff1000000000000000000000000000000000000000000000000000000008152908816958101959095529151959b5090995093634209fff1936024808501948390030190829087803b158015610c0b57600080fd5b505af1158015610c1f573d6000803e3d6000fd5b505050506040513d6020811015610c3557600080fd5b50511515610cdb5760408051818152600d81830152600080516020613d8483398151915260608201526080602082018190526022908201527f5349474e45525f4e4f545f415554484f52495a45445f574954485f4143434f5560a08201527f4e5400000000000000000000000000000000000000000000000000000000000060c082015290518c91600080516020613dc4833981519152919081900360e00190a26110f0565b898560400151600160a060020a03166370a0823187600001516040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b158015610d3f57600080fd5b505af1158015610d53573d6000803e3d6000fd5b505050506040513d6020811015610d6957600080fd5b50511015610de95760408051818152600d81830152600080516020613d848339815191526060820152608060208201819052601f908201527f494e53554646494349454e545f42414c414e43455f494e5f4143434f554e540060a082015290518c91600080516020613dc4833981519152919081900360c00190a26110f0565b610e1a610e0f610e0187608001518860c001516133bd565b670de0b6b3a76400006133e5565b8661014001516133fa565b9350610e2a85608001518561340a565b925089831115610eac5760408051818152600d81830152600080516020613d8483398151915260608201526080602082018190526016908201527f494e53554646494349454e545f52455041594d454e540000000000000000000060a082015290518c91600080516020613dc4833981519152919081900360c00190a26110f0565b60008561014001511115610f5e5760025485516040808801516005546101408a015183517f5e61e1c8000000000000000000000000000000000000000000000000000000008152600160a060020a03958616600482015292851660248401529084166044830152606482015290519190921691635e61e1c891608480830192600092919082900301818387803b158015610f4557600080fd5b505af1158015610f59573d6000803e3d6000fd5b505050505b60048054604080880151885182517f106689a5000000000000000000000000000000000000000000000000000000008152600160a060020a0392831695810195909552811660248501526044840187905260648401889052600060848501819052915192169263106689a59260a4808301939282900301818387803b158015610fe657600080fd5b505af1158015610ffa573d6000803e3d6000fd5b50506002546060880151885160a08a0151604080517fbeabacc8000000000000000000000000000000000000000000000000000000008152600160a060020a039485166004820152928416602484015260448301919091525191909216935063beabacc89250606480830192600092919082900301818387803b15801561108057600080fd5b505af1158015611094573d6000803e3d6000fd5b50505050610180850180516000908152600c6020908152604091829020805460ff19166001179055915181518d8152915190927f2d538ae573a2661798539a62b24b14e263cf75f5597027ac2ecfc44ba8ddf9e3928290030190a25b5050505050505050505050565b61111333600035600160e060020a0319166131f1565b1515611157576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020613da4833981519152604482015290519081900360640190fd5b60018054600160a060020a031916600160a060020a0383811691909117918290556040519116907fce241d7ca1f669fee44b6fc00b8eba2df3bb514eed0f6f668f8f89096e81ed9490600090a250565b60006111b1613cf3565b50600082815260096020818152604080842081516101a0810183528154600160a060020a0390811682526001830154811694820194909452600282015484169281019290925260038101549092166060820152600482015460808201819052600583015460a0830152600683015460c08301819052600784015460e0840152600884015461010084015293830154610120830152600a830154610140830152600b830154610160830152600c90920154610180820152929182916112879161127c91610e01916133bd565b8461014001516133fa565b915061129783608001518361340a565b95945050505050565b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a461130733600035600160e060020a0319166131f1565b151561134b576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020613da4833981519152604482015290519081900360640190fd5b82600160a060020a038116151561139a576040805160e560020a62461bcd0281526020600482015260186024820152600080516020613e04833981519152604482015290519081900360640190fd5b505060068054600160a060020a031916600160a060020a03939093169290921790915550565b600754600160a060020a031681565b600d6020526000908152604090205460ff1681565b600160a060020a0381166000908152600b602090815260409182902080548351818402810184019094528084526060939283018282801561144557602002820191906000526020600020905b81548152600190910190602001808311611430575b505050505090505b919050565b600080600080600080600080600080600061146b613cf3565b600960008e600019166000191681526020019081526020016000206101a060405190810160405290816000820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016001820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016002820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016003820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a03168152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201546000191660001916815250509050806000015181602001518260400151836060015184608001518560a001518660c001518761010001518861012001518961014001518a61016001519b509b509b509b509b509b509b509b509b509b509b505091939597999b90929496989a50565b600354600160a060020a031681565b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a461168a33600035600160e060020a0319166131f1565b15156116ce576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020613da4833981519152604482015290519081900360640190fd5b82600160a060020a038116151561171d576040805160e560020a62461bcd0281526020600482015260186024820152600080516020613e04833981519152604482015290519081900360640190fd5b505060078054600160a060020a031916600160a060020a03939093169290921790915550565b600b6020528160005260406000208181548110151561175e57fe5b90600052602060002001600091509150505481565b60015474010000000000000000000000000000000000000000900460ff1681565b600654600160a060020a031681565b6117b933600035600160e060020a0319166131f1565b15156117fd576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020613da4833981519152604482015290519081900360640190fd5b60008054600160a060020a031916600160a060020a03838116919091178083556040519116917f1abebea81bfa2637f28358c371278fb15ede7ea8dd28d2e03b112ff6d936ada491a250565b6060600880548060200260200160405190810160405280929190818152602001828054801561189857602002820191906000526020600020905b81548152600190910190602001808311611883575b5050505050905090565b600c6020526000908152604090205460ff1681565b600a6020526000908152604090205460ff1681565b600154600160a060020a031681565b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a461194233600035600160e060020a0319166131f1565b1515611986576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020613da4833981519152604482015290519081900360640190fd5b82600160a060020a03811615156119d5576040805160e560020a62461bcd0281526020600482015260186024820152600080516020613e04833981519152604482015290519081900360640190fd5b505060058054600160a060020a031916600160a060020a03939093169290921790915550565b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a4611a6233600035600160e060020a0319166131f1565b1515611aa6576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020613da4833981519152604482015290519081900360640190fd5b82600160a060020a0381161515611af5576040805160e560020a62461bcd0281526020600482015260186024820152600080516020613e04833981519152604482015290519081900360640190fd5b505060048054600160a060020a031916600160a060020a03939093169290921790915550565b6008805482908110611b2957fe5b600091825260209091200154905081565b611b42613cf3565b604080513480825260208201838152369383018490526000936060936004359360243593849386933393600160e060020a03198b35169390928b929091818c018484808284376040519201829003965090945050505050a4600654604080517f9c14ee290000000000000000000000000000000000000000000000000000000081523360048201529051600160a060020a0390921691639c14ee29916024808201926020929091908290030181600087803b158015611c0057600080fd5b505af1158015611c14573d6000803e3d6000fd5b505050506040513d6020811015611c2a57600080fd5b50511515611c82576040805160e560020a62461bcd02815260206004820152601f60248201527f4b65726e656c3a3a5f20494e56414c49445f41444d494e5f4143434f554e5400604482015290519081900360640190fd5b6000878152600a602052604090205460ff161515611d245760408051818152600f818301527f4b65726e656c3a3a70726f63657373000000000000000000000000000000000060608201526080602082018190526014908201527f4f524445525f444f45535f4e4f545f455849535400000000000000000000000060a082015290518891600080516020613dc4833981519152919081900360c00190a2612083565b6000878152600c602052604090205460ff1615611dc55760408051818152600f818301527f4b65726e656c3a3a70726f63657373000000000000000000000000000000000060608201526080602082018190526014908201527f4f524445525f414c52454144595f52455041494400000000000000000000000060a082015290518891600080516020613dc4833981519152919081900360c00190a2612083565b6000878152600d602052604090205460ff1615611e665760408051818152600f818301527f4b65726e656c3a3a70726f63657373000000000000000000000000000000000060608201526080602082018190526017908201527f4f524445525f414c52454144595f44454641554c54454400000000000000000060a082015290518891600080516020613dc4833981519152919081900360c00190a2612083565b600087815260096020818152604080842081516101a0810183528154600160a060020a03908116825260018301548116828601526002830154811682850152600383015416606082015260048201546080820152600582015460a0820152600682015460c0820152600782015460e08201526008820154610100820190815294820154610120820152600a820154610140820152600b820154610160820152600c9091015461018082015281519283019091528382529151919750919550909350421115611f6d5760408051808201909152600f81527f4455455f444154455f50415353454400000000000000000000000000000000006020820152600194509250611fb8565b611f77858761341a565b1515611fb85760408051808201909152601181527f434f4c4c41544552414c5f554e5341464500000000000000000000000000000060208201526001945092505b6000878152600d60205260409020805460ff1916851580159190911790915561208357611fe48561349c565b61018085015160408051602080825286518183015286517f98e393d0760ecfe8e3907134d357e8a4fa5b37e364c3baeb0b059a98317638c4938893928392918301919085019080838360005b83811015612048578181015183820152602001612030565b50505050905090810190601f1680156120755780820380516001836020036101000a031916815260200191505b509250505060405180910390a25b50505050505050565b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a46120f333600035600160e060020a0319166131f1565b1515612137576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020613da4833981519152604482015290519081900360640190fd5b82600160a060020a0381161515612186576040805160e560020a62461bcd0281526020600482015260186024820152600080516020613e04833981519152604482015290519081900360640190fd5b505060038054600160a060020a031916600160a060020a03939093169290921790915550565b6121c233600035600160e060020a0319166131f1565b1515612206576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020613da4833981519152604482015290519081900360640190fd5b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a450506001805474ff000000000000000000000000000000000000000019169055565b600054600160a060020a031681565b612290613cf3565b604080513480825260208201838152369383018490526000936004359360243593849386933393600160e060020a03198a351693928a929190606082018484808284376040519201829003965090945050505050a4600654604080517f9c14ee290000000000000000000000000000000000000000000000000000000081523360048201529051600160a060020a0390921691639c14ee29916024808201926020929091908290030181600087803b15801561234b57600080fd5b505af115801561235f573d6000803e3d6000fd5b505050506040513d602081101561237557600080fd5b505115156123cd576040805160e560020a62461bcd02815260206004820152601f60248201527f4b65726e656c3a3a5f20494e56414c49445f41444d494e5f4143434f554e5400604482015290519081900360640190fd5b60015474010000000000000000000000000000000000000000900460ff1615612440576040805160e560020a62461bcd02815260206004820152601960248201527f445353746f703a3a5f20464541545552455f53544f5050454400000000000000604482015290519081900360640190fd5b604080516080818101909252612487918a90600490839083908082843750506040805160c081810190925293508c9250600691508390839080828437506138fe9350505050565b93506124c884610180015187878080601f0160208091040260200160405190810160405280939291908181526020018383808284375061339b945050505050565b92508360200151600160a060020a031683600160a060020a03161415156125645761018084015160408051818152601381830152600080516020613de483398151915260608201526080602082018190526018908201527f5349474e45525f4e4f545f4f524445525f43524541544f52000000000000000060a08201529051600080516020613dc48339815191529181900360c00190a2612feb565b6101808401516000908152600a602052604090205460ff16156125fc5761018084015160408051818152601381830152600080516020613de483398151915260608201526080602082018190526014908201527f4f524445525f414c52454144595f45584953545300000000000000000000000060a08201529051600080516020613dc48339815191529181900360c00190a2612feb565b6003548451604080517f25ca4c9c000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152905191909216916325ca4c9c9160248083019260209291908290030181600087803b15801561266657600080fd5b505af115801561267a573d6000803e3d6000fd5b505050506040513d602081101561269057600080fd5b505115156127135761018084015160408051818152601381830152600080516020613de483398151915260608201526080602082018190526015908201527f494e56414c49445f4f524445525f4143434f554e54000000000000000000000060a08201529051600080516020613dc48339815191529181900360c00190a2612feb565b8360000151600160a060020a0316634209fff1846040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b15801561277257600080fd5b505af1158015612786573d6000803e3d6000fd5b505050506040513d602081101561279c57600080fd5b505115156128455761018084015160408051818152601381830152600080516020613de483398151915260608201526080602082018190526022908201527f5349474e45525f4e4f545f415554484f52495a45445f574954485f4143434f5560a08201527f4e5400000000000000000000000000000000000000000000000000000000000060c08201529051600080516020613dc48339815191529181900360e00190a2612feb565b61284e846139b9565b15156128cf5761018084015160408051818152601381830152600080516020613de483398151915260608201526080602082018190526018908201527f494e56414c49445f4f524445525f504152414d4554455253000000000000000060a08201529051600080516020613dc48339815191529181900360c00190a2612feb565b8360a001518460600151600160a060020a03166370a0823186600001516040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b15801561293757600080fd5b505af115801561294b573d6000803e3d6000fd5b505050506040513d602081101561296157600080fd5b50511015612a0a5761018084015160408051818152601381830152600080516020613de483398151915260608201526080602082018190526022908201527f494e53554646494349454e545f434f4c4c41544552414c5f494e5f4143434f5560a08201527f4e5400000000000000000000000000000000000000000000000000000000000060c08201529051600080516020613dc48339815191529181900360e00190a2612feb565b83608001518460400151600160a060020a03166370a08231600460009054906101000a9004600160a060020a0316600160a060020a031663e2fdcc176040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015612a7557600080fd5b505af1158015612a89573d6000803e3d6000fd5b505050506040513d6020811015612a9f57600080fd5b50516040805160e060020a63ffffffff8516028152600160a060020a0390921660048301525160248083019260209291908290030181600087803b158015612ae657600080fd5b505af1158015612afa573d6000803e3d6000fd5b505050506040513d6020811015612b1057600080fd5b50511015612b935761018084015160408051818152601381830152600080516020613de48339815191526060820152608060208201819052601d908201527f494e53554646494349454e545f46554e44535f494e5f5245534552564500000060a08201529051600080516020613dc48339815191529181900360c00190a2612feb565b6008846101800151908060018154018082558091505090600182039060005260206000200160009091929091909150906000191690555083600960008661018001516000191660001916815260200190815260200160002060008201518160000160006101000a815481600160a060020a030219169083600160a060020a0316021790555060208201518160010160006101000a815481600160a060020a030219169083600160a060020a0316021790555060408201518160020160006101000a815481600160a060020a030219169083600160a060020a0316021790555060608201518160030160006101000a815481600160a060020a030219169083600160a060020a031602179055506080820151816004015560a0820151816005015560c0820151816006015560e082015181600701556101008201518160080155610120820151816009015561014082015181600a015561016082015181600b015561018082015181600c01906000191690559050506001600a60008661018001516000191660001916815260200190815260200160002060006101000a81548160ff021916908315150217905550600b60008560000151600160a060020a0316600160a060020a031681526020019081526020016000208461018001519080600181540180825580915050906001820390600052602060002001600090919290919091509060001916905550600260009054906101000a9004600160a060020a0316600160a060020a0316635e61e1c885600001518660600151600260009054906101000a9004600160a060020a03168860a001516040518563ffffffff1660e060020a0281526004018085600160a060020a0316600160a060020a0316815260200184600160a060020a0316600160a060020a0316815260200183600160a060020a0316600160a060020a03168152602001828152602001945050505050600060405180830381600087803b158015612e6b57600080fd5b505af1158015612e7f573d6000803e3d6000fd5b505060048054604080890151895160808b015183517f8bfb07c9000000000000000000000000000000000000000000000000000000008152600160a060020a039384169681019690965290821660248601526044850152905191169350638bfb07c99250606480830192600092919082900301818387803b158015612f0357600080fd5b505af1158015612f17573d6000803e3d6000fd5b505050508360400151600160a060020a03168460000151600160a060020a0316856101800151600019167f42436fe8b8c5070e5a6cb3c26e7bc2e889f99c1857c1a1323c54b13fedc655f68760600151886020015189608001518a60a001518b60c001518c61010001518d61014001516040518088600160a060020a0316600160a060020a0316815260200187600160a060020a0316600160a060020a0316815260200186815260200185815260200184815260200183815260200182815260200197505050505050505060405180910390a45b5050505050505050565b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a461305c33600035600160e060020a0319166131f1565b15156130a0576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020613da4833981519152604482015290519081900360640190fd5b82600160a060020a03811615156130ef576040805160e560020a62461bcd0281526020600482015260186024820152600080516020613e04833981519152604482015290519081900360640190fd5b505060028054600160a060020a031916600160a060020a03939093169290921790915550565b600960208190526000918252604090912080546001820154600283015460038401546004850154600586015460068701546007880154600889015499890154600a8a0154600b8b0154600c909b0154600160a060020a039a8b169c998b169b988b169a9097169895979496939592949293919290918d565b600454600160a060020a031681565b600254600160a060020a031681565b600554600160a060020a031681565b60408051808201909152600581527f312e302e30000000000000000000000000000000000000000000000000000000602082015281565b6000600160a060020a03831630141561320c575060016132f4565b600154600160a060020a038481169116141561322a575060016132f4565b600054600160a060020a03161515613244575060006132f4565b60008054604080517fb7009613000000000000000000000000000000000000000000000000000000008152600160a060020a038781166004830152306024830152600160e060020a0319871660448301529151919092169263b700961392606480820193602093909283900390910190829087803b1580156132c557600080fd5b505af11580156132d9573d6000803e3d6000fd5b505050506040513d60208110156132ef57600080fd5b505190505b92915050565b604080516c010000000000000000000000003002602080830191909152603482018590526054808301859052835180840390910181526074909201928390528151600093918291908401908083835b602083106133685780518252601f199092019160209182019101613349565b5181516020939093036101000a600019018019909116921691909117905260405192018290039091209695505050505050565b60006133b6826133aa85613a99565b9063ffffffff613b4316565b9392505050565b60008115806133da5750508082028282828115156133d757fe5b04145b15156132f457600080fd5b600081838115156133f257fe5b049392505050565b808203828111156132f457600080fd5b808201828110156132f457600080fd5b6000806000806000613433610e018860a00151886133bd565b935061344a610e0188608001518960c001516133bd565b925061346161345a8460036133bd565b60646133e5565b915061347a61347488608001518561340a565b8361340a565b90508084101561348d5760009450613492565b600194505b5050505092915050565b6000806000806134b7610e0186608001518760c001516133bd565b93506134c785608001518561340a565b60075460025460608801516040808a015160a08b015182517fc83ec89d000000000000000000000000000000000000000000000000000000008152600160a060020a039586166004820152938516602485015290841660448401526064830152608482018590528051949750919092169263c83ec89d9260a48082019392918290030181600087803b15801561355c57600080fd5b505af1158015613570573d6000803e3d6000fd5b505050506040513d604081101561358657600080fd5b50805160209091015190925090508282106137a057600085610140015111156136425760025460408087015160055461014089015183517fbeabacc8000000000000000000000000000000000000000000000000000000008152600160a060020a03938416600482015291831660248301526044820152915192169163beabacc89160648082019260009290919082900301818387803b15801561362957600080fd5b505af115801561363d573d6000803e3d6000fd5b505050505b6004546040860151600254610140880151600160a060020a039384169363106689a5939216906136739087906133fa565b61368f613684888c608001516133fa565b8b61014001516133fa565b6040805160e060020a63ffffffff8816028152600160a060020a03958616600482015293909416602484015260448301919091526064820152600060848201819052915160a4808301939282900301818387803b1580156136ef57600080fd5b505af1158015613703573d6000803e3d6000fd5b505060025460608801518851604080517fbeabacc8000000000000000000000000000000000000000000000000000000008152600160a060020a0393841660048201529183166024830152604482018790525191909216935063beabacc89250606480830192600092919082900301818387803b15801561378357600080fd5b505af1158015613797573d6000803e3d6000fd5b505050506138f7565b82821080156137b3575084608001518210155b1561384a5760045460408601516002546080880151600160a060020a039384169363106689a59392169086906137ea9082906133fa565b6040805160e060020a63ffffffff8816028152600160a060020a03958616600482015293909416602484015260448301919091526064820152600060848201819052915160a4808301939282900301818387803b15801561378357600080fd5b60045460408601516002546080880151600160a060020a039384169363106689a593921690869060009061387e90836133fa565b6040805160e060020a63ffffffff8916028152600160a060020a039687166004820152949095166024850152604484019290925260648301526084820152905160a480830192600092919082900301818387803b1580156138de57600080fd5b505af11580156138f2573d6000803e3d6000fd5b505050505b5050505050565b613906613cf3565b61390e613cf3565b604080516101a0810182528551600160a060020a03908116825260208088015182168184015287840151821683850152606080890151909216828401528651608084015286015160a08301529185015160c0820152908401805160e08301525161010082019061397f90429061340a565b8152608080860151602083015260a08601516040830152426060830152600091015290506139ac81613c18565b6101808201529392505050565b8051600090600160a060020a031615806139de57506020820151600160a060020a0316155b806139f457506040820151600160a060020a0316155b80613a0a57506060820151600160a060020a0316155b80613a2e57508160400151600160a060020a03168260600151600160a060020a0316145b80613a3e57506000826080015111155b80613a4e575060008260a0015111155b80613a5e575060008260c0015111155b80613a73575081610160015182610100015111155b80613a845750600082610120015111155b15613a915750600061144d565b506001919050565b604080517f19457468657265756d205369676e6564204d6573736167653a0a333200000000602080830191909152603c80830185905283518084039091018152605c909201928390528151600093918291908401908083835b60208310613b115780518252601f199092019160209182019101613af2565b5181516020939093036101000a6000190180199091169216919091179052604051920182900390912095945050505050565b60008060008084516041141515613b5d5760009350613c0f565b50505060208201516040830151606084015160001a601b60ff82161015613b8257601b015b8060ff16601b14158015613b9a57508060ff16601c14155b15613ba85760009350613c0f565b60408051600080825260208083018085528a905260ff8516838501526060830187905260808301869052925160019360a0808501949193601f19840193928390039091019190865af1158015613c02573d6000803e3d6000fd5b5050506020604051035193505b50505092915050565b80516040808301516060840151608085015160a086015160c087015160e08801516101208901516101408a015188516c01000000000000000000000000308102602080840191909152600160a060020a039c8d1682026034840152998c16810260488301529a909716909902605c8701526070860194909452609085019290925260b084015260d083015260f0820152610110808201949094528251808203909401845261013001918290528251600093929182919084019080838360208310613b115780518252601f199092019160209182019101613af2565b6101a0604051908101604052806000600160a060020a031681526020016000600160a060020a031681526020016000600160a060020a031681526020016000600160a060020a03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008019168152509056004b65726e656c3a3a7265706179000000000000000000000000000000000000004453417574683a3a5f2053454e4445525f4e4f545f415554484f52495a454400db0b341562703a7cbd47efa0b024b1ed2e3c68e2d313e46d276db9a46d8a6f804b65726e656c3a3a6372656174654f72646572000000000000000000000000005574696c733a3a5f20494e56414c49445f414444524553530000000000000000a165627a7a7230582081a021c80837ae0518b8c3e2b233a2e8b17c0a3182f3058e9aa43ada0691d9290029
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000af38668f4719ecf9452dc0300be3f6c83cbf37210000000000000000000000004e9d7f37eadc6fef64b5f5dccc4deb622466767700000000000000000000000064d14595152b430cf6940da15c6e39545c7c5b7e0000000000000000000000003e990e787a88cd4426fb3af9b90dd1d951e2cb87000000000000000000000000431f429035a1e3059d5c6a9a83208c6d3143d925000000000000000000000000521550e569bc80f1b4957c4f3fd3d677d9ca31f1
-----Decoded View---------------
Arg [0] : _escrow (address): 0xaf38668F4719Ecf9452DC0300BE3f6c83Cbf3721
Arg [1] : _accountFactory (address): 0x4E9D7f37EADc6fef64B5F5DCcC4deB6224667677
Arg [2] : _reserve (address): 0x64d14595152B430CF6940Da15C6e39545c7c5B7e
Arg [3] : _feeWallet (address): 0x3E990e787a88cD4426fB3AF9B90DD1D951E2cb87
Arg [4] : _config (address): 0x431F429035a1e3059d5c6a9a83208c6D3143D925
Arg [5] : _kyberConnector (address): 0x521550E569bc80F1b4957C4F3Fd3D677d9ca31f1
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 000000000000000000000000af38668f4719ecf9452dc0300be3f6c83cbf3721
Arg [1] : 0000000000000000000000004e9d7f37eadc6fef64b5f5dccc4deb6224667677
Arg [2] : 00000000000000000000000064d14595152b430cf6940da15c6e39545c7c5b7e
Arg [3] : 0000000000000000000000003e990e787a88cd4426fb3af9b90dd1d951e2cb87
Arg [4] : 000000000000000000000000431f429035a1e3059d5c6a9a83208c6d3143d925
Arg [5] : 000000000000000000000000521550e569bc80f1b4957c4f3fd3d677d9ca31f1
Swarm Source
bzzr://81a021c80837ae0518b8c3e2b233a2e8b17c0a3182f3058e9aa43ada0691d929
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.