More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 30,793 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Process Trade Fo... | 11868876 | 1328 days ago | IN | 0 ETH | 0.05672727 | ||||
Process Trade Fo... | 11868876 | 1328 days ago | IN | 0 ETH | 0.13643383 | ||||
Process Trade Fo... | 11863153 | 1329 days ago | IN | 0 ETH | 0.0090639 | ||||
Process Trade Fo... | 11863064 | 1329 days ago | IN | 0 ETH | 0.00817138 | ||||
Process Trade Fo... | 11863064 | 1329 days ago | IN | 0 ETH | 0.00871123 | ||||
Process Trade Fo... | 11863057 | 1329 days ago | IN | 0 ETH | 0.00750159 | ||||
Process Trade Fo... | 11863013 | 1329 days ago | IN | 0 ETH | 0.00829426 | ||||
Process Trade Fo... | 11863013 | 1329 days ago | IN | 0 ETH | 0.00884223 | ||||
Process Trade Fo... | 11863008 | 1329 days ago | IN | 0 ETH | 0.0075862 | ||||
Process Trade Fo... | 10885277 | 1479 days ago | IN | 0 ETH | 0.00983808 | ||||
Process Trade Fo... | 10884531 | 1480 days ago | IN | 0 ETH | 0.00983808 | ||||
Process Trade Fo... | 10884531 | 1480 days ago | IN | 0 ETH | 0.39328744 | ||||
Process Trade Fo... | 10861056 | 1483 days ago | IN | 0 ETH | 0.01041572 | ||||
Process Trade Fo... | 10861023 | 1483 days ago | IN | 0 ETH | 0.01041908 | ||||
Process Trade Fo... | 10860963 | 1483 days ago | IN | 0 ETH | 0.01041908 | ||||
Liquidate Order | 10845021 | 1486 days ago | IN | 0 ETH | 0.00729017 | ||||
Process Trade Fo... | 10813234 | 1490 days ago | IN | 0 ETH | 0.38459671 | ||||
Process Trade Fo... | 10813218 | 1490 days ago | IN | 0 ETH | 0.36496378 | ||||
Process Trade Fo... | 10813198 | 1490 days ago | IN | 0 ETH | 0.349826 | ||||
Process Trade Fo... | 10813173 | 1490 days ago | IN | 0 ETH | 0.38018733 | ||||
Process Trade Fo... | 10812888 | 1491 days ago | IN | 0 ETH | 0.36590355 | ||||
Process Trade Fo... | 10812886 | 1491 days ago | IN | 0 ETH | 0.36451498 | ||||
Process Trade Fo... | 10812879 | 1491 days ago | IN | 0 ETH | 0.36731242 | ||||
Process Trade Fo... | 10803602 | 1492 days ago | IN | 0 ETH | 1.05101332 | ||||
Process Trade Fo... | 10801382 | 1492 days ago | IN | 0 ETH | 0.01757868 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
MKernel
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-18 */ pragma solidity 0.4.24; 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 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 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 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); } } } } contract SelfAuthorized { modifier authorized() { require(msg.sender == address(this), "Method can only be called from this contract"); _; } } 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 Utils { modifier addressValid(address _address) { require(_address != address(0), "Utils::_ INVALID_ADDRESS"); _; } } 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 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; } } 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 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); } } 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 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; } } 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 { } 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)); } } 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 MKernel is DSStop, DSThing, Utils, Utils2, ErrorUtils { Escrow public escrow; AccountFactory public accountFactory; Reserve public reserve; address public feeWallet; Config public config; constructor ( Escrow _escrow, AccountFactory _accountFactory, Reserve _reserve, address _feeWallet, Config _config ) public { escrow = _escrow; accountFactory = _accountFactory; reserve = _reserve; feeWallet = _feeWallet; config = _config; } 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 setFeeWallet(address _feeWallet) public note auth addressValid(_feeWallet) { feeWallet = _feeWallet; } event LogOrderCreated( bytes32 indexed orderHash, uint tradeAmount, uint expirationTimestamp ); event LogOrderLiquidatedByUser( bytes32 indexed orderHash ); event LogOrderStoppedAtProfit( bytes32 indexed orderHash ); event LogOrderDefaulted( bytes32 indexed orderHash, string reason ); event LogNoActionPerformed( bytes32 indexed orderHash ); event LogOrderSettlement( bytes32 indexed orderHash, uint valueRepaid, uint reserveProfit, uint reserveLoss, uint collateralLeft, uint userProfit, uint fee ); struct Order { address account; address byUser; address principalToken; address collateralToken; Trade trade; uint principalAmount; uint collateralAmount; uint premium; uint expirationTimestamp; uint duration; uint salt; uint fee; uint createdTimestamp; bytes32 orderHash; } struct Trade { address tradeToken; address closingToken; address exchangeConnector; //stores initial and then just used to pass around params uint stopProfit; uint stopLoss; } bytes32[] public orders; mapping (bytes32 => Order) public hashToOrder; mapping (bytes32 => bool) public isOrder; mapping (address => bytes32[]) public accountToOrders; mapping (bytes32 => uint) public initialTradeAmount; mapping (bytes32 => bool) public isLiquidated; mapping (bytes32 => bool) public isDefaulted; modifier onlyAdmin() { require(config.isAdminValid(msg.sender), "MKernel::_ INVALID_ADMIN_ACCOUNT"); _; } function createOrder ( address[6] _orderAddresses, uint[8] _orderValues, address _exchangeConnector, bytes _signature ) external note onlyAdmin whenNotStopped addressValid(_exchangeConnector) { Order memory order = _composeOrder(_orderAddresses, _orderValues); address signer = _recoverSigner(order.orderHash, _signature); order.trade.exchangeConnector = _exchangeConnector; if(signer != order.byUser) { emit LogErrorWithHintBytes32(order.orderHash, "MKernel::createOrder","SIGNER_NOT_ORDER_CREATOR"); return; } if(isOrder[order.orderHash]){ emit LogErrorWithHintBytes32(order.orderHash, "MKernel::createOrder","ORDER_ALREADY_EXISTS"); return; } if(!accountFactory.isAccount(order.account)){ emit LogErrorWithHintBytes32(order.orderHash, "MKernel::createOrder","INVALID_ORDER_ACCOUNT"); return; } if(!Account(order.account).isUser(signer)) { emit LogErrorWithHintBytes32(order.orderHash, "MKernel::createOrder","SIGNER_NOT_AUTHORIZED_WITH_ACCOUNT"); return; } if(!_isOrderValid(order)){ emit LogErrorWithHintBytes32(order.orderHash, "MKernel::createOrder","INVALID_ORDER_PARAMETERS"); return; } if(ERC20(order.collateralToken).balanceOf(order.account) < order.collateralAmount){ emit LogErrorWithHintBytes32(order.orderHash, "MKernel::createOrder","INSUFFICIENT_COLLATERAL_IN_ACCOUNT"); return; } if(ERC20(order.principalToken).balanceOf(reserve.escrow()) < order.principalAmount){ emit LogErrorWithHintBytes32(order.orderHash, "MKernel::createOrder","INSUFFICIENT_FUNDS_IN_RESERVE"); return; } if(!_isTradeFeasible(order, order.principalToken, order.trade.tradeToken, order.principalAmount)) { emit LogErrorWithHintBytes32(order.orderHash, "MKernel::createOrder","TRADE_NOT_FEASIBLE"); 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, address(escrow), order.principalAmount); (initialTradeAmount[order.orderHash],) = _tradeWithFixedInput( order, ERC20(order.principalToken), ERC20(order.trade.tradeToken), order.principalAmount ); emit LogOrderCreated( order.orderHash, initialTradeAmount[order.orderHash], order.expirationTimestamp ); } function liquidateOrder ( bytes32 _orderHash, address _exchangeConnector, bytes _signature ) external note onlyAdmin addressValid(_exchangeConnector) { if(!isOrder[_orderHash]){ emit LogErrorWithHintBytes32(_orderHash, "MKernel::liquidateOrder","ORDER_DOES_NOT_EXIST"); return; } if(isLiquidated[_orderHash]){ emit LogErrorWithHintBytes32(_orderHash, "MKernel::liquidateOrder","ORDER_ALREADY_LIQUIDATED"); return; } if(isDefaulted[_orderHash]){ emit LogErrorWithHintBytes32(_orderHash, "MKernel::liquidateOrder","ORDER_ALREADY_DEFAULTED"); return; } bytes32 liquidateOrderHash = _generateLiquidateOrderHash(_orderHash); address signer = _recoverSigner(liquidateOrderHash, _signature); Order memory order = hashToOrder[_orderHash]; order.trade.exchangeConnector = _exchangeConnector; if(!Account(order.account).isUser(signer)){ emit LogErrorWithHintBytes32(_orderHash, "MKernel::liquidateOrder", "SIGNER_NOT_AUTHORIZED_WITH_ACCOUNT"); return; } if(ERC20(order.trade.tradeToken).balanceOf(address(escrow)) < initialTradeAmount[_orderHash]){ emit LogErrorWithHintBytes32(_orderHash, "MKernel::liquidateOrder", "INSUFFICIENT_TRADE_BALANCE_IN_ESCROW"); return; } if(ERC20(order.collateralToken).balanceOf(address(escrow)) < order.collateralAmount){ emit LogErrorWithHintBytes32(_orderHash, "MKernel::liquidateOrder", "INSUFFICIENT_COLLATERAL_BALANCE_IN_ESCROW"); return; } isLiquidated[order.orderHash] = true; _performOrderLiquidation(order); emit LogOrderLiquidatedByUser(_orderHash); } function processTradeForExpiry ( bytes32 _orderHash, address _exchangeConnector ) external note onlyAdmin addressValid(_exchangeConnector) { if(!isOrder[_orderHash]){ emit LogErrorWithHintBytes32(_orderHash, "MKernel::processTradeForExpiry","ORDER_DOES_NOT_EXIST"); return; } if(isLiquidated[_orderHash]){ emit LogErrorWithHintBytes32(_orderHash, "MKernel::processTradeForExpiry","ORDER_ALREADY_LIQUIDATED"); return; } if(isDefaulted[_orderHash]){ emit LogErrorWithHintBytes32(_orderHash, "MKernel::processTradeForExpiry","ORDER_ALREADY_DEFAULTED"); return; } Order memory order = hashToOrder[_orderHash]; order.trade.exchangeConnector = _exchangeConnector; if(ERC20(order.trade.tradeToken).balanceOf(address(escrow)) < initialTradeAmount[_orderHash]){ emit LogErrorWithHintBytes32(_orderHash, "MKernel::processTradeForExpiry", "INSUFFICIENT_TRADE_BALANCE_IN_ESCROW"); return; } if(ERC20(order.collateralToken).balanceOf(address(escrow)) < order.collateralAmount){ emit LogErrorWithHintBytes32(_orderHash, "MKernel::processTradeForExpiry", "INSUFFICIENT_COLLATERAL_BALANCE_IN_ESCROW"); return; } if(now > order.expirationTimestamp) { isDefaulted[order.orderHash] = true; _performOrderLiquidation(order); emit LogOrderDefaulted(order.orderHash, "MKERNEL_DUE_DATE_PASSED"); return; } emit LogErrorWithHintBytes32(order.orderHash, "MKernel::processTradeForExpiry", "NO_ACTION_PERFORMED"); } function processTradeForStopLoss ( bytes32 _orderHash, address _exchangeConnector, uint[2] _tokenPrices, uint _bufferInPrincipal ) external note onlyAdmin addressValid(_exchangeConnector) { if(!isOrder[_orderHash]){ emit LogErrorWithHintBytes32(_orderHash, "MKernel::processTradeForStopLoss","ORDER_DOES_NOT_EXIST"); return; } if(isLiquidated[_orderHash]){ emit LogErrorWithHintBytes32(_orderHash, "MKernel::processTradeForStopLoss","ORDER_ALREADY_LIQUIDATED"); return; } if(isDefaulted[_orderHash]){ emit LogErrorWithHintBytes32(_orderHash, "MKernel::processTradeForStopLoss","ORDER_ALREADY_DEFAULTED"); return; } Order memory order = hashToOrder[_orderHash]; order.trade.exchangeConnector = _exchangeConnector; if(ERC20(order.trade.tradeToken).balanceOf(address(escrow)) < initialTradeAmount[_orderHash]){ emit LogErrorWithHintBytes32(_orderHash, "MKernel::processTradeForStopLoss", "INSUFFICIENT_TRADE_BALANCE_IN_ESCROW"); return; } if(ERC20(order.collateralToken).balanceOf(address(escrow)) < order.collateralAmount){ emit LogErrorWithHintBytes32(_orderHash, "MKernel::processTradeForStopLoss", "INSUFFICIENT_COLLATERAL_BALANCE_IN_ESCROW"); return; } if(!_isPositionAboveStopLoss(order, _tokenPrices, _bufferInPrincipal)) { isDefaulted[order.orderHash] = true; _performOrderLiquidation(order); emit LogOrderDefaulted(order.orderHash, "MKERNEL_ORDER_UNSAFE"); return; } emit LogErrorWithHintBytes32(order.orderHash, "MKernel::processTradeForStopLoss", "NO_ACTION_PERFORMED"); } function processTradeForStopProfit ( bytes32 _orderHash, address _exchangeConnector, uint[2] _tokenPrices, uint _bufferInPrincipal ) external note onlyAdmin addressValid(_exchangeConnector) { if(!isOrder[_orderHash]){ emit LogErrorWithHintBytes32(_orderHash, "MKernel::processTradeForStopProfit","ORDER_DOES_NOT_EXIST"); return; } if(isLiquidated[_orderHash]){ emit LogErrorWithHintBytes32(_orderHash, "MKernel::processTradeForStopProfit","ORDER_ALREADY_LIQUIDATED"); return; } if(isDefaulted[_orderHash]){ emit LogErrorWithHintBytes32(_orderHash, "MKernel::processTradeForStopProfit","ORDER_ALREADY_DEFAULTED"); return; } Order memory order = hashToOrder[_orderHash]; order.trade.exchangeConnector = _exchangeConnector; if(ERC20(order.trade.tradeToken).balanceOf(address(escrow)) < initialTradeAmount[_orderHash]){ emit LogErrorWithHintBytes32(_orderHash, "MKernel::processTradeForStopProfit", "INSUFFICIENT_TRADE_BALANCE_IN_ESCROW"); return; } if(ERC20(order.collateralToken).balanceOf(address(escrow)) < order.collateralAmount){ emit LogErrorWithHintBytes32(_orderHash, "MKernel::processTradeForStopProfit", "INSUFFICIENT_COLLATERAL_BALANCE_IN_ESCROW"); return; } if(_isPositionAboveStopProfit(order, _tokenPrices, _bufferInPrincipal)) { isLiquidated[order.orderHash] = true; _performOrderLiquidation(order); emit LogOrderStoppedAtProfit(order.orderHash); return; } emit LogErrorWithHintBytes32(order.orderHash, "MKernel::processTradeForStopProfit", "NO_ACTION_PERFORMED"); } function _performOrderLiquidation(Order _order) internal { uint tradeAmount = initialTradeAmount[_order.orderHash]; uint valueToRepay = add(_order.principalAmount, _order.premium); uint valueToRepayWithFee = add(valueToRepay, _order.fee); uint principalFromTrade = 0; uint principalFromCollateral = 0; uint principalNeededFromCollateral = 0; uint collateralLeft = 0; uint userProfit = 0; uint totalPrincipalAcquired = 0; uint orderFee = 0; (principalFromTrade,) = _tradeWithFixedInput(_order, _order.trade.tradeToken, _order.principalToken, tradeAmount); if(principalFromTrade >= valueToRepayWithFee) { userProfit = sub(principalFromTrade, valueToRepayWithFee); orderFee = _order.fee; _performSettlement(_order, valueToRepay, _order.premium, 0, _order.collateralAmount, userProfit, orderFee); } else { principalNeededFromCollateral = sub(valueToRepayWithFee, principalFromTrade); if (_order.collateralToken == _order.principalToken) { principalFromCollateral = principalNeededFromCollateral; if(_order.collateralAmount >= principalNeededFromCollateral) { collateralLeft = sub(_order.collateralAmount, principalNeededFromCollateral); } } else { (principalFromCollateral, collateralLeft) = _tradeWithFixedOutput(_order, _order.collateralToken, _order.principalToken, _order.collateralAmount, principalNeededFromCollateral); } if(principalFromCollateral >= principalNeededFromCollateral) { orderFee = _order.fee; _performSettlement(_order, valueToRepay, _order.premium, 0, collateralLeft, 0, orderFee); } else { totalPrincipalAcquired = add(principalFromTrade, principalFromCollateral); _performSettlementAfterAllPossibleLiquidations(_order, totalPrincipalAcquired); } } } function _tradeWithFixedInput(Order _order, address _srcToken, address _destToken, uint _srcTokenValue) internal returns (uint _destTokenValue, uint _srcTokenValueLeft) { ExchangeConnector exchangeConnector = ExchangeConnector(_order.trade.exchangeConnector); return exchangeConnector.tradeWithInputFixed( escrow, _srcToken, _destToken, _srcTokenValue ); } function _tradeWithFixedOutput(Order _order, address _srcToken, address _destToken, uint _srcTokenValue, uint _maxDestTokenValue) internal returns (uint _destTokenValue, uint _srcTokenValueLeft) { ExchangeConnector exchangeConnector = ExchangeConnector(_order.trade.exchangeConnector); return exchangeConnector.tradeWithOutputFixed( escrow, _srcToken, _destToken, _srcTokenValue, _maxDestTokenValue ); } function _isTradeFeasible(Order _order, address _srcToken, address _destToken, uint _srcTokenValue) internal view returns (bool) { ExchangeConnector exchangeConnector = ExchangeConnector(_order.trade.exchangeConnector); return exchangeConnector.isTradeFeasible(_srcToken, _destToken, _srcTokenValue); } function _performSettlementAfterAllPossibleLiquidations ( Order _order, uint _totalPrincipalAcquired ) internal { uint valueToRepay = add(_order.principalAmount, _order.premium); if(_totalPrincipalAcquired >= valueToRepay) { _performSettlement(_order, valueToRepay, _order.premium, 0, 0, 0, sub(_totalPrincipalAcquired, valueToRepay)); } else if((_totalPrincipalAcquired < valueToRepay) && (_totalPrincipalAcquired >= _order.principalAmount)) { _performSettlement(_order, _totalPrincipalAcquired, sub(_totalPrincipalAcquired, _order.principalAmount), 0, 0, 0, 0); } else { _performSettlement(_order, _totalPrincipalAcquired, 0, sub(_order.principalAmount, _totalPrincipalAcquired), 0, 0, 0); } } function _performSettlement ( Order _order, uint _valueRepaid, uint _reserveProfit, uint _reserveLoss, uint _collateralLeft, uint _userProfit, uint _fee ) internal { uint closingFromPrincipal = 0; uint userEarnings = _userProfit; if(_fee > 0){ escrow.transfer(_order.principalToken, feeWallet, _fee); } reserve.lock(_order.principalToken, escrow, _valueRepaid, _reserveProfit, _reserveLoss); if(_collateralLeft > 0) { escrow.transfer(_order.collateralToken, _order.account, _collateralLeft); } if(_userProfit > 0) { if(_order.trade.closingToken == _order.principalToken || !_isTradeFeasible(_order, _order.principalToken, _order.trade.closingToken, _userProfit)) { escrow.transfer(_order.principalToken, _order.account, _userProfit); } else { (closingFromPrincipal,) = _tradeWithFixedInput(_order, _order.principalToken, _order.trade.closingToken, _userProfit); escrow.transfer(_order.trade.closingToken, _order.account, closingFromPrincipal); userEarnings = closingFromPrincipal; } } emit LogOrderSettlement(_order.orderHash, _valueRepaid, _reserveProfit, _reserveLoss, _collateralLeft, userEarnings, _fee); } function _isPositionAboveStopLoss(Order _order, uint[2] _tokenPrices, uint _bufferInPrincipal) internal view returns (bool) { uint principalPerCollateral = _tokenPrices[0]; uint principalPerTrade = _tokenPrices[1]; uint tradeAmount = initialTradeAmount[_order.orderHash]; uint valueToRepayWithFee = add(add(_order.principalAmount, _order.premium), _order.fee); uint totalCollateralValueInPrincipal = div(mul(_order.collateralAmount, principalPerCollateral), WAD); uint totalTradeValueInPrincipal = div(mul(tradeAmount, principalPerTrade), WAD); uint bufferValue = div(mul(_order.principalAmount, _bufferInPrincipal), WAD); uint minValueReq = div(mul(_order.trade.stopLoss, totalCollateralValueInPrincipal), WAD); if(add(valueToRepayWithFee, bufferValue) >= totalTradeValueInPrincipal && sub(add(valueToRepayWithFee, bufferValue), totalTradeValueInPrincipal) >= minValueReq) { return false; } return true; } function _isPositionAboveStopProfit(Order _order, uint[2] _tokenPrices, uint _bufferInPrincipal) internal view returns (bool) { if(_order.trade.stopProfit == 0) { return false; } else { uint principalPerTrade = _tokenPrices[1]; uint tradeAmount = initialTradeAmount[_order.orderHash]; uint valueToRepayWithFee = add(add(_order.principalAmount, _order.premium), _order.fee); uint totalTradeValueInPrincipal = div(mul(tradeAmount, principalPerTrade), WAD); uint stopProfitValue = div(mul(_order.principalAmount, _order.trade.stopProfit), WAD); uint bufferValue = div(mul(_order.principalAmount, _bufferInPrincipal), WAD); if(totalTradeValueInPrincipal >= add(add(valueToRepayWithFee, stopProfitValue), bufferValue)) { return true; } return false; } } function _generateLiquidateOrderHash ( bytes32 _orderHash ) internal view returns (bytes32 _liquidateOrderHash) { return keccak256( abi.encodePacked( address(this), _orderHash, "CANCEL_MKERNEL_ORDER" ) ); } 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.trade.closingToken == address(0) || _order.trade.tradeToken == address(0) || (_order.trade.tradeToken == _order.principalToken) || _order.trade.exchangeConnector == address(0) || _order.principalAmount == 0 || _order.collateralAmount == 0 || _order.premium == 0 || _order.expirationTimestamp <= _order.createdTimestamp || _order.salt == 0) { return false; } return true; } function _composeOrder ( address[6] _orderAddresses, uint[8] _orderValues ) internal view returns (Order _order) { Trade memory trade = _composeTrade(_orderAddresses[4], _orderAddresses[5], _orderValues[6], _orderValues[7]); 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), trade: trade }); order.orderHash = _generateOrderHash(order); return order; } function _composeTrade ( address _tradeToken, address _closingToken, uint _stopProfit, uint _stopLoss ) internal pure returns (Trade _trade) { _trade = Trade({ tradeToken: _tradeToken, closingToken: _closingToken, stopProfit: _stopProfit, stopLoss: _stopLoss, exchangeConnector: address(0) }); } function _generateOrderHash(Order _order) internal view returns (bytes32 _orderHash) { return keccak256( abi.encodePacked( address(this), _generateOrderHash1(_order), _generateOrderHash2(_order) ) ); } function _generateOrderHash1(Order _order) internal view returns (bytes32 _orderHash1) { 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 _generateOrderHash2(Order _order) internal view returns (bytes32 _orderHash2) { return keccak256( abi.encodePacked( address(this), _order.trade.tradeToken, _order.trade.closingToken, _order.trade.stopProfit, _order.trade.stopLoss, _order.salt ) ); } 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 getTrade(bytes32 _orderHash) public view returns ( address _tradeToken, address _closingToken, address _initExchangeConnector, uint _stopProfit, uint _stopLoss ) { Order memory order = hashToOrder[_orderHash]; return ( order.trade.tradeToken, order.trade.closingToken, order.trade.exchangeConnector, order.trade.stopProfit, order.trade.stopLoss ); } function getOrdersForAccount(address _account) public view returns ( bytes32[] ) { return accountToOrders[_account]; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"constant":false,"inputs":[],"name":"stop","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":"","type":"bytes32"}],"name":"initialTradeAmount","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":"","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":"","type":"bytes32"}],"name":"isLiquidated","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_orderHash","type":"bytes32"},{"name":"_exchangeConnector","type":"address"}],"name":"processTradeForExpiry","outputs":[],"payable":false,"stateMutability":"nonpayable","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":false,"inputs":[{"name":"_orderAddresses","type":"address[6]"},{"name":"_orderValues","type":"uint256[8]"},{"name":"_exchangeConnector","type":"address"},{"name":"_signature","type":"bytes"}],"name":"createOrder","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"accountFactory","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","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":"_orderHash","type":"bytes32"},{"name":"_exchangeConnector","type":"address"},{"name":"_tokenPrices","type":"uint256[2]"},{"name":"_bufferInPrincipal","type":"uint256"}],"name":"processTradeForStopLoss","outputs":[],"payable":false,"stateMutability":"nonpayable","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":"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":"_orderHash","type":"bytes32"}],"name":"getTrade","outputs":[{"name":"_tradeToken","type":"address"},{"name":"_closingToken","type":"address"},{"name":"_initExchangeConnector","type":"address"},{"name":"_stopProfit","type":"uint256"},{"name":"_stopLoss","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"orders","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","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":"_orderHash","type":"bytes32"},{"name":"_exchangeConnector","type":"address"},{"name":"_tokenPrices","type":"uint256[2]"},{"name":"_bufferInPrincipal","type":"uint256"}],"name":"processTradeForStopProfit","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"},{"components":[{"name":"tradeToken","type":"address"},{"name":"closingToken","type":"address"},{"name":"exchangeConnector","type":"address"},{"name":"stopProfit","type":"uint256"},{"name":"stopLoss","type":"uint256"}],"name":"trade","type":"tuple"},{"name":"principalAmount","type":"uint256"},{"name":"collateralAmount","type":"uint256"},{"name":"premium","type":"uint256"},{"name":"expirationTimestamp","type":"uint256"},{"name":"duration","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":false,"inputs":[{"name":"_orderHash","type":"bytes32"},{"name":"_exchangeConnector","type":"address"},{"name":"_signature","type":"bytes"}],"name":"liquidateOrder","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"feeWallet","outputs":[{"name":"","type":"address"}],"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"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"orderHash","type":"bytes32"},{"indexed":false,"name":"tradeAmount","type":"uint256"},{"indexed":false,"name":"expirationTimestamp","type":"uint256"}],"name":"LogOrderCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"orderHash","type":"bytes32"}],"name":"LogOrderLiquidatedByUser","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"orderHash","type":"bytes32"}],"name":"LogOrderStoppedAtProfit","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":true,"name":"orderHash","type":"bytes32"}],"name":"LogNoActionPerformed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"orderHash","type":"bytes32"},{"indexed":false,"name":"valueRepaid","type":"uint256"},{"indexed":false,"name":"reserveProfit","type":"uint256"},{"indexed":false,"name":"reserveLoss","type":"uint256"},{"indexed":false,"name":"collateralLeft","type":"uint256"},{"indexed":false,"name":"userProfit","type":"uint256"},{"indexed":false,"name":"fee","type":"uint256"}],"name":"LogOrderSettlement","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
60806040526001805460a060020a60ff021916905534801561002057600080fd5b5060405160a08062005b488339810160408181528251602084015191840151606085015160809095015160018054600160a060020a031916339081179091559295939491939290917fce241d7ca1f669fee44b6fc00b8eba2df3bb514eed0f6f668f8f89096e81ed9490600090a260028054600160a060020a0319908116600160a060020a03978816179091556003805482169587169590951790945560048054851693861693909317909255600580548416918516919091179055600680549092169216919091179055615a4d80620000fb6000396000f3006080604052600436106101875763ffffffff60e060020a60003504166307da68f5811461018c57806313af4035146101a3578063162cfaac146101c457806320e3dbd4146101ee5780632fcdb8dd1461020f578063359abaed1461023b578063431025e1146102ac5780634459c9a3146102c45780635778472a146102e85780636722232614610368578063687cd9c11461039a5780636dec3260146103cb57806375f12b21146103ef57806379502c55146104045780637959f20a146104195780637a9e5e4b146104425780637bea0d1c146104635780638723555e146104785780638da5cb5b1461049057806390d49b9d146104a55780639cecc80a146104c6578063a3b13799146104e7578063a85c38ef14610539578063addc1a7614610551578063be9a655514610572578063bf7e214f14610587578063c046229e1461059c578063c10c3546146105c5578063c559f686146105e6578063cd3293de146106bf578063e2fdcc17146106d4578063ebac0bd9146106e9578063f25f4b561461071a575b600080fd5b34801561019857600080fd5b506101a161072f565b005b3480156101af57600080fd5b506101a1600160a060020a0360043516610813565b3480156101d057600080fd5b506101dc6004356108bd565b60408051918252519081900360200190f35b3480156101fa57600080fd5b506101a1600160a060020a03600435166108cf565b34801561021b57600080fd5b506102276004356109ef565b604080519115158252519081900360200190f35b34801561024757600080fd5b5061025c600160a060020a0360043516610a04565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610298578181015183820152602001610280565b505050509050019250505060405180910390f35b3480156102b857600080fd5b50610227600435610a72565b3480156102d057600080fd5b506101a1600435600160a060020a0360243516610a87565b3480156102f457600080fd5b50610300600435611185565b60408051600160a060020a039c8d1681529a8c1660208c0152988b168a8a0152969099166060890152608088019490945260a087019290925260c086015260e08501526101008401526101208301939093526101408201929092529051908190036101600190f35b34801561037457600080fd5b506101a1600460c46101c435600160a060020a03166101e43560248101908401356113fd565b3480156103a657600080fd5b506103af612294565b60408051600160a060020a039092168252519081900360200190f35b3480156103d757600080fd5b506101dc600160a060020a03600435166024356122a3565b3480156103fb57600080fd5b506102276122d3565b34801561041057600080fd5b506103af6122f4565b34801561042557600080fd5b506101a1600435600160a060020a03602435166044608435612303565b34801561044e57600080fd5b506101a1600160a060020a0360043516612b91565b34801561046f57600080fd5b5061025c612c37565b34801561048457600080fd5b50610227600435612c90565b34801561049c57600080fd5b506103af612ca5565b3480156104b157600080fd5b506101a1600160a060020a0360043516612cb4565b3480156104d257600080fd5b506101a1600160a060020a0360043516612dd4565b3480156104f357600080fd5b506104ff600435612ef4565b60408051600160a060020a039687168152948616602086015292909416838301526060830152608082019290925290519081900360a00190f35b34801561054557600080fd5b506101dc60043561301a565b34801561055d57600080fd5b506101a1600160a060020a0360043516613039565b34801561057e57600080fd5b506101a1613159565b34801561059357600080fd5b506103af613226565b3480156105a857600080fd5b506101a1600435600160a060020a03602435166044608435613235565b3480156105d157600080fd5b506101a1600160a060020a0360043516613ada565b3480156105f257600080fd5b506105fe600435613bfa565b604051808f600160a060020a0316600160a060020a031681526020018e600160a060020a0316600160a060020a031681526020018d600160a060020a0316600160a060020a031681526020018c600160a060020a0316600160a060020a031681526020018b81526020018a815260200189815260200188815260200187815260200186815260200185815260200184815260200183815260200182600019166000191681526020019e50505050505050505050505050505060405180910390f35b3480156106cb57600080fd5b506103af613cb8565b3480156106e057600080fd5b506103af613cc7565b3480156106f557600080fd5b506101a1600480359060248035600160a060020a031691604435918201910135613cd6565b34801561072657600080fd5b506103af6145c3565b61074533600035600160e060020a0319166145d2565b1515610789576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020615862833981519152604482015290519081900360640190fd5b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a450506001805474ff0000000000000000000000000000000000000000191674010000000000000000000000000000000000000000179055565b61082933600035600160e060020a0319166145d2565b151561086d576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020615862833981519152604482015290519081900360640190fd5b60018054600160a060020a031916600160a060020a0383811691909117918290556040519116907fce241d7ca1f669fee44b6fc00b8eba2df3bb514eed0f6f668f8f89096e81ed9490600090a250565b600b6020526000908152604090205481565b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a461093633600035600160e060020a0319166145d2565b151561097a576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020615862833981519152604482015290519081900360640190fd5b82600160a060020a03811615156109c9576040805160e560020a62461bcd02815260206004820152601860248201526000805160206159c2833981519152604482015290519081900360640190fd5b505060068054600160a060020a031916600160a060020a03939093169290921790915550565b600d6020526000908152604090205460ff1681565b600160a060020a0381166000908152600a6020908152604091829020805483518184028101840190945280845260609392830182828015610a6557602002820191906000526020600020905b81548152600190910190602001808311610a50575b505050505090505b919050565b600c6020526000908152604090205460ff1681565b610a8f61579a565b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a46006546040805160e060020a639c14ee290281523360048201529051600160a060020a0390921691639c14ee29916024808201926020929091908290030181600087803b158015610b3057600080fd5b505af1158015610b44573d6000803e3d6000fd5b505050506040513d6020811015610b5a57600080fd5b50511515610ba0576040805160e560020a62461bcd02815260206004820181905260248201526000805160206159e2833981519152604482015290519081900360640190fd5b83600160a060020a0381161515610bef576040805160e560020a62461bcd02815260206004820152601860248201526000805160206159c2833981519152604482015290519081900360640190fd5b60008681526009602052604090205460ff161515610c6d5760408051818152601e818301526000805160206158e2833981519152606082015260806020820181905260149082015260008051602061598283398151915260a0820152905187916000805160206158a2833981519152919081900360c00190a261117d565b6000868152600c602052604090205460ff1615610cea5760408051818152601e818301526000805160206158e2833981519152606082015260806020820181905260189082015260008051602061584283398151915260a0820152905187916000805160206158a2833981519152919081900360c00190a261117d565b6000868152600d602052604090205460ff1615610d675760408051818152601e818301526000805160206158e2833981519152606082015260806020820181905260179082015260008051602061588283398151915260a0820152905187916000805160206158a2833981519152919081900360c00190a261117d565b600086815260086020818152604080842081516101c0810183528154600160a060020a039081168252600183015481168286015260028084015482168386015260038401548216606080850191909152855160a081810188526004808801548616835260058801548616838b0152600788015493830193909352988601546080828101919091528501818152600987015499860199909952600a86015460c0860152600b8087015460e0870152600c870154610100870152600d870154610120870152600e870154610140870152600f87015461016087015260108701546101808701526011909601546101a08601528e8416908701528e8952938652848820549651519054855160e060020a6370a08231028152908316948101949094529351919a50949592909416936370a082319360248084019491938390030190829087803b158015610eb657600080fd5b505af1158015610eca573d6000803e3d6000fd5b505050506040513d6020811015610ee057600080fd5b50511015610f5e5760408051818152601e818301526000805160206158e2833981519152606082015260806020820181905260249082015260008051602061594283398151915260a082015260e060020a6343524f570260c0820152905187916000805160206158a2833981519152919081900360e00190a261117d565b60c084015160608501516002546040805160e060020a6370a08231028152600160a060020a039283166004820152905191909216916370a082319160248083019260209291908290030181600087803b158015610fba57600080fd5b505af1158015610fce573d6000803e3d6000fd5b505050506040513d6020811015610fe457600080fd5b505110156110665760408051818152601e818301526000805160206158e2833981519152606082015260806020820181905260299082015260008051602061596283398151915260a0820152600080516020615a0283398151915260c0820152905187916000805160206158a2833981519152919081900360e00190a261117d565b836101000151421115611106576101a08401516000908152600d60205260409020805460ff1916600117905561109b846146db565b6101a08401516040805160208082526017908201527f4d4b45524e454c5f4455455f444154455f5041535345440000000000000000008183015290517f98e393d0760ecfe8e3907134d357e8a4fa5b37e364c3baeb0b059a98317638c49181900360600190a261117d565b6101a084015160408051818152601e818301526000805160206158e283398151915260608201526080602082018190526013908201527f4e4f5f414354494f4e5f504552464f524d45440000000000000000000000000060a082015290516000805160206158a28339815191529181900360c00190a25b505050505050565b600080600080600080600080600080600061119e61579a565b600860008e600019166000191681526020019081526020016000206101c060405190810160405290816000820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016001820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016002820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016003820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016004820160a060405190810160405290816000820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016001820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016002820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a0316815260200160038201548152602001600482015481525050815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201548152602001600d8201548152602001600e8201548152602001600f8201548152602001601082015481526020016011820154600019166000191681525050905080600001518160200151826040015183606001518460a001518560c001518660e001518761010001518861014001518961016001518a61018001519b509b509b509b509b509b509b509b509b509b509b505091939597999b90929496989a50565b61140561579a565b604080513480825260208201838152369383018490526000936004359360243593849386933393600160e060020a03198a351693928a929190606082018484808284376040519201829003965090945050505050a46006546040805160e060020a639c14ee290281523360048201529051600160a060020a0390921691639c14ee29916024808201926020929091908290030181600087803b1580156114aa57600080fd5b505af11580156114be573d6000803e3d6000fd5b505050506040513d60208110156114d457600080fd5b5051151561151a576040805160e560020a62461bcd02815260206004820181905260248201526000805160206159e2833981519152604482015290519081900360640190fd5b60015474010000000000000000000000000000000000000000900460ff161561158d576040805160e560020a62461bcd02815260206004820152601960248201527f445353746f703a3a5f20464541545552455f53544f5050454400000000000000604482015290519081900360640190fd5b86600160a060020a03811615156115dc576040805160e560020a62461bcd02815260206004820152601860248201526000805160206159c2833981519152604482015290519081900360640190fd5b6040805160c0818101909252611624918c90600690839083908082843750506040805161010081810190925293508e92506008915083908390808284375061485b9350505050565b9450611665856101a0015188888080601f01602080910402602001604051908101604052809392919081815260200183838082843750614950945050505050565b6080860151600160a060020a03808b16604090920191909152602087015191955080861691161461170b576101a0850151604080518181526014818301526000805160206159a283398151915260608201526080602082018190526018908201527f5349474e45525f4e4f545f4f524445525f43524541544f52000000000000000060a082015290516000805160206158a28339815191529181900360c00190a2612288565b6101a085015160009081526009602052604090205460ff16156117a2576101a08501516040805181815260148183018190526000805160206159a283398151915260608301526080602083018190528201527f4f524445525f414c52454144595f45584953545300000000000000000000000060a082015290516000805160206158a28339815191529181900360c00190a2612288565b6003548551604080517f25ca4c9c000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152905191909216916325ca4c9c9160248083019260209291908290030181600087803b15801561180c57600080fd5b505af1158015611820573d6000803e3d6000fd5b505050506040513d602081101561183657600080fd5b505115156118b9576101a0850151604080518181526014818301526000805160206159a283398151915260608201526080602082018190526015908201527f494e56414c49445f4f524445525f4143434f554e54000000000000000000000060a082015290516000805160206158a28339815191529181900360c00190a2612288565b8460000151600160a060020a0316634209fff1856040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b15801561191857600080fd5b505af115801561192c573d6000803e3d6000fd5b505050506040513d602081101561194257600080fd5b505115156119eb576101a0850151604080518181526014818301526000805160206159a283398151915260608201526080602082018190526022908201527f5349474e45525f4e4f545f415554484f52495a45445f574954485f4143434f5560a08201527f4e5400000000000000000000000000000000000000000000000000000000000060c082015290516000805160206158a28339815191529181900360e00190a2612288565b6119f485614972565b1515611a75576101a0850151604080518181526014818301526000805160206159a283398151915260608201526080602082018190526018908201527f494e56414c49445f4f524445525f504152414d4554455253000000000000000060a082015290516000805160206158a28339815191529181900360c00190a2612288565b8460c001518560600151600160a060020a03166370a0823187600001516040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b158015611add57600080fd5b505af1158015611af1573d6000803e3d6000fd5b505050506040513d6020811015611b0757600080fd5b50511015611bb0576101a0850151604080518181526014818301526000805160206159a283398151915260608201526080602082018190526022908201527f494e53554646494349454e545f434f4c4c41544552414c5f494e5f4143434f5560a08201527f4e5400000000000000000000000000000000000000000000000000000000000060c082015290516000805160206158a28339815191529181900360e00190a2612288565b8460a001518560400151600160a060020a03166370a08231600460009054906101000a9004600160a060020a0316600160a060020a031663e2fdcc176040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015611c1b57600080fd5b505af1158015611c2f573d6000803e3d6000fd5b505050506040513d6020811015611c4557600080fd5b50516040805160e060020a63ffffffff8516028152600160a060020a0390921660048301525160248083019260209291908290030181600087803b158015611c8c57600080fd5b505af1158015611ca0573d6000803e3d6000fd5b505050506040513d6020811015611cb657600080fd5b50511015611d39576101a0850151604080518181526014818301526000805160206159a28339815191526060820152608060208201819052601d908201527f494e53554646494349454e545f46554e44535f494e5f5245534552564500000060a082015290516000805160206158a28339815191529181900360c00190a2612288565b611d558586604001518760800151600001518860a00151614a95565b1515611dd6576101a0850151604080518181526014818301526000805160206159a283398151915260608201526080602082018190526012908201527f54524144455f4e4f545f4645415349424c45000000000000000000000000000060a082015290516000805160206158a28339815191529181900360c00190a2612288565b6007856101a0015190806001815401808255809150509060018203906000526020600020016000909192909190915090600019169055508460086000876101a001516000191660001916815260200190815260200160002060008201518160000160006101000a815481600160a060020a030219169083600160a060020a0316021790555060208201518160010160006101000a815481600160a060020a030219169083600160a060020a0316021790555060408201518160020160006101000a815481600160a060020a030219169083600160a060020a0316021790555060608201518160030160006101000a815481600160a060020a030219169083600160a060020a0316021790555060808201518160040160008201518160000160006101000a815481600160a060020a030219169083600160a060020a0316021790555060208201518160010160006101000a815481600160a060020a030219169083600160a060020a0316021790555060408201518160020160006101000a815481600160a060020a030219169083600160a060020a031602179055506060820151816003015560808201518160040155505060a0820151816009015560c082015181600a015560e082015181600b015561010082015181600c015561012082015181600d015561014082015181600e015561016082015181600f015561018082015181601001556101a08201518160110190600019169055905050600160096000876101a001516000191660001916815260200190815260200160002060006101000a81548160ff021916908315150217905550600a60008660000151600160a060020a0316600160a060020a03168152602001908152602001600020856101a001519080600181540180825580915050906001820390600052602060002001600090919290919091509060001916905550600260009054906101000a9004600160a060020a0316600160a060020a0316635e61e1c886600001518760600151600260009054906101000a9004600160a060020a03168960c001516040518563ffffffff1660e060020a0281526004018085600160a060020a0316600160a060020a0316815260200184600160a060020a0316600160a060020a0316815260200183600160a060020a0316600160a060020a03168152602001828152602001945050505050600060405180830381600087803b15801561215557600080fd5b505af1158015612169573d6000803e3d6000fd5b5050600480546040808a015160025460a08c015183517f8bfb07c9000000000000000000000000000000000000000000000000000000008152600160a060020a039384169681019690965290821660248601526044850152905191169350638bfb07c99250606480830192600092919082900301818387803b1580156121ee57600080fd5b505af1158015612202573d6000803e3d6000fd5b505050506122228586604001518760800151600001518860a00151614b48565b506101a0860180516000908152600b602090815260408083209490945591518082529083902054610100890151845191825292810192909252825190927fea0bf587ab60e35e1551a895f638f97223b5471e71aef9e3102dfe8ceb87dc01928290030190a25b50505050505050505050565b600354600160a060020a031681565b600a602052816000526040600020818154811015156122be57fe5b90600052602060002001600091509150505481565b60015474010000000000000000000000000000000000000000900460ff1681565b600654600160a060020a031681565b61230b61579a565b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a46006546040805160e060020a639c14ee290281523360048201529051600160a060020a0390921691639c14ee29916024808201926020929091908290030181600087803b1580156123ac57600080fd5b505af11580156123c0573d6000803e3d6000fd5b505050506040513d60208110156123d657600080fd5b5051151561241c576040805160e560020a62461bcd02815260206004820181905260248201526000805160206159e2833981519152604482015290519081900360640190fd5b85600160a060020a038116151561246b576040805160e560020a62461bcd02815260206004820152601860248201526000805160206159c2833981519152604482015290519081900360640190fd5b60008881526009602052604090205460ff1615156124ea576040805181815260208183018190526000805160206159228339815191526060830152608090820181905260149082015260008051602061598283398151915260a0820152905189916000805160206158a2833981519152919081900360c00190a2612b87565b6000888152600c602052604090205460ff1615612568576040805181815260208183018190526000805160206159228339815191526060830152608090820181905260189082015260008051602061584283398151915260a0820152905189916000805160206158a2833981519152919081900360c00190a2612b87565b6000888152600d602052604090205460ff16156125e6576040805181815260208183018190526000805160206159228339815191526060830152608090820181905260179082015260008051602061588283398151915260a0820152905189916000805160206158a2833981519152919081900360c00190a2612b87565b6008600089600019166000191681526020019081526020016000206101c060405190810160405290816000820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016001820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016002820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016003820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016004820160a060405190810160405290816000820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016001820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016002820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a0316815260200160038201548152602001600482015481525050815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201548152602001600d8201548152602001600e8201548152602001600f8201548152602001601082015481526020016011820154600019166000191681525050935086846080015160400190600160a060020a03169081600160a060020a031681525050600b6000896000191660001916815260200190815260200160002054846080015160000151600160a060020a03166370a08231600260009054906101000a9004600160a060020a03166040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b15801561289a57600080fd5b505af11580156128ae573d6000803e3d6000fd5b505050506040513d60208110156128c457600080fd5b50511015612943576040805181815260208183018190526000805160206159228339815191526060830152608090820181905260249082015260008051602061594283398151915260a082015260e060020a6343524f570260c0820152905189916000805160206158a2833981519152919081900360e00190a2612b87565b60c084015160608501516002546040805160e060020a6370a08231028152600160a060020a039283166004820152905191909216916370a082319160248083019260209291908290030181600087803b15801561299f57600080fd5b505af11580156129b3573d6000803e3d6000fd5b505050506040513d60208110156129c957600080fd5b50511015612a4c576040805181815260208183018190526000805160206159228339815191526060830152608090820181905260299082015260008051602061596283398151915260a0820152600080516020615a0283398151915260c0820152905189916000805160206158a2833981519152919081900360e00190a2612b87565b604080518082018252612a769186919089906002908390839080828437508b9350614c1092505050565b1515612b0f576101a08401516000908152600d60205260409020805460ff19166001179055612aa4846146db565b6101a08401516040805160208082526014908201527f4d4b45524e454c5f4f524445525f554e534146450000000000000000000000008183015290517f98e393d0760ecfe8e3907134d357e8a4fa5b37e364c3baeb0b059a98317638c49181900360600190a2612b87565b6101a0840151604080518181526020818301819052600080516020615922833981519152606083015260809082018190526013908201527f4e4f5f414354494f4e5f504552464f524d45440000000000000000000000000060a082015290516000805160206158a28339815191529181900360c00190a25b5050505050505050565b612ba733600035600160e060020a0319166145d2565b1515612beb576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020615862833981519152604482015290519081900360640190fd5b60008054600160a060020a031916600160a060020a03838116919091178083556040519116917f1abebea81bfa2637f28358c371278fb15ede7ea8dd28d2e03b112ff6d936ada491a250565b60606007805480602002602001604051908101604052809291908181526020018280548015612c8657602002820191906000526020600020905b81548152600190910190602001808311612c71575b5050505050905090565b60096020526000908152604090205460ff1681565b600154600160a060020a031681565b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a4612d1b33600035600160e060020a0319166145d2565b1515612d5f576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020615862833981519152604482015290519081900360640190fd5b82600160a060020a0381161515612dae576040805160e560020a62461bcd02815260206004820152601860248201526000805160206159c2833981519152604482015290519081900360640190fd5b505060058054600160a060020a031916600160a060020a03939093169290921790915550565b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a4612e3b33600035600160e060020a0319166145d2565b1515612e7f576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020615862833981519152604482015290519081900360640190fd5b82600160a060020a0381161515612ece576040805160e560020a62461bcd02815260206004820152601860248201526000805160206159c2833981519152604482015290519081900360640190fd5b505060048054600160a060020a031916600160a060020a03939093169290921790915550565b6000806000806000612f0461579a565b505050600093845250506008602081815260409384902084516101c0810186528154600160a060020a0390811682526001830154811682850152600283015481168288015260038301548116606080840191909152875160a08082018a5260048601548416825260058601548416968201968752600686015490931698810198895260078501549181019182529584015460808088019182528401879052600985015492840192909252600a84015460c0840152600b84015460e0840152600c840154610100840152600d840154610120840152600e840154610140840152600f84015461016084015260108401546101808401526011909301546101a090920191909152925191519451905192519195909350565b600780548290811061302857fe5b600091825260209091200154905081565b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a46130a033600035600160e060020a0319166145d2565b15156130e4576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020615862833981519152604482015290519081900360640190fd5b82600160a060020a0381161515613133576040805160e560020a62461bcd02815260206004820152601860248201526000805160206159c2833981519152604482015290519081900360640190fd5b505060038054600160a060020a031916600160a060020a03939093169290921790915550565b61316f33600035600160e060020a0319166145d2565b15156131b3576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020615862833981519152604482015290519081900360640190fd5b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a450506001805474ff000000000000000000000000000000000000000019169055565b600054600160a060020a031681565b61323d61579a565b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a46006546040805160e060020a639c14ee290281523360048201529051600160a060020a0390921691639c14ee29916024808201926020929091908290030181600087803b1580156132de57600080fd5b505af11580156132f2573d6000803e3d6000fd5b505050506040513d602081101561330857600080fd5b5051151561334e576040805160e560020a62461bcd02815260206004820181905260248201526000805160206159e2833981519152604482015290519081900360640190fd5b85600160a060020a038116151561339d576040805160e560020a62461bcd02815260206004820152601860248201526000805160206159c2833981519152604482015290519081900360640190fd5b60008881526009602052604090205460ff1615156134295760408051818152602281830152600080516020615902833981519152606082015260f260020a611a5d02608082015260a06020820181905260149082015260008051602061598283398151915260c0820152905189916000805160206158a2833981519152919081900360e00190a2612b87565b6000888152600c602052604090205460ff16156134b45760408051818152602281830152600080516020615902833981519152606082015260f260020a611a5d02608082015260a06020820181905260189082015260008051602061584283398151915260c0820152905189916000805160206158a2833981519152919081900360e00190a2612b87565b6000888152600d602052604090205460ff161561353f5760408051818152602281830152600080516020615902833981519152606082015260f260020a611a5d02608082015260a06020820181905260179082015260008051602061588283398151915260c0820152905189916000805160206158a2833981519152919081900360e00190a2612b87565b6008600089600019166000191681526020019081526020016000206101c060405190810160405290816000820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016001820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016002820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016003820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016004820160a060405190810160405290816000820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016001820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016002820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a0316815260200160038201548152602001600482015481525050815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201548152602001600d8201548152602001600e8201548152602001600f8201548152602001601082015481526020016011820154600019166000191681525050935086846080015160400190600160a060020a03169081600160a060020a031681525050600b6000896000191660001916815260200190815260200160002054846080015160000151600160a060020a03166370a08231600260009054906101000a9004600160a060020a03166040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b1580156137f357600080fd5b505af1158015613807573d6000803e3d6000fd5b505050506040513d602081101561381d57600080fd5b505110156138aa5760408051818152602281830152600080516020615902833981519152606082015260f260020a611a5d02608082015260a06020820181905260249082015260008051602061594283398151915260c082015260e060020a6343524f570260e0820152905189916000805160206158a283398151915291908190036101000190a2612b87565b60c084015160608501516002546040805160e060020a6370a08231028152600160a060020a039283166004820152905191909216916370a082319160248083019260209291908290030181600087803b15801561390657600080fd5b505af115801561391a573d6000803e3d6000fd5b505050506040513d602081101561393057600080fd5b505110156139c15760408051818152602281830152600080516020615902833981519152606082015260f260020a611a5d02608082015260a06020820181905260299082015260008051602061596283398151915260c0820152600080516020615a0283398151915260e0820152905189916000805160206158a283398151915291908190036101000190a2612b87565b6040805180820182526139eb9186919089906002908390839080828437508b9350614d0692505050565b15613a4c576101a08401516000908152600c60205260409020805460ff19166001179055613a18846146db565b6101a08401516040517fc614d231c29c73ae067f16cd5460d0050c98401008b3cce99b3abb37302e548590600090a2612b87565b6101a084015160408051818152602281830152600080516020615902833981519152606082015260f260020a611a5d02608082015260a0602082018190526013908201527f4e4f5f414354494f4e5f504552464f524d45440000000000000000000000000060c082015290516000805160206158a28339815191529181900360e00190a25050505050505050565b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a4613b4133600035600160e060020a0319166145d2565b1515613b85576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020615862833981519152604482015290519081900360640190fd5b82600160a060020a0381161515613bd4576040805160e560020a62461bcd02815260206004820152601860248201526000805160206159c2833981519152604482015290519081900360640190fd5b505060028054600160a060020a031916600160a060020a03939093169290921790915550565b6008602081815260009283526040928390208054600182015460028301546003840154875160a0810189526004860154600160a060020a03908116825260058701548116978201979097526006860154871698810198909852600785015460608901529584015460808801526009840154600a850154600b860154600c870154600d880154600e890154600f8a015460108b01546011909b0154998c169d988c169c978c169b9097169997989597949693959294919390929091908e565b600454600160a060020a031681565b600254600160a060020a031681565b600080613ce161579a565b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a46006546040805160e060020a639c14ee290281523360048201529051600160a060020a0390921691639c14ee29916024808201926020929091908290030181600087803b158015613d8257600080fd5b505af1158015613d96573d6000803e3d6000fd5b505050506040513d6020811015613dac57600080fd5b50511515613df2576040805160e560020a62461bcd02815260206004820181905260248201526000805160206159e2833981519152604482015290519081900360640190fd5b87600160a060020a0381161515613e41576040805160e560020a62461bcd02815260206004820152601860248201526000805160206159c2833981519152604482015290519081900360640190fd5b60008a81526009602052604090205460ff161515613ebf57604080518181526017818301526000805160206158c2833981519152606082015260806020820181905260149082015260008051602061598283398151915260a082015290518b916000805160206158a2833981519152919081900360c00190a2612288565b60008a8152600c602052604090205460ff1615613f3c57604080518181526017818301526000805160206158c2833981519152606082015260806020820181905260189082015260008051602061584283398151915260a082015290518b916000805160206158a2833981519152919081900360c00190a2612288565b60008a8152600d602052604090205460ff1615613fb8576040805181815260178183018190526000805160206158c2833981519152606083015260806020830181905282015260008051602061588283398151915260a082015290518b916000805160206158a2833981519152919081900360c00190a2612288565b613fc18a614de3565b9550613ffd8689898080601f01602080910402602001604051908101604052809392919081815260200183838082843750614950945050505050565b9450600860008b600019166000191681526020019081526020016000206101c060405190810160405290816000820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016001820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016002820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016003820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016004820160a060405190810160405290816000820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016001820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016002820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a0316815260200160038201548152602001600482015481525050815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201548152602001600d8201548152602001600e8201548152602001600f8201548152602001601082015481526020016011820154600019166000191681525050935088846080015160400190600160a060020a03169081600160a060020a0316815250508360000151600160a060020a0316634209fff1866040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b15801561427e57600080fd5b505af1158015614292573d6000803e3d6000fd5b505050506040513d60208110156142a857600080fd5b5051151561434e57604080518181526017818301526000805160206158c283398151915260608201526080602082018190526022908201527f5349474e45525f4e4f545f415554484f52495a45445f574954485f4143434f5560a08201527f4e5400000000000000000000000000000000000000000000000000000000000060c082015290518b916000805160206158a2833981519152919081900360e00190a2612288565b60008a8152600b6020908152604080832054608088015151600254835160e060020a6370a08231028152600160a060020a039182166004820152935192959116936370a08231936024808201949293918390030190829087803b1580156143b457600080fd5b505af11580156143c8573d6000803e3d6000fd5b505050506040513d60208110156143de57600080fd5b5051101561445c57604080518181526017818301526000805160206158c2833981519152606082015260806020820181905260249082015260008051602061594283398151915260a082015260e060020a6343524f570260c082015290518b916000805160206158a2833981519152919081900360e00190a2612288565b60c084015160608501516002546040805160e060020a6370a08231028152600160a060020a039283166004820152905191909216916370a082319160248083019260209291908290030181600087803b1580156144b857600080fd5b505af11580156144cc573d6000803e3d6000fd5b505050506040513d60208110156144e257600080fd5b5051101561456457604080518181526017818301526000805160206158c2833981519152606082015260806020820181905260299082015260008051602061596283398151915260a0820152600080516020615a0283398151915260c082015290518b916000805160206158a2833981519152919081900360e00190a2612288565b6101a08401516000908152600c60205260409020805460ff1916600117905561458c846146db565b6040518a907f6cc69d7894fbf109ad278f7e331e91f734cd486332ee4e1eb3625bb2538eea4990600090a250505050505050505050565b600554600160a060020a031681565b6000600160a060020a0383163014156145ed575060016146d5565b600154600160a060020a038481169116141561460b575060016146d5565b600054600160a060020a03161515614625575060006146d5565b60008054604080517fb7009613000000000000000000000000000000000000000000000000000000008152600160a060020a038781166004830152306024830152600160e060020a0319871660448301529151919092169263b700961392606480820193602093909283900390910190829087803b1580156146a657600080fd5b505af11580156146ba573d6000803e3d6000fd5b505050506040513d60208110156146d057600080fd5b505190505b92915050565b600080600080600080600080600080600b60008c6101a001516000191660001916815260200190815260200160002054995061471f8b60a001518c60e00151614ea1565b9850614730898c6101600151614ea1565b9750600096506000955060009450600093506000925060009150600090506147668b8c60800151600001518d604001518d614b48565b5096508787106147a15761477a8789614eb1565b92508a6101600151905061479c8b8a8d60e0015160008f60c001518887614ec1565b61484e565b6147ab8888614eb1565b94508a60400151600160a060020a03168b60600151600160a060020a031614156147f557849550848b60c001511015156147f0576147ed8b60c0015186614eb1565b93505b614814565b61480e8b8c606001518d604001518e60c001518961524e565b90965093505b848610614838578a6101600151905061479c8b8a8d60e00151600088600087614ec1565b6148428787614ea1565b915061484e8b8361531e565b5050505050505050505050565b61486361579a565b61486b615813565b61487361579a565b608085015160a086015160c086015160e0870151614893939291906153b8565b604080516101c0810182528751600160a060020a0390811682526020808a0151821681840152898401518216838501526060808b01519092168284015260808301859052885160a084015288015160c08301529187015160e08201529086015191935090610100820190614908904290614ea1565b81526060808701516020830152608080880151604084015260a08089015192840192909252429083015260009101529050614942816153fa565b6101a0820152949350505050565b600061496b8261495f8561548a565b9063ffffffff61550116565b9392505050565b8051600090600160a060020a0316158061499757506020820151600160a060020a0316155b806149ad57506040820151600160a060020a0316155b806149c357506060820151600160a060020a0316155b806149dd5750608082015160200151600160a060020a0316155b806149f45750608082015151600160a060020a0316155b80614a1c57508160400151600160a060020a0316826080015160000151600160a060020a0316145b80614a365750608082015160400151600160a060020a0316155b80614a43575060a0820151155b80614a50575060c0820151155b80614a5d575060e0820151155b80614a72575081610180015182610100015111155b80614a805750610140820151155b15614a8d57506000610a6d565b506001919050565b608084015160409081015181517f5d0b4e5c000000000000000000000000000000000000000000000000000000008152600160a060020a0386811660048301528581166024830152604482018590529251600093831691635d0b4e5c91606480830192602092919082900301818887803b158015614b1257600080fd5b505af1158015614b26573d6000803e3d6000fd5b505050506040513d6020811015614b3c57600080fd5b50519695505050505050565b608084015160409081015160025482517f17fd9cc5000000000000000000000000000000000000000000000000000000008152600160a060020a039182166004820152868216602482015285821660448201526064810185905283516000948594938416926317fd9cc5926084808301939282900301818887803b158015614bcf57600080fd5b505af1158015614be3573d6000803e3d6000fd5b505050506040513d6040811015614bf957600080fd5b508051602090910151909890975095505050505050565b81516020808401516101a08601516000908152600b909252604082205460a087015160e088015193949385918291829182918291614c5d91614c529190614ea1565b8d6101600151614ea1565b9450614c7e614c708d60c001518a6155d6565b670de0b6b3a76400006155fe565b9350614c8d614c7087896155d6565b9250614ca0614c708d60a001518c6155d6565b9150614cb7614c708d6080015160800151866155d6565b905082614cc48684614ea1565b10158015614ce4575080614ce1614cdb8785614ea1565b85614eb1565b10155b15614cf25760009850614cf7565b600198505b50505050505050509392505050565b600080600080600080600089608001516060015160001415614d2b5760009650614dd6565b6020808a01516101a08c01516000908152600b90925260409091205460a08c015160e08d0151929850909650614d7091614d659190614ea1565b8b6101600151614ea1565b9350614d7f614c7086886155d6565b9250614d9a614c708b60a001518c60800151606001516155d6565b9150614dad614c708b60a001518a6155d6565b9050614dc2614dbc8584614ea1565b82614ea1565b8310614dd15760019650614dd6565b600096505b5050505050509392505050565b604080516c010000000000000000000000003002602080830191909152603482018490527f43414e43454c5f4d4b45524e454c5f4f524445520000000000000000000000006054830152825160488184030181526068909201928390528151600093918291908401908083835b60208310614e6f5780518252601f199092019160209182019101614e50565b5181516020939093036101000a6000190180199091169216919091179052604051920182900390912095945050505050565b808201828110156146d557600080fd5b808203828111156146d557600080fd5b60008281831115614f4b576002546040808b0151600554825160e360020a6317d57599028152600160a060020a039283166004820152908216602482015260448101879052915192169163beabacc89160648082019260009290919082900301818387803b158015614f3257600080fd5b505af1158015614f46573d6000803e3d6000fd5b505050505b600480546040808c015160025482517f106689a5000000000000000000000000000000000000000000000000000000008152600160a060020a039283169581019590955281166024850152604484018c9052606484018b9052608484018a9052905191169163106689a59160a480830192600092919082900301818387803b158015614fd657600080fd5b505af1158015614fea573d6000803e3d6000fd5b5050505060008511156150765760025460608a01518a516040805160e360020a6317d57599028152600160a060020a03938416600482015291831660248301526044820189905251919092169163beabacc891606480830192600092919082900301818387803b15801561505d57600080fd5b505af1158015615071573d6000803e3d6000fd5b505050505b60008411156151e8578860400151600160a060020a0316896080015160200151600160a060020a031614806150c057506150be898a604001518b608001516020015187614a95565b155b15615147576002546040808b01518b51825160e360020a6317d57599028152600160a060020a039283166004820152908216602482015260448101889052915192169163beabacc89160648082019260009290919082900301818387803b15801561512a57600080fd5b505af115801561513e573d6000803e3d6000fd5b505050506151e8565b61515f898a604001518b608001516020015187614b48565b5060025460808b0151602001518b516040805160e360020a6317d57599028152600160a060020a0393841660048201529183166024830152604482018590525193955091169163beabacc89160648082019260009290919082900301818387803b1580156151cc57600080fd5b505af11580156151e0573d6000803e3d6000fd5b505050508190505b6101a0890151604080518a8152602081018a9052808201899052606081018890526080810184905260a0810186905290517fd5620126c5a9c2d177d7302570339d14ed881b5f6d3fdb8f63bd6fa00601bc6b9181900360c00190a2505050505050505050565b608085015160409081015160025482517fc83ec89d000000000000000000000000000000000000000000000000000000008152600160a060020a039182166004820152878216602482015286821660448201526064810186905260848101859052835160009485949384169263c83ec89d9260a4808301939282900301818887803b1580156152dc57600080fd5b505af11580156152f0573d6000803e3d6000fd5b505050506040513d604081101561530657600080fd5b50805160209091015190999098509650505050505050565b60006153328360a001518460e00151614ea1565b905080821061535e5761535983828560e0015160008060006153548989614eb1565b614ec1565b6153b3565b808210801561537157508260a001518210155b15615394576153598383615389858760a00151614eb1565b600080600080614ec1565b6153b3838360006153a98760a0015187614eb1565b6000806000614ec1565b505050565b6153c0615813565b506040805160a081018252600160a060020a0395861681529390941660208401526000938301939093526060820152608081019190915290565b60003061540683615613565b61540f846156ef565b604080516c01000000000000000000000000600160a060020a0390951694909402602080860191909152603485019390935260548085019290925280518085039092018252607490930192839052805190929182919084019080838360208310614e6f5780518252601f199092019160209182019101614e50565b604080517f19457468657265756d205369676e6564204d6573736167653a0a333200000000602080830191909152603c80830185905283518084039091018152605c9092019283905281516000939182919084019080838360208310614e6f5780518252601f199092019160209182019101614e50565b6000806000808451604114151561551b57600093506155cd565b50505060208201516040830151606084015160001a601b60ff8216101561554057601b015b8060ff16601b1415801561555857508060ff16601c14155b1561556657600093506155cd565b60408051600080825260208083018085528a905260ff8516838501526060830187905260808301869052925160019360a0808501949193601f19840193928390039091019190865af11580156155c0573d6000803e3d6000fd5b5050506020604051035193505b50505092915050565b60008115806155f35750508082028282828115156155f057fe5b04145b15156146d557600080fd5b6000818381151561560b57fe5b049392505050565b8051604080830151606084015160a085015160c086015160e08701516101208801516101408901516101608a015188516c01000000000000000000000000308102602080840191909152600160a060020a039c8d1682026034840152998c16810260488301529a909716909902605c8701526070860194909452609085019290925260b084015260d083015260f0820152610110808201949094528251808203909401845261013001918290528251600093929182919084019080838360208310614e6f5780518252601f199092019160209182019101614e50565b608080820151805160208083015160608401519390940151610140860151604080516c0100000000000000000000000030810282870152600160a060020a0396871681026034830152959097169094026048870152605c860194909452607c850152609c808501939093528151808503909301835260bc90930190819052815160009382919084019080838360208310614e6f5780518252601f199092019160209182019101614e50565b60408051610240810182526000808252602082018190529181018290526060810191909152608081016157cb615813565b81526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600080191681525090565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091529056004f524445525f414c52454144595f4c49515549444154454400000000000000004453417574683a3a5f2053454e4445525f4e4f545f415554484f52495a4544004f524445525f414c52454144595f44454641554c544544000000000000000000db0b341562703a7cbd47efa0b024b1ed2e3c68e2d313e46d276db9a46d8a6f804d4b65726e656c3a3a6c69717569646174654f726465720000000000000000004d4b65726e656c3a3a70726f636573735472616465466f7245787069727900004d4b65726e656c3a3a70726f636573735472616465466f7253746f7050726f664d4b65726e656c3a3a70726f636573735472616465466f7253746f704c6f7373494e53554646494349454e545f54524144455f42414c414e43455f494e5f4553494e53554646494349454e545f434f4c4c41544552414c5f42414c414e43455f4f524445525f444f45535f4e4f545f45584953540000000000000000000000004d4b65726e656c3a3a6372656174654f726465720000000000000000000000005574696c733a3a5f20494e56414c49445f4144445245535300000000000000004d4b65726e656c3a3a5f20494e56414c49445f41444d494e5f4143434f554e54494e5f455343524f570000000000000000000000000000000000000000000000a165627a7a72305820b978523cfaf0225ad9aaac828feaa290019983b18ae0961590f65ff6838948120029000000000000000000000000af38668f4719ecf9452dc0300be3f6c83cbf37210000000000000000000000004e9d7f37eadc6fef64b5f5dccc4deb622466767700000000000000000000000064d14595152b430cf6940da15c6e39545c7c5b7e0000000000000000000000003e990e787a88cd4426fb3af9b90dd1d951e2cb87000000000000000000000000431f429035a1e3059d5c6a9a83208c6d3143d925
Deployed Bytecode
0x6080604052600436106101875763ffffffff60e060020a60003504166307da68f5811461018c57806313af4035146101a3578063162cfaac146101c457806320e3dbd4146101ee5780632fcdb8dd1461020f578063359abaed1461023b578063431025e1146102ac5780634459c9a3146102c45780635778472a146102e85780636722232614610368578063687cd9c11461039a5780636dec3260146103cb57806375f12b21146103ef57806379502c55146104045780637959f20a146104195780637a9e5e4b146104425780637bea0d1c146104635780638723555e146104785780638da5cb5b1461049057806390d49b9d146104a55780639cecc80a146104c6578063a3b13799146104e7578063a85c38ef14610539578063addc1a7614610551578063be9a655514610572578063bf7e214f14610587578063c046229e1461059c578063c10c3546146105c5578063c559f686146105e6578063cd3293de146106bf578063e2fdcc17146106d4578063ebac0bd9146106e9578063f25f4b561461071a575b600080fd5b34801561019857600080fd5b506101a161072f565b005b3480156101af57600080fd5b506101a1600160a060020a0360043516610813565b3480156101d057600080fd5b506101dc6004356108bd565b60408051918252519081900360200190f35b3480156101fa57600080fd5b506101a1600160a060020a03600435166108cf565b34801561021b57600080fd5b506102276004356109ef565b604080519115158252519081900360200190f35b34801561024757600080fd5b5061025c600160a060020a0360043516610a04565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610298578181015183820152602001610280565b505050509050019250505060405180910390f35b3480156102b857600080fd5b50610227600435610a72565b3480156102d057600080fd5b506101a1600435600160a060020a0360243516610a87565b3480156102f457600080fd5b50610300600435611185565b60408051600160a060020a039c8d1681529a8c1660208c0152988b168a8a0152969099166060890152608088019490945260a087019290925260c086015260e08501526101008401526101208301939093526101408201929092529051908190036101600190f35b34801561037457600080fd5b506101a1600460c46101c435600160a060020a03166101e43560248101908401356113fd565b3480156103a657600080fd5b506103af612294565b60408051600160a060020a039092168252519081900360200190f35b3480156103d757600080fd5b506101dc600160a060020a03600435166024356122a3565b3480156103fb57600080fd5b506102276122d3565b34801561041057600080fd5b506103af6122f4565b34801561042557600080fd5b506101a1600435600160a060020a03602435166044608435612303565b34801561044e57600080fd5b506101a1600160a060020a0360043516612b91565b34801561046f57600080fd5b5061025c612c37565b34801561048457600080fd5b50610227600435612c90565b34801561049c57600080fd5b506103af612ca5565b3480156104b157600080fd5b506101a1600160a060020a0360043516612cb4565b3480156104d257600080fd5b506101a1600160a060020a0360043516612dd4565b3480156104f357600080fd5b506104ff600435612ef4565b60408051600160a060020a039687168152948616602086015292909416838301526060830152608082019290925290519081900360a00190f35b34801561054557600080fd5b506101dc60043561301a565b34801561055d57600080fd5b506101a1600160a060020a0360043516613039565b34801561057e57600080fd5b506101a1613159565b34801561059357600080fd5b506103af613226565b3480156105a857600080fd5b506101a1600435600160a060020a03602435166044608435613235565b3480156105d157600080fd5b506101a1600160a060020a0360043516613ada565b3480156105f257600080fd5b506105fe600435613bfa565b604051808f600160a060020a0316600160a060020a031681526020018e600160a060020a0316600160a060020a031681526020018d600160a060020a0316600160a060020a031681526020018c600160a060020a0316600160a060020a031681526020018b81526020018a815260200189815260200188815260200187815260200186815260200185815260200184815260200183815260200182600019166000191681526020019e50505050505050505050505050505060405180910390f35b3480156106cb57600080fd5b506103af613cb8565b3480156106e057600080fd5b506103af613cc7565b3480156106f557600080fd5b506101a1600480359060248035600160a060020a031691604435918201910135613cd6565b34801561072657600080fd5b506103af6145c3565b61074533600035600160e060020a0319166145d2565b1515610789576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020615862833981519152604482015290519081900360640190fd5b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a450506001805474ff0000000000000000000000000000000000000000191674010000000000000000000000000000000000000000179055565b61082933600035600160e060020a0319166145d2565b151561086d576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020615862833981519152604482015290519081900360640190fd5b60018054600160a060020a031916600160a060020a0383811691909117918290556040519116907fce241d7ca1f669fee44b6fc00b8eba2df3bb514eed0f6f668f8f89096e81ed9490600090a250565b600b6020526000908152604090205481565b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a461093633600035600160e060020a0319166145d2565b151561097a576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020615862833981519152604482015290519081900360640190fd5b82600160a060020a03811615156109c9576040805160e560020a62461bcd02815260206004820152601860248201526000805160206159c2833981519152604482015290519081900360640190fd5b505060068054600160a060020a031916600160a060020a03939093169290921790915550565b600d6020526000908152604090205460ff1681565b600160a060020a0381166000908152600a6020908152604091829020805483518184028101840190945280845260609392830182828015610a6557602002820191906000526020600020905b81548152600190910190602001808311610a50575b505050505090505b919050565b600c6020526000908152604090205460ff1681565b610a8f61579a565b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a46006546040805160e060020a639c14ee290281523360048201529051600160a060020a0390921691639c14ee29916024808201926020929091908290030181600087803b158015610b3057600080fd5b505af1158015610b44573d6000803e3d6000fd5b505050506040513d6020811015610b5a57600080fd5b50511515610ba0576040805160e560020a62461bcd02815260206004820181905260248201526000805160206159e2833981519152604482015290519081900360640190fd5b83600160a060020a0381161515610bef576040805160e560020a62461bcd02815260206004820152601860248201526000805160206159c2833981519152604482015290519081900360640190fd5b60008681526009602052604090205460ff161515610c6d5760408051818152601e818301526000805160206158e2833981519152606082015260806020820181905260149082015260008051602061598283398151915260a0820152905187916000805160206158a2833981519152919081900360c00190a261117d565b6000868152600c602052604090205460ff1615610cea5760408051818152601e818301526000805160206158e2833981519152606082015260806020820181905260189082015260008051602061584283398151915260a0820152905187916000805160206158a2833981519152919081900360c00190a261117d565b6000868152600d602052604090205460ff1615610d675760408051818152601e818301526000805160206158e2833981519152606082015260806020820181905260179082015260008051602061588283398151915260a0820152905187916000805160206158a2833981519152919081900360c00190a261117d565b600086815260086020818152604080842081516101c0810183528154600160a060020a039081168252600183015481168286015260028084015482168386015260038401548216606080850191909152855160a081810188526004808801548616835260058801548616838b0152600788015493830193909352988601546080828101919091528501818152600987015499860199909952600a86015460c0860152600b8087015460e0870152600c870154610100870152600d870154610120870152600e870154610140870152600f87015461016087015260108701546101808701526011909601546101a08601528e8416908701528e8952938652848820549651519054855160e060020a6370a08231028152908316948101949094529351919a50949592909416936370a082319360248084019491938390030190829087803b158015610eb657600080fd5b505af1158015610eca573d6000803e3d6000fd5b505050506040513d6020811015610ee057600080fd5b50511015610f5e5760408051818152601e818301526000805160206158e2833981519152606082015260806020820181905260249082015260008051602061594283398151915260a082015260e060020a6343524f570260c0820152905187916000805160206158a2833981519152919081900360e00190a261117d565b60c084015160608501516002546040805160e060020a6370a08231028152600160a060020a039283166004820152905191909216916370a082319160248083019260209291908290030181600087803b158015610fba57600080fd5b505af1158015610fce573d6000803e3d6000fd5b505050506040513d6020811015610fe457600080fd5b505110156110665760408051818152601e818301526000805160206158e2833981519152606082015260806020820181905260299082015260008051602061596283398151915260a0820152600080516020615a0283398151915260c0820152905187916000805160206158a2833981519152919081900360e00190a261117d565b836101000151421115611106576101a08401516000908152600d60205260409020805460ff1916600117905561109b846146db565b6101a08401516040805160208082526017908201527f4d4b45524e454c5f4455455f444154455f5041535345440000000000000000008183015290517f98e393d0760ecfe8e3907134d357e8a4fa5b37e364c3baeb0b059a98317638c49181900360600190a261117d565b6101a084015160408051818152601e818301526000805160206158e283398151915260608201526080602082018190526013908201527f4e4f5f414354494f4e5f504552464f524d45440000000000000000000000000060a082015290516000805160206158a28339815191529181900360c00190a25b505050505050565b600080600080600080600080600080600061119e61579a565b600860008e600019166000191681526020019081526020016000206101c060405190810160405290816000820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016001820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016002820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016003820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016004820160a060405190810160405290816000820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016001820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016002820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a0316815260200160038201548152602001600482015481525050815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201548152602001600d8201548152602001600e8201548152602001600f8201548152602001601082015481526020016011820154600019166000191681525050905080600001518160200151826040015183606001518460a001518560c001518660e001518761010001518861014001518961016001518a61018001519b509b509b509b509b509b509b509b509b509b509b505091939597999b90929496989a50565b61140561579a565b604080513480825260208201838152369383018490526000936004359360243593849386933393600160e060020a03198a351693928a929190606082018484808284376040519201829003965090945050505050a46006546040805160e060020a639c14ee290281523360048201529051600160a060020a0390921691639c14ee29916024808201926020929091908290030181600087803b1580156114aa57600080fd5b505af11580156114be573d6000803e3d6000fd5b505050506040513d60208110156114d457600080fd5b5051151561151a576040805160e560020a62461bcd02815260206004820181905260248201526000805160206159e2833981519152604482015290519081900360640190fd5b60015474010000000000000000000000000000000000000000900460ff161561158d576040805160e560020a62461bcd02815260206004820152601960248201527f445353746f703a3a5f20464541545552455f53544f5050454400000000000000604482015290519081900360640190fd5b86600160a060020a03811615156115dc576040805160e560020a62461bcd02815260206004820152601860248201526000805160206159c2833981519152604482015290519081900360640190fd5b6040805160c0818101909252611624918c90600690839083908082843750506040805161010081810190925293508e92506008915083908390808284375061485b9350505050565b9450611665856101a0015188888080601f01602080910402602001604051908101604052809392919081815260200183838082843750614950945050505050565b6080860151600160a060020a03808b16604090920191909152602087015191955080861691161461170b576101a0850151604080518181526014818301526000805160206159a283398151915260608201526080602082018190526018908201527f5349474e45525f4e4f545f4f524445525f43524541544f52000000000000000060a082015290516000805160206158a28339815191529181900360c00190a2612288565b6101a085015160009081526009602052604090205460ff16156117a2576101a08501516040805181815260148183018190526000805160206159a283398151915260608301526080602083018190528201527f4f524445525f414c52454144595f45584953545300000000000000000000000060a082015290516000805160206158a28339815191529181900360c00190a2612288565b6003548551604080517f25ca4c9c000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152905191909216916325ca4c9c9160248083019260209291908290030181600087803b15801561180c57600080fd5b505af1158015611820573d6000803e3d6000fd5b505050506040513d602081101561183657600080fd5b505115156118b9576101a0850151604080518181526014818301526000805160206159a283398151915260608201526080602082018190526015908201527f494e56414c49445f4f524445525f4143434f554e54000000000000000000000060a082015290516000805160206158a28339815191529181900360c00190a2612288565b8460000151600160a060020a0316634209fff1856040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b15801561191857600080fd5b505af115801561192c573d6000803e3d6000fd5b505050506040513d602081101561194257600080fd5b505115156119eb576101a0850151604080518181526014818301526000805160206159a283398151915260608201526080602082018190526022908201527f5349474e45525f4e4f545f415554484f52495a45445f574954485f4143434f5560a08201527f4e5400000000000000000000000000000000000000000000000000000000000060c082015290516000805160206158a28339815191529181900360e00190a2612288565b6119f485614972565b1515611a75576101a0850151604080518181526014818301526000805160206159a283398151915260608201526080602082018190526018908201527f494e56414c49445f4f524445525f504152414d4554455253000000000000000060a082015290516000805160206158a28339815191529181900360c00190a2612288565b8460c001518560600151600160a060020a03166370a0823187600001516040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b158015611add57600080fd5b505af1158015611af1573d6000803e3d6000fd5b505050506040513d6020811015611b0757600080fd5b50511015611bb0576101a0850151604080518181526014818301526000805160206159a283398151915260608201526080602082018190526022908201527f494e53554646494349454e545f434f4c4c41544552414c5f494e5f4143434f5560a08201527f4e5400000000000000000000000000000000000000000000000000000000000060c082015290516000805160206158a28339815191529181900360e00190a2612288565b8460a001518560400151600160a060020a03166370a08231600460009054906101000a9004600160a060020a0316600160a060020a031663e2fdcc176040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015611c1b57600080fd5b505af1158015611c2f573d6000803e3d6000fd5b505050506040513d6020811015611c4557600080fd5b50516040805160e060020a63ffffffff8516028152600160a060020a0390921660048301525160248083019260209291908290030181600087803b158015611c8c57600080fd5b505af1158015611ca0573d6000803e3d6000fd5b505050506040513d6020811015611cb657600080fd5b50511015611d39576101a0850151604080518181526014818301526000805160206159a28339815191526060820152608060208201819052601d908201527f494e53554646494349454e545f46554e44535f494e5f5245534552564500000060a082015290516000805160206158a28339815191529181900360c00190a2612288565b611d558586604001518760800151600001518860a00151614a95565b1515611dd6576101a0850151604080518181526014818301526000805160206159a283398151915260608201526080602082018190526012908201527f54524144455f4e4f545f4645415349424c45000000000000000000000000000060a082015290516000805160206158a28339815191529181900360c00190a2612288565b6007856101a0015190806001815401808255809150509060018203906000526020600020016000909192909190915090600019169055508460086000876101a001516000191660001916815260200190815260200160002060008201518160000160006101000a815481600160a060020a030219169083600160a060020a0316021790555060208201518160010160006101000a815481600160a060020a030219169083600160a060020a0316021790555060408201518160020160006101000a815481600160a060020a030219169083600160a060020a0316021790555060608201518160030160006101000a815481600160a060020a030219169083600160a060020a0316021790555060808201518160040160008201518160000160006101000a815481600160a060020a030219169083600160a060020a0316021790555060208201518160010160006101000a815481600160a060020a030219169083600160a060020a0316021790555060408201518160020160006101000a815481600160a060020a030219169083600160a060020a031602179055506060820151816003015560808201518160040155505060a0820151816009015560c082015181600a015560e082015181600b015561010082015181600c015561012082015181600d015561014082015181600e015561016082015181600f015561018082015181601001556101a08201518160110190600019169055905050600160096000876101a001516000191660001916815260200190815260200160002060006101000a81548160ff021916908315150217905550600a60008660000151600160a060020a0316600160a060020a03168152602001908152602001600020856101a001519080600181540180825580915050906001820390600052602060002001600090919290919091509060001916905550600260009054906101000a9004600160a060020a0316600160a060020a0316635e61e1c886600001518760600151600260009054906101000a9004600160a060020a03168960c001516040518563ffffffff1660e060020a0281526004018085600160a060020a0316600160a060020a0316815260200184600160a060020a0316600160a060020a0316815260200183600160a060020a0316600160a060020a03168152602001828152602001945050505050600060405180830381600087803b15801561215557600080fd5b505af1158015612169573d6000803e3d6000fd5b5050600480546040808a015160025460a08c015183517f8bfb07c9000000000000000000000000000000000000000000000000000000008152600160a060020a039384169681019690965290821660248601526044850152905191169350638bfb07c99250606480830192600092919082900301818387803b1580156121ee57600080fd5b505af1158015612202573d6000803e3d6000fd5b505050506122228586604001518760800151600001518860a00151614b48565b506101a0860180516000908152600b602090815260408083209490945591518082529083902054610100890151845191825292810192909252825190927fea0bf587ab60e35e1551a895f638f97223b5471e71aef9e3102dfe8ceb87dc01928290030190a25b50505050505050505050565b600354600160a060020a031681565b600a602052816000526040600020818154811015156122be57fe5b90600052602060002001600091509150505481565b60015474010000000000000000000000000000000000000000900460ff1681565b600654600160a060020a031681565b61230b61579a565b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a46006546040805160e060020a639c14ee290281523360048201529051600160a060020a0390921691639c14ee29916024808201926020929091908290030181600087803b1580156123ac57600080fd5b505af11580156123c0573d6000803e3d6000fd5b505050506040513d60208110156123d657600080fd5b5051151561241c576040805160e560020a62461bcd02815260206004820181905260248201526000805160206159e2833981519152604482015290519081900360640190fd5b85600160a060020a038116151561246b576040805160e560020a62461bcd02815260206004820152601860248201526000805160206159c2833981519152604482015290519081900360640190fd5b60008881526009602052604090205460ff1615156124ea576040805181815260208183018190526000805160206159228339815191526060830152608090820181905260149082015260008051602061598283398151915260a0820152905189916000805160206158a2833981519152919081900360c00190a2612b87565b6000888152600c602052604090205460ff1615612568576040805181815260208183018190526000805160206159228339815191526060830152608090820181905260189082015260008051602061584283398151915260a0820152905189916000805160206158a2833981519152919081900360c00190a2612b87565b6000888152600d602052604090205460ff16156125e6576040805181815260208183018190526000805160206159228339815191526060830152608090820181905260179082015260008051602061588283398151915260a0820152905189916000805160206158a2833981519152919081900360c00190a2612b87565b6008600089600019166000191681526020019081526020016000206101c060405190810160405290816000820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016001820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016002820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016003820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016004820160a060405190810160405290816000820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016001820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016002820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a0316815260200160038201548152602001600482015481525050815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201548152602001600d8201548152602001600e8201548152602001600f8201548152602001601082015481526020016011820154600019166000191681525050935086846080015160400190600160a060020a03169081600160a060020a031681525050600b6000896000191660001916815260200190815260200160002054846080015160000151600160a060020a03166370a08231600260009054906101000a9004600160a060020a03166040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b15801561289a57600080fd5b505af11580156128ae573d6000803e3d6000fd5b505050506040513d60208110156128c457600080fd5b50511015612943576040805181815260208183018190526000805160206159228339815191526060830152608090820181905260249082015260008051602061594283398151915260a082015260e060020a6343524f570260c0820152905189916000805160206158a2833981519152919081900360e00190a2612b87565b60c084015160608501516002546040805160e060020a6370a08231028152600160a060020a039283166004820152905191909216916370a082319160248083019260209291908290030181600087803b15801561299f57600080fd5b505af11580156129b3573d6000803e3d6000fd5b505050506040513d60208110156129c957600080fd5b50511015612a4c576040805181815260208183018190526000805160206159228339815191526060830152608090820181905260299082015260008051602061596283398151915260a0820152600080516020615a0283398151915260c0820152905189916000805160206158a2833981519152919081900360e00190a2612b87565b604080518082018252612a769186919089906002908390839080828437508b9350614c1092505050565b1515612b0f576101a08401516000908152600d60205260409020805460ff19166001179055612aa4846146db565b6101a08401516040805160208082526014908201527f4d4b45524e454c5f4f524445525f554e534146450000000000000000000000008183015290517f98e393d0760ecfe8e3907134d357e8a4fa5b37e364c3baeb0b059a98317638c49181900360600190a2612b87565b6101a0840151604080518181526020818301819052600080516020615922833981519152606083015260809082018190526013908201527f4e4f5f414354494f4e5f504552464f524d45440000000000000000000000000060a082015290516000805160206158a28339815191529181900360c00190a25b5050505050505050565b612ba733600035600160e060020a0319166145d2565b1515612beb576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020615862833981519152604482015290519081900360640190fd5b60008054600160a060020a031916600160a060020a03838116919091178083556040519116917f1abebea81bfa2637f28358c371278fb15ede7ea8dd28d2e03b112ff6d936ada491a250565b60606007805480602002602001604051908101604052809291908181526020018280548015612c8657602002820191906000526020600020905b81548152600190910190602001808311612c71575b5050505050905090565b60096020526000908152604090205460ff1681565b600154600160a060020a031681565b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a4612d1b33600035600160e060020a0319166145d2565b1515612d5f576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020615862833981519152604482015290519081900360640190fd5b82600160a060020a0381161515612dae576040805160e560020a62461bcd02815260206004820152601860248201526000805160206159c2833981519152604482015290519081900360640190fd5b505060058054600160a060020a031916600160a060020a03939093169290921790915550565b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a4612e3b33600035600160e060020a0319166145d2565b1515612e7f576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020615862833981519152604482015290519081900360640190fd5b82600160a060020a0381161515612ece576040805160e560020a62461bcd02815260206004820152601860248201526000805160206159c2833981519152604482015290519081900360640190fd5b505060048054600160a060020a031916600160a060020a03939093169290921790915550565b6000806000806000612f0461579a565b505050600093845250506008602081815260409384902084516101c0810186528154600160a060020a0390811682526001830154811682850152600283015481168288015260038301548116606080840191909152875160a08082018a5260048601548416825260058601548416968201968752600686015490931698810198895260078501549181019182529584015460808088019182528401879052600985015492840192909252600a84015460c0840152600b84015460e0840152600c840154610100840152600d840154610120840152600e840154610140840152600f84015461016084015260108401546101808401526011909301546101a090920191909152925191519451905192519195909350565b600780548290811061302857fe5b600091825260209091200154905081565b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a46130a033600035600160e060020a0319166145d2565b15156130e4576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020615862833981519152604482015290519081900360640190fd5b82600160a060020a0381161515613133576040805160e560020a62461bcd02815260206004820152601860248201526000805160206159c2833981519152604482015290519081900360640190fd5b505060038054600160a060020a031916600160a060020a03939093169290921790915550565b61316f33600035600160e060020a0319166145d2565b15156131b3576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020615862833981519152604482015290519081900360640190fd5b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a450506001805474ff000000000000000000000000000000000000000019169055565b600054600160a060020a031681565b61323d61579a565b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a46006546040805160e060020a639c14ee290281523360048201529051600160a060020a0390921691639c14ee29916024808201926020929091908290030181600087803b1580156132de57600080fd5b505af11580156132f2573d6000803e3d6000fd5b505050506040513d602081101561330857600080fd5b5051151561334e576040805160e560020a62461bcd02815260206004820181905260248201526000805160206159e2833981519152604482015290519081900360640190fd5b85600160a060020a038116151561339d576040805160e560020a62461bcd02815260206004820152601860248201526000805160206159c2833981519152604482015290519081900360640190fd5b60008881526009602052604090205460ff1615156134295760408051818152602281830152600080516020615902833981519152606082015260f260020a611a5d02608082015260a06020820181905260149082015260008051602061598283398151915260c0820152905189916000805160206158a2833981519152919081900360e00190a2612b87565b6000888152600c602052604090205460ff16156134b45760408051818152602281830152600080516020615902833981519152606082015260f260020a611a5d02608082015260a06020820181905260189082015260008051602061584283398151915260c0820152905189916000805160206158a2833981519152919081900360e00190a2612b87565b6000888152600d602052604090205460ff161561353f5760408051818152602281830152600080516020615902833981519152606082015260f260020a611a5d02608082015260a06020820181905260179082015260008051602061588283398151915260c0820152905189916000805160206158a2833981519152919081900360e00190a2612b87565b6008600089600019166000191681526020019081526020016000206101c060405190810160405290816000820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016001820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016002820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016003820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016004820160a060405190810160405290816000820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016001820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016002820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a0316815260200160038201548152602001600482015481525050815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201548152602001600d8201548152602001600e8201548152602001600f8201548152602001601082015481526020016011820154600019166000191681525050935086846080015160400190600160a060020a03169081600160a060020a031681525050600b6000896000191660001916815260200190815260200160002054846080015160000151600160a060020a03166370a08231600260009054906101000a9004600160a060020a03166040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b1580156137f357600080fd5b505af1158015613807573d6000803e3d6000fd5b505050506040513d602081101561381d57600080fd5b505110156138aa5760408051818152602281830152600080516020615902833981519152606082015260f260020a611a5d02608082015260a06020820181905260249082015260008051602061594283398151915260c082015260e060020a6343524f570260e0820152905189916000805160206158a283398151915291908190036101000190a2612b87565b60c084015160608501516002546040805160e060020a6370a08231028152600160a060020a039283166004820152905191909216916370a082319160248083019260209291908290030181600087803b15801561390657600080fd5b505af115801561391a573d6000803e3d6000fd5b505050506040513d602081101561393057600080fd5b505110156139c15760408051818152602281830152600080516020615902833981519152606082015260f260020a611a5d02608082015260a06020820181905260299082015260008051602061596283398151915260c0820152600080516020615a0283398151915260e0820152905189916000805160206158a283398151915291908190036101000190a2612b87565b6040805180820182526139eb9186919089906002908390839080828437508b9350614d0692505050565b15613a4c576101a08401516000908152600c60205260409020805460ff19166001179055613a18846146db565b6101a08401516040517fc614d231c29c73ae067f16cd5460d0050c98401008b3cce99b3abb37302e548590600090a2612b87565b6101a084015160408051818152602281830152600080516020615902833981519152606082015260f260020a611a5d02608082015260a0602082018190526013908201527f4e4f5f414354494f4e5f504552464f524d45440000000000000000000000000060c082015290516000805160206158a28339815191529181900360e00190a25050505050505050565b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a4613b4133600035600160e060020a0319166145d2565b1515613b85576040805160e560020a62461bcd02815260206004820152601f6024820152600080516020615862833981519152604482015290519081900360640190fd5b82600160a060020a0381161515613bd4576040805160e560020a62461bcd02815260206004820152601860248201526000805160206159c2833981519152604482015290519081900360640190fd5b505060028054600160a060020a031916600160a060020a03939093169290921790915550565b6008602081815260009283526040928390208054600182015460028301546003840154875160a0810189526004860154600160a060020a03908116825260058701548116978201979097526006860154871698810198909852600785015460608901529584015460808801526009840154600a850154600b860154600c870154600d880154600e890154600f8a015460108b01546011909b0154998c169d988c169c978c169b9097169997989597949693959294919390929091908e565b600454600160a060020a031681565b600254600160a060020a031681565b600080613ce161579a565b60408051348082526020820183815236938301849052600435936024359384938693339360008035600160e060020a031916949092606082018484808284376040519201829003965090945050505050a46006546040805160e060020a639c14ee290281523360048201529051600160a060020a0390921691639c14ee29916024808201926020929091908290030181600087803b158015613d8257600080fd5b505af1158015613d96573d6000803e3d6000fd5b505050506040513d6020811015613dac57600080fd5b50511515613df2576040805160e560020a62461bcd02815260206004820181905260248201526000805160206159e2833981519152604482015290519081900360640190fd5b87600160a060020a0381161515613e41576040805160e560020a62461bcd02815260206004820152601860248201526000805160206159c2833981519152604482015290519081900360640190fd5b60008a81526009602052604090205460ff161515613ebf57604080518181526017818301526000805160206158c2833981519152606082015260806020820181905260149082015260008051602061598283398151915260a082015290518b916000805160206158a2833981519152919081900360c00190a2612288565b60008a8152600c602052604090205460ff1615613f3c57604080518181526017818301526000805160206158c2833981519152606082015260806020820181905260189082015260008051602061584283398151915260a082015290518b916000805160206158a2833981519152919081900360c00190a2612288565b60008a8152600d602052604090205460ff1615613fb8576040805181815260178183018190526000805160206158c2833981519152606083015260806020830181905282015260008051602061588283398151915260a082015290518b916000805160206158a2833981519152919081900360c00190a2612288565b613fc18a614de3565b9550613ffd8689898080601f01602080910402602001604051908101604052809392919081815260200183838082843750614950945050505050565b9450600860008b600019166000191681526020019081526020016000206101c060405190810160405290816000820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016001820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016002820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016003820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016004820160a060405190810160405290816000820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016001820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a031681526020016002820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a0316815260200160038201548152602001600482015481525050815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201548152602001600d8201548152602001600e8201548152602001600f8201548152602001601082015481526020016011820154600019166000191681525050935088846080015160400190600160a060020a03169081600160a060020a0316815250508360000151600160a060020a0316634209fff1866040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b15801561427e57600080fd5b505af1158015614292573d6000803e3d6000fd5b505050506040513d60208110156142a857600080fd5b5051151561434e57604080518181526017818301526000805160206158c283398151915260608201526080602082018190526022908201527f5349474e45525f4e4f545f415554484f52495a45445f574954485f4143434f5560a08201527f4e5400000000000000000000000000000000000000000000000000000000000060c082015290518b916000805160206158a2833981519152919081900360e00190a2612288565b60008a8152600b6020908152604080832054608088015151600254835160e060020a6370a08231028152600160a060020a039182166004820152935192959116936370a08231936024808201949293918390030190829087803b1580156143b457600080fd5b505af11580156143c8573d6000803e3d6000fd5b505050506040513d60208110156143de57600080fd5b5051101561445c57604080518181526017818301526000805160206158c2833981519152606082015260806020820181905260249082015260008051602061594283398151915260a082015260e060020a6343524f570260c082015290518b916000805160206158a2833981519152919081900360e00190a2612288565b60c084015160608501516002546040805160e060020a6370a08231028152600160a060020a039283166004820152905191909216916370a082319160248083019260209291908290030181600087803b1580156144b857600080fd5b505af11580156144cc573d6000803e3d6000fd5b505050506040513d60208110156144e257600080fd5b5051101561456457604080518181526017818301526000805160206158c2833981519152606082015260806020820181905260299082015260008051602061596283398151915260a0820152600080516020615a0283398151915260c082015290518b916000805160206158a2833981519152919081900360e00190a2612288565b6101a08401516000908152600c60205260409020805460ff1916600117905561458c846146db565b6040518a907f6cc69d7894fbf109ad278f7e331e91f734cd486332ee4e1eb3625bb2538eea4990600090a250505050505050505050565b600554600160a060020a031681565b6000600160a060020a0383163014156145ed575060016146d5565b600154600160a060020a038481169116141561460b575060016146d5565b600054600160a060020a03161515614625575060006146d5565b60008054604080517fb7009613000000000000000000000000000000000000000000000000000000008152600160a060020a038781166004830152306024830152600160e060020a0319871660448301529151919092169263b700961392606480820193602093909283900390910190829087803b1580156146a657600080fd5b505af11580156146ba573d6000803e3d6000fd5b505050506040513d60208110156146d057600080fd5b505190505b92915050565b600080600080600080600080600080600b60008c6101a001516000191660001916815260200190815260200160002054995061471f8b60a001518c60e00151614ea1565b9850614730898c6101600151614ea1565b9750600096506000955060009450600093506000925060009150600090506147668b8c60800151600001518d604001518d614b48565b5096508787106147a15761477a8789614eb1565b92508a6101600151905061479c8b8a8d60e0015160008f60c001518887614ec1565b61484e565b6147ab8888614eb1565b94508a60400151600160a060020a03168b60600151600160a060020a031614156147f557849550848b60c001511015156147f0576147ed8b60c0015186614eb1565b93505b614814565b61480e8b8c606001518d604001518e60c001518961524e565b90965093505b848610614838578a6101600151905061479c8b8a8d60e00151600088600087614ec1565b6148428787614ea1565b915061484e8b8361531e565b5050505050505050505050565b61486361579a565b61486b615813565b61487361579a565b608085015160a086015160c086015160e0870151614893939291906153b8565b604080516101c0810182528751600160a060020a0390811682526020808a0151821681840152898401518216838501526060808b01519092168284015260808301859052885160a084015288015160c08301529187015160e08201529086015191935090610100820190614908904290614ea1565b81526060808701516020830152608080880151604084015260a08089015192840192909252429083015260009101529050614942816153fa565b6101a0820152949350505050565b600061496b8261495f8561548a565b9063ffffffff61550116565b9392505050565b8051600090600160a060020a0316158061499757506020820151600160a060020a0316155b806149ad57506040820151600160a060020a0316155b806149c357506060820151600160a060020a0316155b806149dd5750608082015160200151600160a060020a0316155b806149f45750608082015151600160a060020a0316155b80614a1c57508160400151600160a060020a0316826080015160000151600160a060020a0316145b80614a365750608082015160400151600160a060020a0316155b80614a43575060a0820151155b80614a50575060c0820151155b80614a5d575060e0820151155b80614a72575081610180015182610100015111155b80614a805750610140820151155b15614a8d57506000610a6d565b506001919050565b608084015160409081015181517f5d0b4e5c000000000000000000000000000000000000000000000000000000008152600160a060020a0386811660048301528581166024830152604482018590529251600093831691635d0b4e5c91606480830192602092919082900301818887803b158015614b1257600080fd5b505af1158015614b26573d6000803e3d6000fd5b505050506040513d6020811015614b3c57600080fd5b50519695505050505050565b608084015160409081015160025482517f17fd9cc5000000000000000000000000000000000000000000000000000000008152600160a060020a039182166004820152868216602482015285821660448201526064810185905283516000948594938416926317fd9cc5926084808301939282900301818887803b158015614bcf57600080fd5b505af1158015614be3573d6000803e3d6000fd5b505050506040513d6040811015614bf957600080fd5b508051602090910151909890975095505050505050565b81516020808401516101a08601516000908152600b909252604082205460a087015160e088015193949385918291829182918291614c5d91614c529190614ea1565b8d6101600151614ea1565b9450614c7e614c708d60c001518a6155d6565b670de0b6b3a76400006155fe565b9350614c8d614c7087896155d6565b9250614ca0614c708d60a001518c6155d6565b9150614cb7614c708d6080015160800151866155d6565b905082614cc48684614ea1565b10158015614ce4575080614ce1614cdb8785614ea1565b85614eb1565b10155b15614cf25760009850614cf7565b600198505b50505050505050509392505050565b600080600080600080600089608001516060015160001415614d2b5760009650614dd6565b6020808a01516101a08c01516000908152600b90925260409091205460a08c015160e08d0151929850909650614d7091614d659190614ea1565b8b6101600151614ea1565b9350614d7f614c7086886155d6565b9250614d9a614c708b60a001518c60800151606001516155d6565b9150614dad614c708b60a001518a6155d6565b9050614dc2614dbc8584614ea1565b82614ea1565b8310614dd15760019650614dd6565b600096505b5050505050509392505050565b604080516c010000000000000000000000003002602080830191909152603482018490527f43414e43454c5f4d4b45524e454c5f4f524445520000000000000000000000006054830152825160488184030181526068909201928390528151600093918291908401908083835b60208310614e6f5780518252601f199092019160209182019101614e50565b5181516020939093036101000a6000190180199091169216919091179052604051920182900390912095945050505050565b808201828110156146d557600080fd5b808203828111156146d557600080fd5b60008281831115614f4b576002546040808b0151600554825160e360020a6317d57599028152600160a060020a039283166004820152908216602482015260448101879052915192169163beabacc89160648082019260009290919082900301818387803b158015614f3257600080fd5b505af1158015614f46573d6000803e3d6000fd5b505050505b600480546040808c015160025482517f106689a5000000000000000000000000000000000000000000000000000000008152600160a060020a039283169581019590955281166024850152604484018c9052606484018b9052608484018a9052905191169163106689a59160a480830192600092919082900301818387803b158015614fd657600080fd5b505af1158015614fea573d6000803e3d6000fd5b5050505060008511156150765760025460608a01518a516040805160e360020a6317d57599028152600160a060020a03938416600482015291831660248301526044820189905251919092169163beabacc891606480830192600092919082900301818387803b15801561505d57600080fd5b505af1158015615071573d6000803e3d6000fd5b505050505b60008411156151e8578860400151600160a060020a0316896080015160200151600160a060020a031614806150c057506150be898a604001518b608001516020015187614a95565b155b15615147576002546040808b01518b51825160e360020a6317d57599028152600160a060020a039283166004820152908216602482015260448101889052915192169163beabacc89160648082019260009290919082900301818387803b15801561512a57600080fd5b505af115801561513e573d6000803e3d6000fd5b505050506151e8565b61515f898a604001518b608001516020015187614b48565b5060025460808b0151602001518b516040805160e360020a6317d57599028152600160a060020a0393841660048201529183166024830152604482018590525193955091169163beabacc89160648082019260009290919082900301818387803b1580156151cc57600080fd5b505af11580156151e0573d6000803e3d6000fd5b505050508190505b6101a0890151604080518a8152602081018a9052808201899052606081018890526080810184905260a0810186905290517fd5620126c5a9c2d177d7302570339d14ed881b5f6d3fdb8f63bd6fa00601bc6b9181900360c00190a2505050505050505050565b608085015160409081015160025482517fc83ec89d000000000000000000000000000000000000000000000000000000008152600160a060020a039182166004820152878216602482015286821660448201526064810186905260848101859052835160009485949384169263c83ec89d9260a4808301939282900301818887803b1580156152dc57600080fd5b505af11580156152f0573d6000803e3d6000fd5b505050506040513d604081101561530657600080fd5b50805160209091015190999098509650505050505050565b60006153328360a001518460e00151614ea1565b905080821061535e5761535983828560e0015160008060006153548989614eb1565b614ec1565b6153b3565b808210801561537157508260a001518210155b15615394576153598383615389858760a00151614eb1565b600080600080614ec1565b6153b3838360006153a98760a0015187614eb1565b6000806000614ec1565b505050565b6153c0615813565b506040805160a081018252600160a060020a0395861681529390941660208401526000938301939093526060820152608081019190915290565b60003061540683615613565b61540f846156ef565b604080516c01000000000000000000000000600160a060020a0390951694909402602080860191909152603485019390935260548085019290925280518085039092018252607490930192839052805190929182919084019080838360208310614e6f5780518252601f199092019160209182019101614e50565b604080517f19457468657265756d205369676e6564204d6573736167653a0a333200000000602080830191909152603c80830185905283518084039091018152605c9092019283905281516000939182919084019080838360208310614e6f5780518252601f199092019160209182019101614e50565b6000806000808451604114151561551b57600093506155cd565b50505060208201516040830151606084015160001a601b60ff8216101561554057601b015b8060ff16601b1415801561555857508060ff16601c14155b1561556657600093506155cd565b60408051600080825260208083018085528a905260ff8516838501526060830187905260808301869052925160019360a0808501949193601f19840193928390039091019190865af11580156155c0573d6000803e3d6000fd5b5050506020604051035193505b50505092915050565b60008115806155f35750508082028282828115156155f057fe5b04145b15156146d557600080fd5b6000818381151561560b57fe5b049392505050565b8051604080830151606084015160a085015160c086015160e08701516101208801516101408901516101608a015188516c01000000000000000000000000308102602080840191909152600160a060020a039c8d1682026034840152998c16810260488301529a909716909902605c8701526070860194909452609085019290925260b084015260d083015260f0820152610110808201949094528251808203909401845261013001918290528251600093929182919084019080838360208310614e6f5780518252601f199092019160209182019101614e50565b608080820151805160208083015160608401519390940151610140860151604080516c0100000000000000000000000030810282870152600160a060020a0396871681026034830152959097169094026048870152605c860194909452607c850152609c808501939093528151808503909301835260bc90930190819052815160009382919084019080838360208310614e6f5780518252601f199092019160209182019101614e50565b60408051610240810182526000808252602082018190529181018290526060810191909152608081016157cb615813565b81526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600080191681525090565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091529056004f524445525f414c52454144595f4c49515549444154454400000000000000004453417574683a3a5f2053454e4445525f4e4f545f415554484f52495a4544004f524445525f414c52454144595f44454641554c544544000000000000000000db0b341562703a7cbd47efa0b024b1ed2e3c68e2d313e46d276db9a46d8a6f804d4b65726e656c3a3a6c69717569646174654f726465720000000000000000004d4b65726e656c3a3a70726f636573735472616465466f7245787069727900004d4b65726e656c3a3a70726f636573735472616465466f7253746f7050726f664d4b65726e656c3a3a70726f636573735472616465466f7253746f704c6f7373494e53554646494349454e545f54524144455f42414c414e43455f494e5f4553494e53554646494349454e545f434f4c4c41544552414c5f42414c414e43455f4f524445525f444f45535f4e4f545f45584953540000000000000000000000004d4b65726e656c3a3a6372656174654f726465720000000000000000000000005574696c733a3a5f20494e56414c49445f4144445245535300000000000000004d4b65726e656c3a3a5f20494e56414c49445f41444d494e5f4143434f554e54494e5f455343524f570000000000000000000000000000000000000000000000a165627a7a72305820b978523cfaf0225ad9aaac828feaa290019983b18ae0961590f65ff6838948120029
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000af38668f4719ecf9452dc0300be3f6c83cbf37210000000000000000000000004e9d7f37eadc6fef64b5f5dccc4deb622466767700000000000000000000000064d14595152b430cf6940da15c6e39545c7c5b7e0000000000000000000000003e990e787a88cd4426fb3af9b90dd1d951e2cb87000000000000000000000000431f429035a1e3059d5c6a9a83208c6d3143d925
-----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
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 000000000000000000000000af38668f4719ecf9452dc0300be3f6c83cbf3721
Arg [1] : 0000000000000000000000004e9d7f37eadc6fef64b5f5dccc4deb6224667677
Arg [2] : 00000000000000000000000064d14595152b430cf6940da15c6e39545c7c5b7e
Arg [3] : 0000000000000000000000003e990e787a88cd4426fb3af9b90dd1d951e2cb87
Arg [4] : 000000000000000000000000431f429035a1e3059d5c6a9a83208c6d3143d925
Swarm Source
bzzr://b978523cfaf0225ad9aaac828feaa290019983b18ae0961590f65ff683894812
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 27 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.