Overview
ETH Balance
48.936188029127750134 ETH
Eth Value
$163,227.72 (@ $3,335.52/ETH)Token Holdings
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 6,159 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Hub Contract Wit... | 13544446 | 1154 days ago | IN | 0 ETH | 0.00969937 | ||||
Empty Channel | 13544424 | 1154 days ago | IN | 0 ETH | 0.01993412 | ||||
Start Exit | 13538056 | 1155 days ago | IN | 0 ETH | 0.01954527 | ||||
Hub Contract Wit... | 10339986 | 1649 days ago | IN | 0 ETH | 0.00223492 | ||||
Hub Authorized U... | 9062263 | 1852 days ago | IN | 0 ETH | 0.00471636 | ||||
Hub Authorized U... | 8996105 | 1863 days ago | IN | 0 ETH | 0.00085371 | ||||
Hub Authorized U... | 8996055 | 1863 days ago | IN | 0 ETH | 0.00085371 | ||||
Hub Authorized U... | 8995991 | 1863 days ago | IN | 0 ETH | 0.00085371 | ||||
Hub Authorized U... | 8995962 | 1863 days ago | IN | 0 ETH | 0.00085371 | ||||
Hub Authorized U... | 8993413 | 1864 days ago | IN | 0 ETH | 0.00519676 | ||||
Hub Authorized U... | 8982579 | 1866 days ago | IN | 0 ETH | 0.00550592 | ||||
Hub Authorized U... | 8945893 | 1872 days ago | IN | 0 ETH | 0.00476102 | ||||
Hub Authorized U... | 8941249 | 1873 days ago | IN | 0 ETH | 0.00498352 | ||||
Hub Authorized U... | 8939491 | 1873 days ago | IN | 0 ETH | 0.00065734 | ||||
Hub Authorized U... | 8934799 | 1874 days ago | IN | 0 ETH | 0.0055105 | ||||
Hub Authorized U... | 8900070 | 1879 days ago | IN | 0 ETH | 0.00497094 | ||||
Hub Authorized U... | 8878838 | 1883 days ago | IN | 0 ETH | 0.0051829 | ||||
Hub Authorized U... | 8871010 | 1884 days ago | IN | 0 ETH | 0.00534548 | ||||
Hub Authorized U... | 8864711 | 1885 days ago | IN | 0 ETH | 0.00477552 | ||||
Hub Authorized U... | 8861335 | 1886 days ago | IN | 0 ETH | 0.00504664 | ||||
Hub Authorized U... | 8857082 | 1886 days ago | IN | 0 ETH | 0.00494078 | ||||
Hub Authorized U... | 8854831 | 1887 days ago | IN | 0 ETH | 0.00541838 | ||||
Hub Authorized U... | 8845025 | 1888 days ago | IN | 0 ETH | 0.00569275 | ||||
Hub Authorized U... | 8843228 | 1889 days ago | IN | 0 ETH | 0.00474524 | ||||
Hub Authorized U... | 8838937 | 1889 days ago | IN | 0 ETH | 0.00532882 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
13544446 | 1154 days ago | 69.04723546 ETH | ||||
13544424 | 1154 days ago | 0.08436122 ETH | ||||
9062263 | 1852 days ago | 0.53072461 ETH | ||||
8993413 | 1864 days ago | 0.2055458 ETH | ||||
8982579 | 1866 days ago | 0.10781521 ETH | ||||
8945893 | 1872 days ago | 0.00600959 ETH | ||||
8941249 | 1873 days ago | 0.02949013 ETH | ||||
8934799 | 1874 days ago | 0.00453851 ETH | ||||
8900070 | 1879 days ago | 0.08466799 ETH | ||||
8878838 | 1883 days ago | 0.55486651 ETH | ||||
8871010 | 1884 days ago | 0.02728037 ETH | ||||
8864711 | 1885 days ago | 0.00463136 ETH | ||||
8861335 | 1886 days ago | 0.14604678 ETH | ||||
8857082 | 1886 days ago | 0.00375171 ETH | ||||
8854831 | 1887 days ago | 0.02225321 ETH | ||||
8845025 | 1888 days ago | 0.00380937 ETH | ||||
8843228 | 1889 days ago | 0.04248721 ETH | ||||
8838937 | 1889 days ago | 0.00073254 ETH | ||||
8837890 | 1889 days ago | 0.83558254 ETH | ||||
8835572 | 1890 days ago | 0.26900188 ETH | ||||
8834724 | 1890 days ago | 0.05111623 ETH | ||||
8831576 | 1890 days ago | 0.0383729 ETH | ||||
8831558 | 1890 days ago | 0.02314295 ETH | ||||
8831402 | 1890 days ago | 0.14745315 ETH | ||||
8830815 | 1891 days ago | 0.00060496 ETH |
Loading...
Loading
This contract contains unverified libraries: ECTools
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
ChannelManager
Compiler Version
v0.4.25+commit.59dbf8f1
Optimization Enabled:
Yes with 1 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2018-12-22 */ pragma solidity ^0.4.25; pragma experimental ABIEncoderV2; // produced by the Solididy File Flattener (c) David Appleton 2018 // contact : [email protected] // released under Apache 2.0 licence contract ERC20Basic { function totalSupply() public view returns (uint256); function balanceOf(address who) public view returns (uint256); function transfer(address to, uint256 value) public returns (bool); event Transfer(address indexed from, address indexed to, uint256 value); } library ECTools { // @dev Recovers the address which has signed a message // @thanks https://gist.github.com/axic/5b33912c6f61ae6fd96d6c4a47afde6d function recoverSigner(bytes32 _hashedMsg, string _sig) public pure returns (address) { require(_hashedMsg != 0x00); // need this for test RPC bytes memory prefix = "\x19Ethereum Signed Message:\n32"; bytes32 prefixedHash = keccak256(abi.encodePacked(prefix, _hashedMsg)); if (bytes(_sig).length != 132) { return 0x0; } bytes32 r; bytes32 s; uint8 v; bytes memory sig = hexstrToBytes(substring(_sig, 2, 132)); 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 0x0; } return ecrecover(prefixedHash, v, r, s); } // @dev Verifies if the message is signed by an address function isSignedBy(bytes32 _hashedMsg, string _sig, address _addr) public pure returns (bool) { require(_addr != 0x0); return _addr == recoverSigner(_hashedMsg, _sig); } // @dev Converts an hexstring to bytes function hexstrToBytes(string _hexstr) public pure returns (bytes) { uint len = bytes(_hexstr).length; require(len % 2 == 0); bytes memory bstr = bytes(new string(len / 2)); uint k = 0; string memory s; string memory r; for (uint i = 0; i < len; i += 2) { s = substring(_hexstr, i, i + 1); r = substring(_hexstr, i + 1, i + 2); uint p = parseInt16Char(s) * 16 + parseInt16Char(r); bstr[k++] = uintToBytes32(p)[31]; } return bstr; } // @dev Parses a hexchar, like 'a', and returns its hex value, in this case 10 function parseInt16Char(string _char) public pure returns (uint) { bytes memory bresult = bytes(_char); // bool decimals = false; if ((bresult[0] >= 48) && (bresult[0] <= 57)) { return uint(bresult[0]) - 48; } else if ((bresult[0] >= 65) && (bresult[0] <= 70)) { return uint(bresult[0]) - 55; } else if ((bresult[0] >= 97) && (bresult[0] <= 102)) { return uint(bresult[0]) - 87; } else { revert(); } } // @dev Converts a uint to a bytes32 // @thanks https://ethereum.stackexchange.com/questions/4170/how-to-convert-a-uint-to-bytes-in-solidity function uintToBytes32(uint _uint) public pure returns (bytes b) { b = new bytes(32); assembly {mstore(add(b, 32), _uint)} } // @dev Hashes the signed message // @ref https://github.com/ethereum/go-ethereum/issues/3731#issuecomment-293866868 function toEthereumSignedMessage(string _msg) public pure returns (bytes32) { uint len = bytes(_msg).length; require(len > 0); bytes memory prefix = "\x19Ethereum Signed Message:\n"; return keccak256(abi.encodePacked(prefix, uintToString(len), _msg)); } // @dev Converts a uint in a string function uintToString(uint _uint) public pure returns (string str) { uint len = 0; uint m = _uint + 0; while (m != 0) { len++; m /= 10; } bytes memory b = new bytes(len); uint i = len - 1; while (_uint != 0) { uint remainder = _uint % 10; _uint = _uint / 10; b[i--] = byte(48 + remainder); } str = string(b); } // @dev extract a substring // @thanks https://ethereum.stackexchange.com/questions/31457/substring-in-solidity function substring(string _str, uint _startIndex, uint _endIndex) public pure returns (string) { bytes memory strBytes = bytes(_str); require(_startIndex <= _endIndex); require(_startIndex >= 0); require(_endIndex <= strBytes.length); bytes memory result = new bytes(_endIndex - _startIndex); for (uint i = _startIndex; i < _endIndex; i++) { result[i - _startIndex] = strBytes[i]; } return string(result); } } library SafeMath { /** * @dev Multiplies two numbers, reverts on overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b); return c; } /** * @dev Integer division of two numbers truncating the quotient, reverts on division by zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0); // Solidity only automatically asserts when dividing by 0 uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a); uint256 c = a - b; return c; } /** * @dev Adds two numbers, reverts on overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a); return c; } /** * @dev Divides two numbers and returns the remainder (unsigned integer modulo), * reverts when dividing by zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0); return a % b; } } contract ERC20 is ERC20Basic { function allowance(address owner, address spender) public view returns (uint256); function transferFrom(address from, address to, uint256 value) public returns (bool); function approve(address spender, uint256 value) public returns (bool); event Approval(address indexed owner, address indexed spender, uint256 value); } contract ChannelManager { using SafeMath for uint256; string public constant NAME = "Channel Manager"; string public constant VERSION = "0.0.1"; address public hub; uint256 public challengePeriod; ERC20 public approvedToken; uint256 public totalChannelWei; uint256 public totalChannelToken; event DidHubContractWithdraw ( uint256 weiAmount, uint256 tokenAmount ); // Note: the payload of DidUpdateChannel contains the state that caused // the update, not the state post-update (ex, if the update contains a // deposit, the event's ``pendingDeposit`` field will be present and the // event's ``balance`` field will not have been updated to reflect that // balance). event DidUpdateChannel ( address indexed user, uint256 senderIdx, // 0: hub, 1: user uint256[2] weiBalances, // [hub, user] uint256[2] tokenBalances, // [hub, user] uint256[4] pendingWeiUpdates, // [hubDeposit, hubWithdrawal, userDeposit, userWithdrawal] uint256[4] pendingTokenUpdates, // [hubDeposit, hubWithdrawal, userDeposit, userWithdrawal] uint256[2] txCount, // [global, onchain] bytes32 threadRoot, uint256 threadCount ); // Note: unlike the DidUpdateChannel event, the ``DidStartExitChannel`` // event will contain the channel state after any state that has been // applied as part of startExitWithUpdate. event DidStartExitChannel ( address indexed user, uint256 senderIdx, // 0: hub, 1: user uint256[2] weiBalances, // [hub, user] uint256[2] tokenBalances, // [hub, user] uint256[2] txCount, // [global, onchain] bytes32 threadRoot, uint256 threadCount ); event DidEmptyChannel ( address indexed user, uint256 senderIdx, // 0: hub, 1: user uint256[2] weiBalances, // [hub, user] uint256[2] tokenBalances, // [hub, user] uint256[2] txCount, // [global, onchain] bytes32 threadRoot, uint256 threadCount ); event DidStartExitThread ( address user, address indexed sender, address indexed receiver, uint256 threadId, address senderAddress, // either hub or user uint256[2] weiBalances, // [sender, receiver] uint256[2] tokenBalances, // [sender, receiver] uint256 txCount ); event DidChallengeThread ( address indexed sender, address indexed receiver, uint256 threadId, address senderAddress, // can be either hub, sender, or receiver uint256[2] weiBalances, // [sender, receiver] uint256[2] tokenBalances, // [sender, receiver] uint256 txCount ); event DidEmptyThread ( address user, address indexed sender, address indexed receiver, uint256 threadId, address senderAddress, // can be anyone uint256[2] channelWeiBalances, uint256[2] channelTokenBalances, uint256[2] channelTxCount, bytes32 channelThreadRoot, uint256 channelThreadCount ); event DidNukeThreads( address indexed user, address senderAddress, // can be anyone uint256 weiAmount, // amount of wei sent uint256 tokenAmount, // amount of tokens sent uint256[2] channelWeiBalances, uint256[2] channelTokenBalances, uint256[2] channelTxCount, bytes32 channelThreadRoot, uint256 channelThreadCount ); enum ChannelStatus { Open, ChannelDispute, ThreadDispute } struct Channel { uint256[3] weiBalances; // [hub, user, total] uint256[3] tokenBalances; // [hub, user, total] uint256[2] txCount; // persisted onchain even when empty [global, pending] bytes32 threadRoot; uint256 threadCount; address exitInitiator; uint256 channelClosingTime; ChannelStatus status; } struct Thread { uint256[2] weiBalances; // [sender, receiver] uint256[2] tokenBalances; // [sender, receiver] uint256 txCount; // persisted onchain even when empty uint256 threadClosingTime; bool[2] emptied; // [sender, receiver] } mapping(address => Channel) public channels; mapping(address => mapping(address => mapping(uint256 => Thread))) threads; // threads[sender][receiver][threadId] bool locked; modifier onlyHub() { require(msg.sender == hub); _; } modifier noReentrancy() { require(!locked, "Reentrant call."); locked = true; _; locked = false; } constructor(address _hub, uint256 _challengePeriod, address _tokenAddress) public { hub = _hub; challengePeriod = _challengePeriod; approvedToken = ERC20(_tokenAddress); } function hubContractWithdraw(uint256 weiAmount, uint256 tokenAmount) public noReentrancy onlyHub { require( getHubReserveWei() >= weiAmount, "hubContractWithdraw: Contract wei funds not sufficient to withdraw" ); require( getHubReserveTokens() >= tokenAmount, "hubContractWithdraw: Contract token funds not sufficient to withdraw" ); hub.transfer(weiAmount); require( approvedToken.transfer(hub, tokenAmount), "hubContractWithdraw: Token transfer failure" ); emit DidHubContractWithdraw(weiAmount, tokenAmount); } function getHubReserveWei() public view returns (uint256) { return address(this).balance.sub(totalChannelWei); } function getHubReserveTokens() public view returns (uint256) { return approvedToken.balanceOf(address(this)).sub(totalChannelToken); } function hubAuthorizedUpdate( address user, address recipient, uint256[2] weiBalances, // [hub, user] uint256[2] tokenBalances, // [hub, user] uint256[4] pendingWeiUpdates, // [hubDeposit, hubWithdrawal, userDeposit, userWithdrawal] uint256[4] pendingTokenUpdates, // [hubDeposit, hubWithdrawal, userDeposit, userWithdrawal] uint256[2] txCount, // [global, onchain] persisted onchain even when empty bytes32 threadRoot, uint256 threadCount, uint256 timeout, string sigUser ) public noReentrancy onlyHub { Channel storage channel = channels[user]; _verifyAuthorizedUpdate( channel, txCount, weiBalances, tokenBalances, pendingWeiUpdates, pendingTokenUpdates, timeout, true ); _verifySig( [user, recipient], weiBalances, tokenBalances, pendingWeiUpdates, // [hubDeposit, hubWithdrawal, userDeposit, userWithdrawal] pendingTokenUpdates, // [hubDeposit, hubWithdrawal, userDeposit, userWithdrawal] txCount, threadRoot, threadCount, timeout, "", // skip hub sig verification sigUser, [false, true] // [checkHubSig?, checkUser] <- only need to check user ); _updateChannelBalances(channel, weiBalances, tokenBalances, pendingWeiUpdates, pendingTokenUpdates); // transfer wei and token to recipient recipient.transfer(pendingWeiUpdates[3]); require(approvedToken.transfer(recipient, pendingTokenUpdates[3]), "user token withdrawal transfer failed"); // update state variables channel.txCount = txCount; channel.threadRoot = threadRoot; channel.threadCount = threadCount; emit DidUpdateChannel( user, 0, // senderIdx weiBalances, tokenBalances, pendingWeiUpdates, pendingTokenUpdates, txCount, threadRoot, threadCount ); } function userAuthorizedUpdate( address recipient, uint256[2] weiBalances, // [hub, user] uint256[2] tokenBalances, // [hub, user] uint256[4] pendingWeiUpdates, // [hubDeposit, hubWithdrawal, userDeposit, userWithdrawal] uint256[4] pendingTokenUpdates, // [hubDeposit, hubWithdrawal, userDeposit, userWithdrawal] uint256[2] txCount, // persisted onchain even when empty bytes32 threadRoot, uint256 threadCount, uint256 timeout, string sigHub ) public payable noReentrancy { require(msg.value == pendingWeiUpdates[2], "msg.value is not equal to pending user deposit"); Channel storage channel = channels[msg.sender]; _verifyAuthorizedUpdate( channel, txCount, weiBalances, tokenBalances, pendingWeiUpdates, pendingTokenUpdates, timeout, false ); _verifySig( [msg.sender, recipient], weiBalances, tokenBalances, pendingWeiUpdates, // [hubDeposit, hubWithdrawal, userDeposit, userWithdrawal] pendingTokenUpdates, // [hubDeposit, hubWithdrawal, userDeposit, userWithdrawal] txCount, threadRoot, threadCount, timeout, sigHub, "", // skip user sig verification [true, false] // [checkHubSig?, checkUser] <- only need to check hub ); // transfer user token deposit to this contract require(approvedToken.transferFrom(msg.sender, address(this), pendingTokenUpdates[2]), "user token deposit failed"); _updateChannelBalances(channel, weiBalances, tokenBalances, pendingWeiUpdates, pendingTokenUpdates); // transfer wei and token to recipient recipient.transfer(pendingWeiUpdates[3]); require(approvedToken.transfer(recipient, pendingTokenUpdates[3]), "user token withdrawal transfer failed"); // update state variables channel.txCount = txCount; channel.threadRoot = threadRoot; channel.threadCount = threadCount; emit DidUpdateChannel( msg.sender, 1, // senderIdx weiBalances, tokenBalances, pendingWeiUpdates, pendingTokenUpdates, channel.txCount, channel.threadRoot, channel.threadCount ); } /********************** * Unilateral Functions *********************/ // start exit with onchain state function startExit( address user ) public noReentrancy { require(user != hub, "user can not be hub"); require(user != address(this), "user can not be channel manager"); Channel storage channel = channels[user]; require(channel.status == ChannelStatus.Open, "channel must be open"); require(msg.sender == hub || msg.sender == user, "exit initiator must be user or hub"); channel.exitInitiator = msg.sender; channel.channelClosingTime = now.add(challengePeriod); channel.status = ChannelStatus.ChannelDispute; emit DidStartExitChannel( user, msg.sender == hub ? 0 : 1, [channel.weiBalances[0], channel.weiBalances[1]], [channel.tokenBalances[0], channel.tokenBalances[1]], channel.txCount, channel.threadRoot, channel.threadCount ); } // start exit with offchain state function startExitWithUpdate( address[2] user, // [user, recipient] uint256[2] weiBalances, // [hub, user] uint256[2] tokenBalances, // [hub, user] uint256[4] pendingWeiUpdates, // [hubDeposit, hubWithdrawal, userDeposit, userWithdrawal] uint256[4] pendingTokenUpdates, // [hubDeposit, hubWithdrawal, userDeposit, userWithdrawal] uint256[2] txCount, // [global, onchain] persisted onchain even when empty bytes32 threadRoot, uint256 threadCount, uint256 timeout, string sigHub, string sigUser ) public noReentrancy { Channel storage channel = channels[user[0]]; require(channel.status == ChannelStatus.Open, "channel must be open"); require(msg.sender == hub || msg.sender == user[0], "exit initiator must be user or hub"); require(timeout == 0, "can't start exit with time-sensitive states"); _verifySig( user, weiBalances, tokenBalances, pendingWeiUpdates, // [hubDeposit, hubWithdrawal, userDeposit, userWithdrawal] pendingTokenUpdates, // [hubDeposit, hubWithdrawal, userDeposit, userWithdrawal] txCount, threadRoot, threadCount, timeout, sigHub, sigUser, [true, true] // [checkHubSig?, checkUser] <- check both sigs ); require(txCount[0] > channel.txCount[0], "global txCount must be higher than the current global txCount"); require(txCount[1] >= channel.txCount[1], "onchain txCount must be higher or equal to the current onchain txCount"); // offchain wei/token balances do not exceed onchain total wei/token require(weiBalances[0].add(weiBalances[1]) <= channel.weiBalances[2], "wei must be conserved"); require(tokenBalances[0].add(tokenBalances[1]) <= channel.tokenBalances[2], "tokens must be conserved"); // pending onchain txs have been executed - force update offchain state to reflect this if (txCount[1] == channel.txCount[1]) { _applyPendingUpdates(channel.weiBalances, weiBalances, pendingWeiUpdates); _applyPendingUpdates(channel.tokenBalances, tokenBalances, pendingTokenUpdates); // pending onchain txs have *not* been executed - revert pending deposits and withdrawals back into offchain balances } else { //txCount[1] > channel.txCount[1] _revertPendingUpdates(channel.weiBalances, weiBalances, pendingWeiUpdates); _revertPendingUpdates(channel.tokenBalances, tokenBalances, pendingTokenUpdates); } // update state variables // only update txCount[0] (global) // - txCount[1] should only be updated by user/hubAuthorizedUpdate channel.txCount[0] = txCount[0]; channel.threadRoot = threadRoot; channel.threadCount = threadCount; channel.exitInitiator = msg.sender; channel.channelClosingTime = now.add(challengePeriod); channel.status = ChannelStatus.ChannelDispute; emit DidStartExitChannel( user[0], msg.sender == hub ? 0 : 1, [channel.weiBalances[0], channel.weiBalances[1]], [channel.tokenBalances[0], channel.tokenBalances[1]], channel.txCount, channel.threadRoot, channel.threadCount ); } // party that didn't start exit can challenge and empty function emptyChannelWithChallenge( address[2] user, uint256[2] weiBalances, // [hub, user] uint256[2] tokenBalances, // [hub, user] uint256[4] pendingWeiUpdates, // [hubDeposit, hubWithdrawal, userDeposit, userWithdrawal] uint256[4] pendingTokenUpdates, // [hubDeposit, hubWithdrawal, userDeposit, userWithdrawal] uint256[2] txCount, // persisted onchain even when empty bytes32 threadRoot, uint256 threadCount, uint256 timeout, string sigHub, string sigUser ) public noReentrancy { Channel storage channel = channels[user[0]]; require(channel.status == ChannelStatus.ChannelDispute, "channel must be in dispute"); require(now < channel.channelClosingTime, "channel closing time must not have passed"); require(msg.sender != channel.exitInitiator, "challenger can not be exit initiator"); require(msg.sender == hub || msg.sender == user[0], "challenger must be either user or hub"); require(timeout == 0, "can't start exit with time-sensitive states"); _verifySig( user, weiBalances, tokenBalances, pendingWeiUpdates, // [hubDeposit, hubWithdrawal, userDeposit, userWithdrawal] pendingTokenUpdates, // [hubDeposit, hubWithdrawal, userDeposit, userWithdrawal] txCount, threadRoot, threadCount, timeout, sigHub, sigUser, [true, true] // [checkHubSig?, checkUser] <- check both sigs ); require(txCount[0] > channel.txCount[0], "global txCount must be higher than the current global txCount"); require(txCount[1] >= channel.txCount[1], "onchain txCount must be higher or equal to the current onchain txCount"); // offchain wei/token balances do not exceed onchain total wei/token require(weiBalances[0].add(weiBalances[1]) <= channel.weiBalances[2], "wei must be conserved"); require(tokenBalances[0].add(tokenBalances[1]) <= channel.tokenBalances[2], "tokens must be conserved"); // pending onchain txs have been executed - force update offchain state to reflect this if (txCount[1] == channel.txCount[1]) { _applyPendingUpdates(channel.weiBalances, weiBalances, pendingWeiUpdates); _applyPendingUpdates(channel.tokenBalances, tokenBalances, pendingTokenUpdates); // pending onchain txs have *not* been executed - revert pending deposits and withdrawals back into offchain balances } else { //txCount[1] > channel.txCount[1] _revertPendingUpdates(channel.weiBalances, weiBalances, pendingWeiUpdates); _revertPendingUpdates(channel.tokenBalances, tokenBalances, pendingTokenUpdates); } // deduct hub/user wei/tokens from total channel balances channel.weiBalances[2] = channel.weiBalances[2].sub(channel.weiBalances[0]).sub(channel.weiBalances[1]); channel.tokenBalances[2] = channel.tokenBalances[2].sub(channel.tokenBalances[0]).sub(channel.tokenBalances[1]); // transfer hub wei balance from channel to reserves totalChannelWei = totalChannelWei.sub(channel.weiBalances[0]).sub(channel.weiBalances[1]); // transfer user wei balance to user user[0].transfer(channel.weiBalances[1]); channel.weiBalances[0] = 0; channel.weiBalances[1] = 0; // transfer hub token balance from channel to reserves totalChannelToken = totalChannelToken.sub(channel.tokenBalances[0]).sub(channel.tokenBalances[1]); // transfer user token balance to user require(approvedToken.transfer(user[0], channel.tokenBalances[1]), "user token withdrawal transfer failed"); channel.tokenBalances[0] = 0; channel.tokenBalances[1] = 0; // update state variables // only update txCount[0] (global) // - txCount[1] should only be updated by user/hubAuthorizedUpdate channel.txCount[0] = txCount[0]; channel.threadRoot = threadRoot; channel.threadCount = threadCount; if (channel.threadCount > 0) { channel.status = ChannelStatus.ThreadDispute; } else { channel.channelClosingTime = 0; channel.status = ChannelStatus.Open; } channel.exitInitiator = address(0x0); emit DidEmptyChannel( user[0], msg.sender == hub ? 0 : 1, [channel.weiBalances[0], channel.weiBalances[1]], [channel.tokenBalances[0], channel.tokenBalances[1]], channel.txCount, channel.threadRoot, channel.threadCount ); } // after timer expires - anyone can call; even before timer expires, non-exit-initiating party can call function emptyChannel( address user ) public noReentrancy { require(user != hub, "user can not be hub"); require(user != address(this), "user can not be channel manager"); Channel storage channel = channels[user]; require(channel.status == ChannelStatus.ChannelDispute, "channel must be in dispute"); require( channel.channelClosingTime < now || msg.sender != channel.exitInitiator && (msg.sender == hub || msg.sender == user), "channel closing time must have passed or msg.sender must be non-exit-initiating party" ); // deduct hub/user wei/tokens from total channel balances channel.weiBalances[2] = channel.weiBalances[2].sub(channel.weiBalances[0]).sub(channel.weiBalances[1]); channel.tokenBalances[2] = channel.tokenBalances[2].sub(channel.tokenBalances[0]).sub(channel.tokenBalances[1]); // transfer hub wei balance from channel to reserves totalChannelWei = totalChannelWei.sub(channel.weiBalances[0]).sub(channel.weiBalances[1]); // transfer user wei balance to user user.transfer(channel.weiBalances[1]); channel.weiBalances[0] = 0; channel.weiBalances[1] = 0; // transfer hub token balance from channel to reserves totalChannelToken = totalChannelToken.sub(channel.tokenBalances[0]).sub(channel.tokenBalances[1]); // transfer user token balance to user require(approvedToken.transfer(user, channel.tokenBalances[1]), "user token withdrawal transfer failed"); channel.tokenBalances[0] = 0; channel.tokenBalances[1] = 0; if (channel.threadCount > 0) { channel.status = ChannelStatus.ThreadDispute; } else { channel.channelClosingTime = 0; channel.status = ChannelStatus.Open; } channel.exitInitiator = address(0x0); emit DidEmptyChannel( user, msg.sender == hub ? 0 : 1, [channel.weiBalances[0], channel.weiBalances[1]], [channel.tokenBalances[0], channel.tokenBalances[1]], channel.txCount, channel.threadRoot, channel.threadCount ); } // ********************** // THREAD DISPUTE METHODS // ********************** // either party starts exit with initial state function startExitThread( address user, address sender, address receiver, uint256 threadId, uint256[2] weiBalances, // [sender, receiver] uint256[2] tokenBalances, // [sender, receiver] bytes proof, string sig ) public noReentrancy { Channel storage channel = channels[user]; require(channel.status == ChannelStatus.ThreadDispute, "channel must be in thread dispute phase"); require(msg.sender == hub || msg.sender == user, "thread exit initiator must be user or hub"); require(user == sender || user == receiver, "user must be thread sender or receiver"); require(weiBalances[1] == 0 && tokenBalances[1] == 0, "initial receiver balances must be zero"); Thread storage thread = threads[sender][receiver][threadId]; require(thread.threadClosingTime == 0, "thread closing time must be zero"); _verifyThread(sender, receiver, threadId, weiBalances, tokenBalances, 0, proof, sig, channel.threadRoot); thread.weiBalances = weiBalances; thread.tokenBalances = tokenBalances; thread.threadClosingTime = now.add(challengePeriod); emit DidStartExitThread( user, sender, receiver, threadId, msg.sender, thread.weiBalances, thread.tokenBalances, thread.txCount ); } // either party starts exit with offchain state function startExitThreadWithUpdate( address user, address[2] threadMembers, //[sender, receiver] uint256 threadId, uint256[2] weiBalances, // [sender, receiver] uint256[2] tokenBalances, // [sender, receiver] bytes proof, string sig, uint256[2] updatedWeiBalances, // [sender, receiver] uint256[2] updatedTokenBalances, // [sender, receiver] uint256 updatedTxCount, string updateSig ) public noReentrancy { Channel storage channel = channels[user]; require(channel.status == ChannelStatus.ThreadDispute, "channel must be in thread dispute phase"); require(msg.sender == hub || msg.sender == user, "thread exit initiator must be user or hub"); require(user == threadMembers[0] || user == threadMembers[1], "user must be thread sender or receiver"); require(weiBalances[1] == 0 && tokenBalances[1] == 0, "initial receiver balances must be zero"); Thread storage thread = threads[threadMembers[0]][threadMembers[1]][threadId]; require(thread.threadClosingTime == 0, "thread closing time must be zero"); _verifyThread(threadMembers[0], threadMembers[1], threadId, weiBalances, tokenBalances, 0, proof, sig, channel.threadRoot); // ********************* // PROCESS THREAD UPDATE // ********************* require(updatedTxCount > 0, "updated thread txCount must be higher than 0"); require(updatedWeiBalances[0].add(updatedWeiBalances[1]) == weiBalances[0], "sum of updated wei balances must match sender's initial wei balance"); require(updatedTokenBalances[0].add(updatedTokenBalances[1]) == tokenBalances[0], "sum of updated token balances must match sender's initial token balance"); // Note: explicitly set threadRoot == 0x0 because then it doesn't get checked by _isContained (updated state is not part of root) _verifyThread(threadMembers[0], threadMembers[1], threadId, updatedWeiBalances, updatedTokenBalances, updatedTxCount, "", updateSig, bytes32(0x0)); thread.weiBalances = updatedWeiBalances; thread.tokenBalances = updatedTokenBalances; thread.txCount = updatedTxCount; thread.threadClosingTime = now.add(challengePeriod); emit DidStartExitThread( user, threadMembers[0], threadMembers[1], threadId, msg.sender == hub ? 0 : 1, thread.weiBalances, thread.tokenBalances, thread.txCount ); } // either hub, sender, or receiver can update the thread state in place function challengeThread( address sender, address receiver, uint256 threadId, uint256[2] weiBalances, // updated weiBalances uint256[2] tokenBalances, // updated tokenBalances uint256 txCount, string sig ) public noReentrancy { require(msg.sender == hub || msg.sender == sender || msg.sender == receiver, "only hub, sender, or receiver can call this function"); Thread storage thread = threads[sender][receiver][threadId]; //verify that thread settlement period has not yet expired require(now < thread.threadClosingTime, "thread closing time must not have passed"); // assumes that the non-sender has a later thread state than what was being proposed when the thread exit started require(txCount > thread.txCount, "thread txCount must be higher than the current thread txCount"); require(weiBalances[0].add(weiBalances[1]) == thread.weiBalances[0].add(thread.weiBalances[1]), "updated wei balances must match sum of thread wei balances"); require(tokenBalances[0].add(tokenBalances[1]) == thread.tokenBalances[0].add(thread.tokenBalances[1]), "updated token balances must match sum of thread token balances"); require(weiBalances[1] >= thread.weiBalances[1] && tokenBalances[1] >= thread.tokenBalances[1], "receiver balances may never decrease"); // Note: explicitly set threadRoot == 0x0 because then it doesn't get checked by _isContained (updated state is not part of root) _verifyThread(sender, receiver, threadId, weiBalances, tokenBalances, txCount, "", sig, bytes32(0x0)); // save the thread balances and txCount thread.weiBalances = weiBalances; thread.tokenBalances = tokenBalances; thread.txCount = txCount; emit DidChallengeThread( sender, receiver, threadId, msg.sender, thread.weiBalances, thread.tokenBalances, thread.txCount ); } //After the thread state has been finalized onchain, emptyThread can be called to withdraw funds for each channel separately. function emptyThread( address user, address sender, address receiver, uint256 threadId, uint256[2] weiBalances, // [sender, receiver] -> initial balances uint256[2] tokenBalances, // [sender, receiver] -> initial balances bytes proof, string sig ) public noReentrancy { Channel storage channel = channels[user]; require(channel.status == ChannelStatus.ThreadDispute, "channel must be in thread dispute"); require(msg.sender == hub || msg.sender == user, "only hub or user can empty thread"); require(user == sender || user == receiver, "user must be thread sender or receiver"); require(weiBalances[1] == 0 && tokenBalances[1] == 0, "initial receiver balances must be zero"); Thread storage thread = threads[sender][receiver][threadId]; // We check to make sure that the thread state has been finalized require(thread.threadClosingTime != 0 && thread.threadClosingTime < now, "Thread closing time must have passed"); // Make sure user has not emptied before require(!thread.emptied[user == sender ? 0 : 1], "user cannot empty twice"); // verify initial thread state. _verifyThread(sender, receiver, threadId, weiBalances, tokenBalances, 0, proof, sig, channel.threadRoot); require(thread.weiBalances[0].add(thread.weiBalances[1]) == weiBalances[0], "sum of thread wei balances must match sender's initial wei balance"); require(thread.tokenBalances[0].add(thread.tokenBalances[1]) == tokenBalances[0], "sum of thread token balances must match sender's initial token balance"); // deduct sender/receiver wei/tokens about to be emptied from the thread from the total channel balances channel.weiBalances[2] = channel.weiBalances[2].sub(thread.weiBalances[0]).sub(thread.weiBalances[1]); channel.tokenBalances[2] = channel.tokenBalances[2].sub(thread.tokenBalances[0]).sub(thread.tokenBalances[1]); // deduct wei balances from total channel wei and reset thread balances totalChannelWei = totalChannelWei.sub(thread.weiBalances[0]).sub(thread.weiBalances[1]); // if user is receiver, send them receiver wei balance if (user == receiver) { user.transfer(thread.weiBalances[1]); // if user is sender, send them remaining sender wei balance } else if (user == sender) { user.transfer(thread.weiBalances[0]); } // deduct token balances from channel total balances and reset thread balances totalChannelToken = totalChannelToken.sub(thread.tokenBalances[0]).sub(thread.tokenBalances[1]); // if user is receiver, send them receiver token balance if (user == receiver) { require(approvedToken.transfer(user, thread.tokenBalances[1]), "user [receiver] token withdrawal transfer failed"); // if user is sender, send them remaining sender token balance } else if (user == sender) { require(approvedToken.transfer(user, thread.tokenBalances[0]), "user [sender] token withdrawal transfer failed"); } // Record that user has emptied thread.emptied[user == sender ? 0 : 1] = true; // decrement the channel threadCount channel.threadCount = channel.threadCount.sub(1); // if this is the last thread being emptied, re-open the channel if (channel.threadCount == 0) { channel.threadRoot = bytes32(0x0); channel.channelClosingTime = 0; channel.status = ChannelStatus.Open; } emit DidEmptyThread( user, sender, receiver, threadId, msg.sender, [channel.weiBalances[0], channel.weiBalances[1]], [channel.tokenBalances[0], channel.tokenBalances[1]], channel.txCount, channel.threadRoot, channel.threadCount ); } // anyone can call to re-open an account stuck in threadDispute after 10x challengePeriods from channel state finalization function nukeThreads( address user ) public noReentrancy { require(user != hub, "user can not be hub"); require(user != address(this), "user can not be channel manager"); Channel storage channel = channels[user]; require(channel.status == ChannelStatus.ThreadDispute, "channel must be in thread dispute"); require(channel.channelClosingTime.add(challengePeriod.mul(10)) < now, "channel closing time must have passed by 10 challenge periods"); // transfer any remaining channel wei to user totalChannelWei = totalChannelWei.sub(channel.weiBalances[2]); user.transfer(channel.weiBalances[2]); uint256 weiAmount = channel.weiBalances[2]; channel.weiBalances[2] = 0; // transfer any remaining channel tokens to user totalChannelToken = totalChannelToken.sub(channel.tokenBalances[2]); require(approvedToken.transfer(user, channel.tokenBalances[2]), "user token withdrawal transfer failed"); uint256 tokenAmount = channel.tokenBalances[2]; channel.tokenBalances[2] = 0; // reset channel params channel.threadCount = 0; channel.threadRoot = bytes32(0x0); channel.channelClosingTime = 0; channel.status = ChannelStatus.Open; emit DidNukeThreads( user, msg.sender, weiAmount, tokenAmount, [channel.weiBalances[0], channel.weiBalances[1]], [channel.tokenBalances[0], channel.tokenBalances[1]], channel.txCount, channel.threadRoot, channel.threadCount ); } function() external payable {} // ****************** // INTERNAL FUNCTIONS // ****************** function _verifyAuthorizedUpdate( Channel storage channel, uint256[2] txCount, uint256[2] weiBalances, uint256[2] tokenBalances, // [hub, user] uint256[4] pendingWeiUpdates, // [hubDeposit, hubWithdrawal, userDeposit, userWithdrawal] uint256[4] pendingTokenUpdates, // [hubDeposit, hubWithdrawal, userDeposit, userWithdrawal] uint256 timeout, bool isHub ) internal view { require(channel.status == ChannelStatus.Open, "channel must be open"); // Usage: // 1. exchange operations to protect user from exchange rate fluctuations // 2. protects hub against user delaying forever require(timeout == 0 || now < timeout, "the timeout must be zero or not have passed"); require(txCount[0] > channel.txCount[0], "global txCount must be higher than the current global txCount"); require(txCount[1] >= channel.txCount[1], "onchain txCount must be higher or equal to the current onchain txCount"); // offchain wei/token balances do not exceed onchain total wei/token require(weiBalances[0].add(weiBalances[1]) <= channel.weiBalances[2], "wei must be conserved"); require(tokenBalances[0].add(tokenBalances[1]) <= channel.tokenBalances[2], "tokens must be conserved"); // hub has enough reserves for wei/token deposits for both the user and itself (if isHub, user deposit comes from hub) if (isHub) { require(pendingWeiUpdates[0].add(pendingWeiUpdates[2]) <= getHubReserveWei(), "insufficient reserve wei for deposits"); require(pendingTokenUpdates[0].add(pendingTokenUpdates[2]) <= getHubReserveTokens(), "insufficient reserve tokens for deposits"); // hub has enough reserves for only its own wei/token deposits } else { require(pendingWeiUpdates[0] <= getHubReserveWei(), "insufficient reserve wei for deposits"); require(pendingTokenUpdates[0] <= getHubReserveTokens(), "insufficient reserve tokens for deposits"); } // wei is conserved - the current total channel wei + both deposits > final balances + both withdrawals require(channel.weiBalances[2].add(pendingWeiUpdates[0]).add(pendingWeiUpdates[2]) >= weiBalances[0].add(weiBalances[1]).add(pendingWeiUpdates[1]).add(pendingWeiUpdates[3]), "insufficient wei"); // token is conserved - the current total channel token + both deposits > final balances + both withdrawals require(channel.tokenBalances[2].add(pendingTokenUpdates[0]).add(pendingTokenUpdates[2]) >= tokenBalances[0].add(tokenBalances[1]).add(pendingTokenUpdates[1]).add(pendingTokenUpdates[3]), "insufficient token"); } function _applyPendingUpdates( uint256[3] storage channelBalances, uint256[2] balances, uint256[4] pendingUpdates ) internal { // update hub balance // If the deposit is greater than the withdrawal, add the net of deposit minus withdrawal to the balances. // Assumes the net has *not yet* been added to the balances. if (pendingUpdates[0] > pendingUpdates[1]) { channelBalances[0] = balances[0].add(pendingUpdates[0].sub(pendingUpdates[1])); // Otherwise, if the deposit is less than or equal to the withdrawal, // Assumes the net has *already* been added to the balances. } else { channelBalances[0] = balances[0]; } // update user balance // If the deposit is greater than the withdrawal, add the net of deposit minus withdrawal to the balances. // Assumes the net has *not yet* been added to the balances. if (pendingUpdates[2] > pendingUpdates[3]) { channelBalances[1] = balances[1].add(pendingUpdates[2].sub(pendingUpdates[3])); // Otherwise, if the deposit is less than or equal to the withdrawal, // Assumes the net has *already* been added to the balances. } else { channelBalances[1] = balances[1]; } } function _revertPendingUpdates( uint256[3] storage channelBalances, uint256[2] balances, uint256[4] pendingUpdates ) internal { // If the pending update has NOT been executed AND deposits > withdrawals, offchain state was NOT updated with delta, and is thus correct if (pendingUpdates[0] > pendingUpdates[1]) { channelBalances[0] = balances[0]; // If the pending update has NOT been executed AND deposits < withdrawals, offchain state should have been updated with delta, and must be reverted } else { channelBalances[0] = balances[0].add(pendingUpdates[1].sub(pendingUpdates[0])); // <- add withdrawal, sub deposit (opposite order as _applyPendingUpdates) } // If the pending update has NOT been executed AND deposits > withdrawals, offchain state was NOT updated with delta, and is thus correct if (pendingUpdates[2] > pendingUpdates[3]) { channelBalances[1] = balances[1]; // If the pending update has NOT been executed AND deposits > withdrawals, offchain state should have been updated with delta, and must be reverted } else { channelBalances[1] = balances[1].add(pendingUpdates[3].sub(pendingUpdates[2])); // <- add withdrawal, sub deposit (opposite order as _applyPendingUpdates) } } function _updateChannelBalances( Channel storage channel, uint256[2] weiBalances, uint256[2] tokenBalances, uint256[4] pendingWeiUpdates, uint256[4] pendingTokenUpdates ) internal { _applyPendingUpdates(channel.weiBalances, weiBalances, pendingWeiUpdates); _applyPendingUpdates(channel.tokenBalances, tokenBalances, pendingTokenUpdates); totalChannelWei = totalChannelWei.add(pendingWeiUpdates[0]).add(pendingWeiUpdates[2]).sub(pendingWeiUpdates[1]).sub(pendingWeiUpdates[3]); totalChannelToken = totalChannelToken.add(pendingTokenUpdates[0]).add(pendingTokenUpdates[2]).sub(pendingTokenUpdates[1]).sub(pendingTokenUpdates[3]); // update channel total balances channel.weiBalances[2] = channel.weiBalances[2].add(pendingWeiUpdates[0]).add(pendingWeiUpdates[2]).sub(pendingWeiUpdates[1]).sub(pendingWeiUpdates[3]); channel.tokenBalances[2] = channel.tokenBalances[2].add(pendingTokenUpdates[0]).add(pendingTokenUpdates[2]).sub(pendingTokenUpdates[1]).sub(pendingTokenUpdates[3]); } function _verifySig ( address[2] user, // [user, recipient] uint256[2] weiBalances, // [hub, user] uint256[2] tokenBalances, // [hub, user] uint256[4] pendingWeiUpdates, // [hubDeposit, hubWithdrawal, userDeposit, userWithdrawal] uint256[4] pendingTokenUpdates, // [hubDeposit, hubWithdrawal, userDeposit, userWithdrawal] uint256[2] txCount, // [global, onchain] persisted onchain even when empty bytes32 threadRoot, uint256 threadCount, uint256 timeout, string sigHub, string sigUser, bool[2] checks // [checkHubSig?, checkUserSig?] ) internal view { require(user[0] != hub, "user can not be hub"); require(user[0] != address(this), "user can not be channel manager"); // prepare state hash to check hub sig bytes32 state = keccak256( abi.encodePacked( address(this), user, // [user, recipient] weiBalances, // [hub, user] tokenBalances, // [hub, user] pendingWeiUpdates, // [hubDeposit, hubWithdrawal, userDeposit, userWithdrawal] pendingTokenUpdates, // [hubDeposit, hubWithdrawal, userDeposit, userWithdrawal] txCount, // persisted onchain even when empty threadRoot, threadCount, timeout ) ); if (checks[0]) { require(hub == ECTools.recoverSigner(state, sigHub), "hub signature invalid"); } if (checks[1]) { require(user[0] == ECTools.recoverSigner(state, sigUser), "user signature invalid"); } } function _verifyThread( address sender, address receiver, uint256 threadId, uint256[2] weiBalances, uint256[2] tokenBalances, uint256 txCount, bytes proof, string sig, bytes32 threadRoot ) internal view { require(sender != receiver, "sender can not be receiver"); require(sender != hub && receiver != hub, "hub can not be sender or receiver"); require(sender != address(this) && receiver != address(this), "channel manager can not be sender or receiver"); bytes32 state = keccak256( abi.encodePacked( address(this), sender, receiver, threadId, weiBalances, // [sender, receiver] tokenBalances, // [sender, receiver] txCount // persisted onchain even when empty ) ); require(ECTools.isSignedBy(state, sig, sender), "signature invalid"); if (threadRoot != bytes32(0x0)) { require(_isContained(state, proof, threadRoot), "initial thread state is not contained in threadRoot"); } } function _isContained(bytes32 _hash, bytes _proof, bytes32 _root) internal pure returns (bool) { bytes32 cursor = _hash; bytes32 proofElem; for (uint256 i = 64; i <= _proof.length; i += 32) { assembly { proofElem := mload(add(_proof, i)) } if (cursor < proofElem) { cursor = keccak256(abi.encodePacked(cursor, proofElem)); } else { cursor = keccak256(abi.encodePacked(proofElem, cursor)); } } return cursor == _root; } function getChannelBalances(address user) constant public returns ( uint256 weiHub, uint256 weiUser, uint256 weiTotal, uint256 tokenHub, uint256 tokenUser, uint256 tokenTotal ) { Channel memory channel = channels[user]; return ( channel.weiBalances[0], channel.weiBalances[1], channel.weiBalances[2], channel.tokenBalances[0], channel.tokenBalances[1], channel.tokenBalances[2] ); } function getChannelDetails(address user) constant public returns ( uint256 txCountGlobal, uint256 txCountChain, bytes32 threadRoot, uint256 threadCount, address exitInitiator, uint256 channelClosingTime, ChannelStatus status ) { Channel memory channel = channels[user]; return ( channel.txCount[0], channel.txCount[1], channel.threadRoot, channel.threadCount, channel.exitInitiator, channel.channelClosingTime, channel.status ); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"constant":true,"inputs":[],"name":"totalChannelWei","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"weiAmount","type":"uint256"},{"name":"tokenAmount","type":"uint256"}],"name":"hubContractWithdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"user","type":"address"},{"name":"threadMembers","type":"address[2]"},{"name":"threadId","type":"uint256"},{"name":"weiBalances","type":"uint256[2]"},{"name":"tokenBalances","type":"uint256[2]"},{"name":"proof","type":"bytes"},{"name":"sig","type":"string"},{"name":"updatedWeiBalances","type":"uint256[2]"},{"name":"updatedTokenBalances","type":"uint256[2]"},{"name":"updatedTxCount","type":"uint256"},{"name":"updateSig","type":"string"}],"name":"startExitThreadWithUpdate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"sender","type":"address"},{"name":"receiver","type":"address"},{"name":"threadId","type":"uint256"},{"name":"weiBalances","type":"uint256[2]"},{"name":"tokenBalances","type":"uint256[2]"},{"name":"txCount","type":"uint256"},{"name":"sig","type":"string"}],"name":"challengeThread","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalChannelToken","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"hub","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"user","type":"address"}],"name":"getChannelBalances","outputs":[{"name":"weiHub","type":"uint256"},{"name":"weiUser","type":"uint256"},{"name":"weiTotal","type":"uint256"},{"name":"tokenHub","type":"uint256"},{"name":"tokenUser","type":"uint256"},{"name":"tokenTotal","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"user","type":"address"}],"name":"emptyChannel","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"user","type":"address"},{"name":"recipient","type":"address"},{"name":"weiBalances","type":"uint256[2]"},{"name":"tokenBalances","type":"uint256[2]"},{"name":"pendingWeiUpdates","type":"uint256[4]"},{"name":"pendingTokenUpdates","type":"uint256[4]"},{"name":"txCount","type":"uint256[2]"},{"name":"threadRoot","type":"bytes32"},{"name":"threadCount","type":"uint256"},{"name":"timeout","type":"uint256"},{"name":"sigUser","type":"string"}],"name":"hubAuthorizedUpdate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"user","type":"address[2]"},{"name":"weiBalances","type":"uint256[2]"},{"name":"tokenBalances","type":"uint256[2]"},{"name":"pendingWeiUpdates","type":"uint256[4]"},{"name":"pendingTokenUpdates","type":"uint256[4]"},{"name":"txCount","type":"uint256[2]"},{"name":"threadRoot","type":"bytes32"},{"name":"threadCount","type":"uint256"},{"name":"timeout","type":"uint256"},{"name":"sigHub","type":"string"},{"name":"sigUser","type":"string"}],"name":"startExitWithUpdate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"user","type":"address"}],"name":"startExit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"user","type":"address"}],"name":"getChannelDetails","outputs":[{"name":"txCountGlobal","type":"uint256"},{"name":"txCountChain","type":"uint256"},{"name":"threadRoot","type":"bytes32"},{"name":"threadCount","type":"uint256"},{"name":"exitInitiator","type":"address"},{"name":"channelClosingTime","type":"uint256"},{"name":"status","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"user","type":"address"}],"name":"nukeThreads","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"channels","outputs":[{"name":"threadRoot","type":"bytes32"},{"name":"threadCount","type":"uint256"},{"name":"exitInitiator","type":"address"},{"name":"channelClosingTime","type":"uint256"},{"name":"status","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getHubReserveTokens","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"user","type":"address[2]"},{"name":"weiBalances","type":"uint256[2]"},{"name":"tokenBalances","type":"uint256[2]"},{"name":"pendingWeiUpdates","type":"uint256[4]"},{"name":"pendingTokenUpdates","type":"uint256[4]"},{"name":"txCount","type":"uint256[2]"},{"name":"threadRoot","type":"bytes32"},{"name":"threadCount","type":"uint256"},{"name":"timeout","type":"uint256"},{"name":"sigHub","type":"string"},{"name":"sigUser","type":"string"}],"name":"emptyChannelWithChallenge","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"NAME","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getHubReserveWei","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"user","type":"address"},{"name":"sender","type":"address"},{"name":"receiver","type":"address"},{"name":"threadId","type":"uint256"},{"name":"weiBalances","type":"uint256[2]"},{"name":"tokenBalances","type":"uint256[2]"},{"name":"proof","type":"bytes"},{"name":"sig","type":"string"}],"name":"emptyThread","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"approvedToken","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"user","type":"address"},{"name":"sender","type":"address"},{"name":"receiver","type":"address"},{"name":"threadId","type":"uint256"},{"name":"weiBalances","type":"uint256[2]"},{"name":"tokenBalances","type":"uint256[2]"},{"name":"proof","type":"bytes"},{"name":"sig","type":"string"}],"name":"startExitThread","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"recipient","type":"address"},{"name":"weiBalances","type":"uint256[2]"},{"name":"tokenBalances","type":"uint256[2]"},{"name":"pendingWeiUpdates","type":"uint256[4]"},{"name":"pendingTokenUpdates","type":"uint256[4]"},{"name":"txCount","type":"uint256[2]"},{"name":"threadRoot","type":"bytes32"},{"name":"threadCount","type":"uint256"},{"name":"timeout","type":"uint256"},{"name":"sigHub","type":"string"}],"name":"userAuthorizedUpdate","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"challengePeriod","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"VERSION","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_hub","type":"address"},{"name":"_challengePeriod","type":"uint256"},{"name":"_tokenAddress","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"weiAmount","type":"uint256"},{"indexed":false,"name":"tokenAmount","type":"uint256"}],"name":"DidHubContractWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"user","type":"address"},{"indexed":false,"name":"senderIdx","type":"uint256"},{"indexed":false,"name":"weiBalances","type":"uint256[2]"},{"indexed":false,"name":"tokenBalances","type":"uint256[2]"},{"indexed":false,"name":"pendingWeiUpdates","type":"uint256[4]"},{"indexed":false,"name":"pendingTokenUpdates","type":"uint256[4]"},{"indexed":false,"name":"txCount","type":"uint256[2]"},{"indexed":false,"name":"threadRoot","type":"bytes32"},{"indexed":false,"name":"threadCount","type":"uint256"}],"name":"DidUpdateChannel","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"user","type":"address"},{"indexed":false,"name":"senderIdx","type":"uint256"},{"indexed":false,"name":"weiBalances","type":"uint256[2]"},{"indexed":false,"name":"tokenBalances","type":"uint256[2]"},{"indexed":false,"name":"txCount","type":"uint256[2]"},{"indexed":false,"name":"threadRoot","type":"bytes32"},{"indexed":false,"name":"threadCount","type":"uint256"}],"name":"DidStartExitChannel","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"user","type":"address"},{"indexed":false,"name":"senderIdx","type":"uint256"},{"indexed":false,"name":"weiBalances","type":"uint256[2]"},{"indexed":false,"name":"tokenBalances","type":"uint256[2]"},{"indexed":false,"name":"txCount","type":"uint256[2]"},{"indexed":false,"name":"threadRoot","type":"bytes32"},{"indexed":false,"name":"threadCount","type":"uint256"}],"name":"DidEmptyChannel","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"user","type":"address"},{"indexed":true,"name":"sender","type":"address"},{"indexed":true,"name":"receiver","type":"address"},{"indexed":false,"name":"threadId","type":"uint256"},{"indexed":false,"name":"senderAddress","type":"address"},{"indexed":false,"name":"weiBalances","type":"uint256[2]"},{"indexed":false,"name":"tokenBalances","type":"uint256[2]"},{"indexed":false,"name":"txCount","type":"uint256"}],"name":"DidStartExitThread","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"sender","type":"address"},{"indexed":true,"name":"receiver","type":"address"},{"indexed":false,"name":"threadId","type":"uint256"},{"indexed":false,"name":"senderAddress","type":"address"},{"indexed":false,"name":"weiBalances","type":"uint256[2]"},{"indexed":false,"name":"tokenBalances","type":"uint256[2]"},{"indexed":false,"name":"txCount","type":"uint256"}],"name":"DidChallengeThread","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"user","type":"address"},{"indexed":true,"name":"sender","type":"address"},{"indexed":true,"name":"receiver","type":"address"},{"indexed":false,"name":"threadId","type":"uint256"},{"indexed":false,"name":"senderAddress","type":"address"},{"indexed":false,"name":"channelWeiBalances","type":"uint256[2]"},{"indexed":false,"name":"channelTokenBalances","type":"uint256[2]"},{"indexed":false,"name":"channelTxCount","type":"uint256[2]"},{"indexed":false,"name":"channelThreadRoot","type":"bytes32"},{"indexed":false,"name":"channelThreadCount","type":"uint256"}],"name":"DidEmptyThread","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"user","type":"address"},{"indexed":false,"name":"senderAddress","type":"address"},{"indexed":false,"name":"weiAmount","type":"uint256"},{"indexed":false,"name":"tokenAmount","type":"uint256"},{"indexed":false,"name":"channelWeiBalances","type":"uint256[2]"},{"indexed":false,"name":"channelTokenBalances","type":"uint256[2]"},{"indexed":false,"name":"channelTxCount","type":"uint256[2]"},{"indexed":false,"name":"channelThreadRoot","type":"bytes32"},{"indexed":false,"name":"channelThreadCount","type":"uint256"}],"name":"DidNukeThreads","type":"event"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060405160608062005e8683398101806040526200003391908101906200008e565b60008054600160a060020a03948516600160a060020a03199182161790915560019290925560028054919093169116179055620000f1565b6000620000798251620000e2565b9392505050565b6000620000798251620000ee565b600080600060608486031215620000a457600080fd5b6000620000b286866200006b565b9350506020620000c58682870162000080565b9250506040620000d8868287016200006b565b9150509250925092565b600160a060020a031690565b90565b615d8580620001016000396000f3006080604052600436106101235763ffffffff60e060020a6000350416629e8690811461012557806301dd7da9146101505780630955acd41461017057806325c29be01461019057806332b573e1146101b0578063365a86fc146101c557806345a92009146101e75780634e2a5c5a14610219578063686bf4601461023957806369f817761461025957806372cc174c1461027957806374c25c20146102995780637651a86b146102cc5780637dce34f7146102ec5780639bcf63cd1461031d578063a1e1fe9314610332578063a3f4df7e14610352578063ad872d0314610374578063b04993ef14610389578063bab46259146103a9578063c8b2f7d6146103cb578063ea682e37146103eb578063f3f480d9146103fe578063ffa1ad7414610413575b005b34801561013157600080fd5b5061013a610428565b6040516101479190615a0a565b60405180910390f35b34801561015c57600080fd5b5061012361016b366004614383565b61042e565b34801561017c57600080fd5b5061012361018b36600461403b565b610604565b34801561019c57600080fd5b506101236101ab366004613f86565b61099b565b3480156101bc57600080fd5b5061013a610c1e565b3480156101d157600080fd5b506101da610c24565b6040516101479190615393565b3480156101f357600080fd5b50610207610202366004613d5a565b610c33565b60405161014796959493929190615ad0565b34801561022557600080fd5b50610123610234366004613d5a565b610d8f565b34801561024557600080fd5b50610123610254366004613e7e565b611159565b34801561026557600080fd5b50610123610274366004614246565b611396565b34801561028557600080fd5b50610123610294366004613d5a565b61168c565b3480156102a557600080fd5b506102b96102b4366004613d5a565b611818565b6040516101479796959493929190615a68565b3480156102d857600080fd5b506101236102e7366004613d5a565b611982565b3480156102f857600080fd5b5061030c610307366004613d5a565b611c8a565b60405161014795949392919061555f565b34801561032957600080fd5b5061013a611cc9565b34801561033e57600080fd5b5061012361034d366004614246565b611d5c565b34801561035e57600080fd5b50610367612198565b6040516101479190615679565b34801561038057600080fd5b5061013a6121c4565b34801561039557600080fd5b506101236103a4366004613d9e565b6121dc565b3480156103b557600080fd5b506103be612871565b60405161014791906155ab565b3480156103d757600080fd5b506101236103e6366004613d9e565b612880565b6101236103f9366004614152565b612aaf565b34801561040a57600080fd5b5061013a612daf565b34801561041f57600080fd5b50610367612db5565b60035481565b60075460ff161561045d5760405160e560020a62461bcd028152600401610454906157ba565b60405180910390fd5b6007805460ff1916600117905560005433600160a060020a039091161461048357600080fd5b8161048c6121c4565b10156104ad5760405160e560020a62461bcd0281526004016104549061585a565b806104b6611cc9565b10156104d75760405160e560020a62461bcd028152600401610454906157ea565b60008054604051600160a060020a039091169184156108fc02918591818181858888f19350505050158015610510573d6000803e3d6000fd5b5060025460005460405160e060020a63a9059cbb028152600160a060020a039283169263a9059cbb9261054a9291169085906004016153cf565b602060405180830381600087803b15801561056457600080fd5b505af1158015610578573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061059c9190810190614347565b15156105bd5760405160e560020a62461bcd0281526004016104549061581a565b7f60a3ff34ec09137572f54ff0fde3035ae459c9bebfdb1643a897de83211ebdf082826040516105ee929190615a5a565b60405180910390a150506007805460ff19169055565b600754600090819060ff161561062f5760405160e560020a62461bcd028152600401610454906157ba565b6007805460ff19166001179055600160a060020a038d16600090815260056020526040902091506002600c83015460ff16600281111561066b57fe5b1461068b5760405160e560020a62461bcd0281526004016104549061598a565b600054600160a060020a03163314806106ac575033600160a060020a038e16145b15156106cd5760405160e560020a62461bcd028152600401610454906158ea565b8b51600160a060020a038e8116911614806106f7575060208c0151600160a060020a038e81169116145b15156107185760405160e560020a62461bcd028152600401610454906159fa565b60208a015115801561072c57506020890151155b151561074d5760405160e560020a62461bcd0281526004016104549061587a565b8b51600160a060020a03166000908152600660205260408120908d60016020020151600160a060020a0316600160a060020a0316815260200190815260200160002060008c81526020019081526020016000209050806005015460001415156107cb5760405160e560020a62461bcd0281526004016104549061579a565b6107ef8c600060200201518d600160200201518d8d8d60008e8e8a60080154612dd7565b600084116108125760405160e560020a62461bcd0281526004016104549061595a565b89516108358760015b60200201518860005b60200201519063ffffffff6130c016565b146108555760405160e560020a62461bcd0281526004016104549061589a565b885161086b8660015b6020020151876000610824565b1461088b5760405160e560020a62461bcd028152600401610454906157ca565b8b516020808e015160408051928301905260008083526108b693928f918b918b918b91908b90612dd7565b6108c281876002613aac565b506108d36002808301908790613aac565b50600481018490556001546108ef90429063ffffffff6130c016565b60058201558b60016020020151600160a060020a03168c60006020020151600160a060020a0316600080516020615ccc8339815191528f8e6000809054906101000a9004600160a060020a0316600160a060020a031633600160a060020a03161461095b57600161095e565b60005b600487015460405161097a9493929189916002830191906154e7565b60405180910390a350506007805460ff191690555050505050505050505050565b60075460009060ff16156109c45760405160e560020a62461bcd028152600401610454906157ba565b6007805460ff1916600117905560005433600160a060020a0390911614806109f4575033600160a060020a038916145b80610a07575033600160a060020a038816145b1515610a285760405160e560020a62461bcd028152600401610454906159ea565b50600160a060020a038088166000908152600660209081526040808320938a16835292815282822088835290522060058101544210610a7c5760405160e560020a62461bcd0281526004016104549061586a565b60048101548311610aa25760405160e560020a62461bcd028152600401610454906159da565b610abc81600101548260005b01549063ffffffff6130c016565b610ac786600161085e565b14610ae75760405160e560020a62461bcd0281526004016104549061574a565b6003810154610afb90600283016000610aae565b6020850151610b0c90866000610824565b14610b2c5760405160e560020a62461bcd0281526004016104549061583a565b6001810154602086015110801590610b4c57506003810154602085015110155b1515610b6d5760405160e560020a62461bcd0281526004016104549061571a565b610b928888888888886020604051908101604052806000815250896000600102612dd7565b610b9e81866002613aac565b50610baf6002808301908690613aac565b5060048101839055604051600160a060020a0380891691908a16907f738f3bb8a8a2b4d0dc29a4076d3a4e41e510cd1044877421546903039766ad1990610c02908a903390879060028201908b90615a18565b60405180910390a350506007805460ff19169055505050505050565b60045481565b600054600160a060020a031681565b600080600080600080610c44613aea565b600160a060020a03881660009081526005602052604090819020815161016081019092528161010081018260038282826020028201915b815481526020019060010190808311610c7b5750505091835250506040805160608101918290526020909201919060038481019182845b815481526020019060010190808311610cb2575050509183525050604080518082019182905260209092019190600684019060029082845b815481526020019060010190808311610cea5750505091835250506008820154602082015260098201546040820152600a820154600160a060020a03166060820152600b8201546080820152600c82015460a09091019060ff166002811115610d4f57fe5b6002811115610d5a57fe5b9052508051805160208083015160409384015194820151805192810151940151929d909c50939a509850909650945092505050565b60075460009060ff1615610db85760405160e560020a62461bcd028152600401610454906157ba565b6007805460ff19166001179055600054600160a060020a0383811691161415610df65760405160e560020a62461bcd0281526004016104549061592a565b600160a060020a038216301415610e225760405160e560020a62461bcd0281526004016104549061599a565b50600160a060020a03811660009081526005602052604090206001600c82015460ff166002811115610e5057fe5b14610e705760405160e560020a62461bcd0281526004016104549061573a565b4281600b01541080610eb65750600a810154600160a060020a03163314801590610eb65750600054600160a060020a0316331480610eb6575033600160a060020a038316145b1515610ed75760405160e560020a62461bcd028152600401610454906159aa565b610f048160015b01548254610ef8908460025b01549063ffffffff6130dd16565b9063ffffffff6130dd16565b8160020155610f266003820160015b0154600383018054610ef8916002610eea565b6005820155610f4c8160015b0154610ef88360005b01546003549063ffffffff6130dd16565b6003556001810154604051600160a060020a0384169180156108fc02916000818181858888f19350505050158015610f88573d6000803e3d6000fd5b5060008181015560008160010155610fbd6003820160015b0154610ef86003840160005b01546004549063ffffffff6130dd16565b600455600254600160a060020a031663a9059cbb8360038401600101546040518363ffffffff1660e060020a028152600401610ffa9291906153cf565b602060405180830381600087803b15801561101457600080fd5b505af1158015611028573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061104c9190810190614347565b151561106d5760405160e560020a62461bcd0281526004016104549061570a565b600060038201819055600482018190556009820154111561109c57600c8101805460ff191660021790556110b0565b6000600b820155600c8101805460ff191690555b600a81018054600160a060020a0319169055600054600160a060020a0383811691600080516020615d2c833981519152911633146110ef5760016110f2565b60005b6040805180820182528554815260018601546020808301919091528251808401845260038801548152600488015491810191909152600887015460098801549351611143959460068a019291615b1f565b60405180910390a250506007805460ff19169055565b60075460009060ff16156111825760405160e560020a62461bcd028152600401610454906157ba565b6007805460ff1916600117905560005433600160a060020a03909116146111a857600080fd5b50600160a060020a038b1660009081526005602052604090206111d281878c8c8c8c8960016130f4565b604080518082018252600160a060020a03808f1682528d166020808301919091528251808201845260008082528451808601909552845260019184019190915261122d928d918d918d918d918d918d918d918d918d906133b8565b61123a818b8b8b8b613781565b6060880151604051600160a060020a038d169180156108fc02916000818181858888f19350505050158015611273573d6000803e3d6000fd5b50600254606088015160405160e060020a63a9059cbb028152600160a060020a039092169163a9059cbb916112ad918f91906004016153cf565b602060405180830381600087803b1580156112c757600080fd5b505af11580156112db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506112ff9190810190614347565b15156113205760405160e560020a62461bcd0281526004016104549061570a565b61132f60068201876002613aac565b506008810185905560098101849055604051600160a060020a038d1690600080516020615cec83398151915290611376906000908e908e908e908e908e908e908e906155b9565b60405180910390a250506007805460ff1916905550505050505050505050565b60075460009060ff16156113bf5760405160e560020a62461bcd028152600401610454906157ba565b506007805460ff191660011790558a51600160a060020a0316600090815260056020526040812090600c82015460ff1660028111156113fa57fe5b1461141a5760405160e560020a62461bcd0281526004016104549061577a565b600054600160a060020a031633148061143c57508b51600160a060020a031633145b151561145d5760405160e560020a62461bcd0281526004016104549061597a565b831561147e5760405160e560020a62461bcd0281526004016104549061582a565b6114b08c8c8c8c8c8c8c8c8c8c8c604080519081016040528060011515151581526020016001151515158152506133b8565b60068101548751116114d75760405160e560020a62461bcd028152600401610454906158aa565b6007810154602088015110156115025760405160e560020a62461bcd028152600401610454906156aa565b806002015461151b8c60015b60200201518d6000610824565b111561153c5760405160e560020a62461bcd028152600401610454906156ca565b60058101546115558b60015b60200201518c6000610824565b11156115765760405160e560020a62461bcd0281526004016104549061584a565b6007810154602088015114156115a457611591818c8b613852565b61159f816003018b8a613852565b6115bd565b6115af818c8b6138e0565b6115bd816003018b8a6138e0565b865160068201556008810186905560098101859055600a81018054600160a060020a031916331790556001546115f49042906130c0565b600b820155600c8101805460ff191660011790558b51600054600160a060020a0391821691600080516020615cac833981519152913391161461163857600161163b565b60005b6040805180820182528554815260018601546020808301919091528251808401845260038801548152600488015491810191909152600887015460098801549351611376959460068a019291615b1f565b60075460009060ff16156116b55760405160e560020a62461bcd028152600401610454906157ba565b6007805460ff19166001179055600054600160a060020a03838116911614156116f35760405160e560020a62461bcd0281526004016104549061592a565b600160a060020a03821630141561171f5760405160e560020a62461bcd0281526004016104549061599a565b50600160a060020a038116600090815260056020526040812090600c82015460ff16600281111561174c57fe5b1461176c5760405160e560020a62461bcd0281526004016104549061577a565b600054600160a060020a031633148061178d575033600160a060020a038316145b15156117ae5760405160e560020a62461bcd0281526004016104549061597a565b600a81018054600160a060020a031916331790556001546117d690429063ffffffff6130c016565b600b820155600c8101805460ff19166001179055600054600160a060020a0383811691600080516020615cac83398151915291339116146110ef5760016110f2565b600080600080600080600061182b613aea565b600160a060020a03891660009081526005602052604090819020815161016081019092528161010081018260038282826020028201915b8154815260200190600101908083116118625750505091835250506040805160608101918290526020909201919060038481019182845b815481526020019060010190808311611899575050509183525050604080518082019182905260209092019190600684019060029082845b8154815260200190600101908083116118d15750505091835250506008820154602082015260098201546040820152600a820154600160a060020a03166060820152600b8201546080820152600c82015460a09091019060ff16600281111561193657fe5b600281111561194157fe5b905250604081015180516020909101516060830151608084015160a085015160c086015160e090960151949f939e50919c509a509850919650945092505050565b6007546000908190819060ff16156119af5760405160e560020a62461bcd028152600401610454906157ba565b6007805460ff19166001179055600054600160a060020a03858116911614156119ed5760405160e560020a62461bcd0281526004016104549061592a565b600160a060020a038416301415611a195760405160e560020a62461bcd0281526004016104549061599a565b600160a060020a038416600090815260056020526040902092506002600c84015460ff166002811115611a4857fe5b14611a685760405160e560020a62461bcd0281526004016104549061590a565b42611a93611a82600a60015461394690919063ffffffff16565b600b8601549063ffffffff6130c016565b10611ab35760405160e560020a62461bcd0281526004016104549061569a565b611abe836002610f3b565b6003556002830154604051600160a060020a0386169180156108fc02916000818181858888f19350505050158015611afa573d6000803e3d6000fd5b508260020154915060008360020155611b17600384016002610fac565b6004908155600254600585015460405160e060020a63a9059cbb028152600160a060020a039092169263a9059cbb92611b549289929091016153cf565b602060405180830381600087803b158015611b6e57600080fd5b505af1158015611b82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611ba69190810190614347565b1515611bc75760405160e560020a62461bcd0281526004016104549061570a565b506005820180546000918290556009840182905560088401829055600b8401829055600c8401805460ff19169055604080518082018252855481526001860154602080830191909152825180840184526003880154815260048801549181019190915291519293600160a060020a038816937f02d2d0f262d032138bbd82feccd6d357a4441f394333cfa7d61792f44a70a0ed93611c72933393899389939160068d019181906154be565b60405180910390a250506007805460ff191690555050565b600560205260009081526040902060088101546009820154600a830154600b840154600c9094015492939192600160a060020a03909116919060ff1685565b6004805460025460405160e060020a6370a08231028152600093611d569392600160a060020a0316916370a0823191611d0491309101615393565b602060405180830381600087803b158015611d1e57600080fd5b505af1158015611d32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ef89190810190614365565b90505b90565b60075460009060ff1615611d855760405160e560020a62461bcd028152600401610454906157ba565b506007805460ff191660019081179091558b51600160a060020a0316600090815260056020526040902090600c82015460ff166002811115611dc357fe5b14611de35760405160e560020a62461bcd0281526004016104549061573a565b600b8101544210611e095760405160e560020a62461bcd028152600401610454906156fa565b600a810154600160a060020a0316331415611e395760405160e560020a62461bcd0281526004016104549061578a565b600054600160a060020a0316331480611e5b57508b51600160a060020a031633145b1515611e7c5760405160e560020a62461bcd0281526004016104549061588a565b8315611e9d5760405160e560020a62461bcd0281526004016104549061582a565b611ecf8c8c8c8c8c8c8c8c8c8c8c604080519081016040528060011515151581526020016001151515158152506133b8565b6006810154875111611ef65760405160e560020a62461bcd028152600401610454906158aa565b600781015460208801511015611f215760405160e560020a62461bcd028152600401610454906156aa565b8060020154611f318c600161150e565b1115611f525760405160e560020a62461bcd028152600401610454906156ca565b6005810154611f628b6001611548565b1115611f835760405160e560020a62461bcd0281526004016104549061584a565b600781015460208801511415611fb157611f9e818c8b613852565b611fac816003018b8a613852565b611fca565b611fbc818c8b6138e0565b611fca816003018b8a6138e0565b611fd5816001610ede565b8160020155611fe8600382016001610f13565b6005820155611ff8816001610f32565b6003558b516001820154604051600160a060020a039092169181156108fc0291906000818181858888f19350505050158015612038573d6000803e3d6000fd5b5060008181015560008160010155612054600382016001610fa0565b60049081556002548d518383015460405160e060020a63a9059cbb028152600160a060020a039093169363a9059cbb93612090939291016153cf565b602060405180830381600087803b1580156120aa57600080fd5b505af11580156120be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506120e29190810190614347565b15156121035760405160e560020a62461bcd0281526004016104549061570a565b6000600382018190556004820181905587516006830155600882018790556009820186905585111561214357600c8101805460ff19166002179055612157565b6000600b820155600c8101805460ff191690555b600a81018054600160a060020a03191690558b51600054600160a060020a0391821691600080516020615d2c8339815191529116331461163857600161163b565b60408051808201909152600f8152608960020a6e21b430b73732b61026b0b730b3b2b902602082015281565b600354600090611d569030319063ffffffff6130dd16565b600754600090819060ff16156122075760405160e560020a62461bcd028152600401610454906157ba565b6007805460ff19166001179055600160a060020a038a16600090815260056020526040902091506002600c83015460ff16600281111561224357fe5b146122635760405160e560020a62461bcd0281526004016104549061590a565b600054600160a060020a0316331480612284575033600160a060020a038b16145b15156122a55760405160e560020a62461bcd028152600401610454906156ba565b88600160a060020a03168a600160a060020a031614806122d6575087600160a060020a03168a600160a060020a0316145b15156122f75760405160e560020a62461bcd028152600401610454906159fa565b602086015115801561230b57506020850151155b151561232c5760405160e560020a62461bcd0281526004016104549061587a565b50600160a060020a038089166000908152600660209081526040808320938b1683529281528282208983529052206005810154158015906123705750428160050154105b15156123915760405160e560020a62461bcd0281526004016104549061591a565b8060060189600160a060020a03168b600160a060020a0316146123b55760016123b8565b60005b60ff16600281106123c557fe5b602081049091015460ff601f9092166101000a900416156123fb5760405160e560020a62461bcd0281526004016104549061580a565b612411898989898960008a8a8a60080154612dd7565b8551600182015461242490836000610aae565b146124445760405160e560020a62461bcd028152600401610454906158ca565b8451600382015461245a90600284016000610aae565b1461247a5760405160e560020a62461bcd0281526004016104549061593a565b6124928160010154610ef88360000154856002610eea565b82600201556124b86002820160010154610ef86002840160000154600386016002610eea565b600583015560018101546124d190610ef8836000610f3b565b600355600160a060020a038a81169089161415612527576001810154604051600160a060020a038c169180156108fc02916000818181858888f19350505050158015612521573d6000803e3d6000fd5b50612579565b88600160a060020a03168a600160a060020a03161415612579578054604051600160a060020a038c169180156108fc02916000818181858888f19350505050158015612577573d6000803e3d6000fd5b505b600381015461259090610ef8600284016000610fac565b600455600160a060020a038a8116908916141561265857600254600382015460405160e060020a63a9059cbb028152600160a060020a039092169163a9059cbb916125e0918e91906004016153cf565b602060405180830381600087803b1580156125fa57600080fd5b505af115801561260e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506126329190810190614347565b15156126535760405160e560020a62461bcd028152600401610454906159ba565b61271e565b88600160a060020a03168a600160a060020a0316141561271e57600280549082015460405160e060020a63a9059cbb028152600160a060020a039092169163a9059cbb916126ab918e91906004016153cf565b602060405180830381600087803b1580156126c557600080fd5b505af11580156126d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506126fd9190810190614347565b151561271e5760405160e560020a62461bcd0281526004016104549061596a565b6001816006018a600160a060020a03168c600160a060020a031614612744576001612747565b60005b60ff166002811061275457fe5b602091828204019190066101000a81548160ff02191690831515021790555061278b600183600901546130dd90919063ffffffff16565b6009830181905515156127b357600060088301819055600b830155600c8201805460ff191690555b87600160a060020a031689600160a060020a03167ff45587a14ff8928bdd940cbf0564b42320b5e46a8fdecaf8a98a9eab63ab1f968c8a33604080519081016040528089600001600060038110151561280857fe5b0154815260018a015460209182015260408051808201825260038c0154815260048c01549281019290925260088b015460098c0154915161285397969594939260068e0192916153ea565b60405180910390a350506007805460ff191690555050505050505050565b600254600160a060020a031681565b600754600090819060ff16156128ab5760405160e560020a62461bcd028152600401610454906157ba565b6007805460ff19166001179055600160a060020a038a16600090815260056020526040902091506002600c83015460ff1660028111156128e757fe5b146129075760405160e560020a62461bcd0281526004016104549061598a565b600054600160a060020a0316331480612928575033600160a060020a038b16145b15156129495760405160e560020a62461bcd028152600401610454906158ea565b88600160a060020a03168a600160a060020a0316148061297a575087600160a060020a03168a600160a060020a0316145b151561299b5760405160e560020a62461bcd028152600401610454906159fa565b60208601511580156129af57506020850151155b15156129d05760405160e560020a62461bcd0281526004016104549061587a565b50600160a060020a038089166000908152600660209081526040808320938b168352928152828220898352905220600581015415612a235760405160e560020a62461bcd0281526004016104549061579a565b612a39898989898960008a8a8a60080154612dd7565b612a4581876002613aac565b50612a566002808301908790613aac565b50600154612a6b90429063ffffffff6130c016565b60058201556004810154604051600160a060020a03808b1692908c1691600080516020615ccc83398151915291612853918f918d9133918991600283019190615463565b60075460009060ff1615612ad85760405160e560020a62461bcd028152600401610454906157ba565b6007805460ff1916600117905587600260200201513414612b0e5760405160e560020a62461bcd028152600401610454906159ca565b6005600033600160a060020a0316600160a060020a031681526020019081526020016000209050612b4681878c8c8c8c8960006130f4565b604080518082018252338152600160a060020a038d1660208083019190915282518082018452600080825284518086019095526001855291840191909152612ba0928d918d918d918d918d918d918d918d918d91906133b8565b600254604080890151905160e060020a6323b872dd028152600160a060020a03909216916323b872dd91612bda91339130916004016153a7565b602060405180830381600087803b158015612bf457600080fd5b505af1158015612c08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612c2c9190810190614347565b1515612c4d5760405160e560020a62461bcd028152600401610454906158da565b612c5a818b8b8b8b613781565b6060880151604051600160a060020a038d169180156108fc02916000818181858888f19350505050158015612c93573d6000803e3d6000fd5b50600254606088015160405160e060020a63a9059cbb028152600160a060020a039092169163a9059cbb91612ccd918f91906004016153cf565b602060405180830381600087803b158015612ce757600080fd5b505af1158015612cfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612d1f9190810190614347565b1515612d405760405160e560020a62461bcd0281526004016104549061570a565b612d4f60068201876002613aac565b5060088101859055600981018490556040513390600080516020615cec83398151915290612d90906001908e908e908e908e9060068a01908e908e90615627565b60405180910390a250506007805460ff19169055505050505050505050565b60015481565b604080518082019091526005815260d860020a64302e302e3102602082015281565b6000600160a060020a038a8116908a161415612e085760405160e560020a62461bcd028152600401610454906157aa565b600054600160a060020a038b8116911614801590612e345750600054600160a060020a038a8116911614155b1515612e555760405160e560020a62461bcd028152600401610454906158ba565b600160a060020a038a163014801590612e775750600160a060020a0389163014155b1515612e985760405160e560020a62461bcd028152600401610454906156ea565b308a8a8a8a8a8a6040516020018088600160a060020a0316600160a060020a0316606060020a02815260140187600160a060020a0316600160a060020a0316606060020a02815260140186600160a060020a0316600160a060020a0316606060020a02815260140185815260200184600260200280838360005b83811015612f2a578181015183820152602001612f12565b5050505090500183600260200280838360005b83811015612f55578181015183820152602001612f3d565b505050509050018281526020019750505050505050506040516020818303038152906040526040518082805190602001908083835b60208310612fa95780518252601f199092019160209182019101612f8a565b5181516020939093036101000a60001901801990911692169190911790526040519201829003822060e060020a631052506f028352945073b01c6adaf785f06f2c01bcfe782e30ceefa90a269350631052506f92506130119185915087908f90600401615530565b60206040518083038186803b15801561302957600080fd5b505af415801561303d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506130619190810190614347565b15156130825760405160e560020a62461bcd028152600401610454906156da565b81156130b457613093818584613974565b15156130b45760405160e560020a62461bcd0281526004016104549061575a565b50505050505050505050565b6000828201838110156130d257600080fd5b8091505b5092915050565b600080838311156130ed57600080fd5b5050900390565b6000600c89015460ff16600281111561310957fe5b146131295760405160e560020a62461bcd0281526004016104549061577a565b81158061313557508142105b15156131565760405160e560020a62461bcd0281526004016104549061594a565b600688015487511161317d5760405160e560020a62461bcd028152600401610454906158aa565b6007880154602088015110156131a85760405160e560020a62461bcd028152600401610454906156aa565b87600201546131b887600161081b565b11156131d95760405160e560020a62461bcd028152600401610454906156ca565b60058801546131e986600161085e565b111561320a5760405160e560020a62461bcd0281526004016104549061584a565b8015613289576132186121c4565b604085015161322990866000610824565b111561324a5760405160e560020a62461bcd028152600401610454906158fa565b613252611cc9565b604084015161326390856000610824565b11156132845760405160e560020a62461bcd028152600401610454906157fa565b6132df565b6132916121c4565b845111156132b45760405160e560020a62461bcd028152600401610454906158fa565b6132bc611cc9565b835111156132df5760405160e560020a62461bcd028152600401610454906157fa565b60608401516020808601519088015161330d92916133019182908b6000610824565b9063ffffffff6130c016565b604085015161332a906133018760005b60200201518c6002610aae565b101561334b5760405160e560020a62461bcd0281526004016104549061568a565b60608301516020808501519087015161336d92916133019182908a6000610824565b604084015161338d906133018660005b602002015160038d016002610aae565b10156133ae5760405160e560020a62461bcd0281526004016104549061576a565b5050505050505050565b600080548d51600160a060020a03908116911614156133ec5760405160e560020a62461bcd0281526004016104549061592a565b8c51600160a060020a03163014156134195760405160e560020a62461bcd0281526004016104549061599a565b308d8d8d8d8d8d8d8d8d604051602001808b600160a060020a0316600160a060020a0316606060020a0281526014018a600260200280838360005b8381101561346c578181015183820152602001613454565b5050505090500189600260200280838360005b8381101561349757818101518382015260200161347f565b5050505090500188600260200280838360005b838110156134c25781810151838201526020016134aa565b5050505090500187600460200280838360005b838110156134ed5781810151838201526020016134d5565b5050505090500186600460200280838360005b83811015613518578181015183820152602001613500565b5050505090500185600260200280838360005b8381101561354357818101518382015260200161352b565b5050505090500184600019166000191681526020018381526020018281526020019a50505050505050505050506040516020818303038152906040526040518082805190602001908083835b602083106135ae5780518252601f19909201916020918201910161358f565b5181516020939093036101000a600019018019909116921691909117905260405192018290039091209350849250600091506135e79050565b6020020151156136ad5760405160e060020a63dca9541902815273b01c6adaf785f06f2c01bcfe782e30ceefa90a269063dca954199061362d9084908890600401615510565b60206040518083038186803b15801561364557600080fd5b505af4158015613659573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061367d9190810190613d80565b600054600160a060020a039081169116146136ad5760405160e560020a62461bcd0281526004016104549061572a565b6020820151156137725760405160e060020a63dca9541902815273b01c6adaf785f06f2c01bcfe782e30ceefa90a269063dca95419906136f39084908790600401615510565b60206040518083038186803b15801561370b57600080fd5b505af415801561371f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506137439190810190613d80565b8d51600160a060020a039081169116146137725760405160e560020a62461bcd028152600401610454906157da565b50505050505050505050505050565b61378c858584613852565b61379a856003018483613852565b60608201516020830151604084015184516003546137c49493610ef89390928492613301916130c0565b60035560608101516020820151604083015183516004546137f19493610ef89390928492613301916130c0565b6004556060820151602083015160408401516138199291610ef891829061330188600061331d565b60028601556060810151602082015160408301516138439291610ef891829061330187600061337d565b60038601600201555050505050565b6020810151815111156138915761388a61388282600160200201518360005b60200201519063ffffffff6130dd16565b836000610824565b8355613896565b815183555b6060810151604082015111156138cf576138c46138bc8260036020020151836002613871565b836001610824565b8360015b01556138db565b60208201518360015b01555b505050565b6020810151815111156138f6578151835561390b565b80516139089061388290836001613871565b83555b6060810151604082015111156139285760208201518360016138c8565b61393e6138bc8260026020020151836003613871565b8360016138d8565b60008083151561395957600091506130d6565b5082820282848281151561396957fe5b04146130d257600080fd5b6000838160405b85518111613a9f5785810151915081831015613a1657604080516020808201869052818301859052825180830384018152606090920192839052815191929182918401908083835b602083106139e25780518252601f1990920191602091820191016139c3565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390209250613a97565b604080516020808201859052818301869052825180830384018152606090920192839052815191929182918401908083835b60208310613a675780518252601f199092019160209182019101613a48565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902092505b60200161397b565b5050919091149392505050565b8260028101928215613ada579160200282015b82811115613ada578251825591602001919060010190613abf565b50613ae6929150613b42565b5090565b6101a060405190810160405280613aff613b5c565b8152602001613b0c613b5c565b8152602001613b19613b7b565b815260006020820181905260408201819052606082018190526080820181905260a09091015290565b611d5991905b80821115613ae65760008155600101613b48565b6060604051908101604052806003906020820280388339509192915050565b60408051808201825290600290829080388339509192915050565b6000613ba28235615bf6565b9392505050565b6000613ba28251615bf6565b6000601f82018313613bc657600080fd5b6002613bd9613bd482615b96565b615b70565b91508183856020840282011115613bef57600080fd5b60005b83811015613c1b5781613c058882613b96565b8452506020928301929190910190600101613bf2565b5050505092915050565b6000601f82018313613c3657600080fd5b6002613c44613bd482615b96565b91508183856020840282011115613c5a57600080fd5b60005b83811015613c1b5781613c708882613cf3565b8452506020928301929190910190600101613c5d565b6000601f82018313613c9757600080fd5b6004613ca5613bd482615b96565b91508183856020840282011115613cbb57600080fd5b60005b83811015613c1b5781613cd18882613cf3565b8452506020928301929190910190600101613cbe565b6000613ba28251615c14565b6000613ba28235611d59565b6000601f82018313613d1057600080fd5b8135613d1e613bd482615bb3565b91508082526020830160208301858383011115613d3a57600080fd5b613d45838284615c45565b50505092915050565b6000613ba28251611d59565b600060208284031215613d6c57600080fd5b6000613d788484613b96565b949350505050565b600060208284031215613d9257600080fd5b6000613d788484613ba9565b600080600080600080600080610140898b031215613dbb57600080fd5b6000613dc78b8b613b96565b9850506020613dd88b828c01613b96565b9750506040613de98b828c01613b96565b9650506060613dfa8b828c01613cf3565b9550506080613e0b8b828c01613c25565b94505060c0613e1c8b828c01613c25565b9350506101008901356001604060020a03811115613e3957600080fd5b613e458b828c01613cff565b9250506101208901356001604060020a03811115613e6257600080fd5b613e6e8b828c01613cff565b9150509295985092959890939650565b60008060008060008060008060008060006102808c8e031215613ea057600080fd5b6000613eac8e8e613b96565b9b50506020613ebd8e828f01613b96565b9a50506040613ece8e828f01613c25565b9950506080613edf8e828f01613c25565b98505060c0613ef08e828f01613c86565b975050610140613f028e828f01613c86565b9650506101c0613f148e828f01613c25565b955050610200613f268e828f01613cf3565b945050610220613f388e828f01613cf3565b935050610240613f4a8e828f01613cf3565b9250506102608c01356001604060020a03811115613f6757600080fd5b613f738e828f01613cff565b9150509295989b509295989b9093969950565b6000806000806000806000610120888a031215613fa257600080fd5b6000613fae8a8a613b96565b9750506020613fbf8a828b01613b96565b9650506040613fd08a828b01613cf3565b9550506060613fe18a828b01613c25565b94505060a0613ff28a828b01613c25565b93505060e06140038a828b01613cf3565b9250506101008801356001604060020a0381111561402057600080fd5b61402c8a828b01613cff565b91505092959891949750929550565b60008060008060008060008060008060006102008c8e03121561405d57600080fd5b60006140698e8e613b96565b9b5050602061407a8e828f01613bb5565b9a5050606061408b8e828f01613cf3565b995050608061409c8e828f01613c25565b98505060c06140ad8e828f01613c25565b9750506101008c01356001604060020a038111156140ca57600080fd5b6140d68e828f01613cff565b9650506101208c01356001604060020a038111156140f357600080fd5b6140ff8e828f01613cff565b9550506101406141118e828f01613c25565b9450506101806141238e828f01613c25565b9350506101c06141358e828f01613cf3565b9250506101e08c01356001604060020a03811115613f6757600080fd5b6000806000806000806000806000806102608b8d03121561417257600080fd5b600061417e8d8d613b96565b9a5050602061418f8d828e01613c25565b99505060606141a08d828e01613c25565b98505060a06141b18d828e01613c86565b9750506101206141c38d828e01613c86565b9650506101a06141d58d828e01613c25565b9550506101e06141e78d828e01613cf3565b9450506102006141f98d828e01613cf3565b93505061022061420b8d828e01613cf3565b9250506102408b01356001604060020a0381111561422857600080fd5b6142348d828e01613cff565b9150509295989b9194979a5092959850565b60008060008060008060008060008060006102a08c8e03121561426857600080fd5b60006142748e8e613bb5565b9b505060406142858e828f01613c25565b9a505060806142968e828f01613c25565b99505060c06142a78e828f01613c86565b9850506101406142b98e828f01613c86565b9750506101c06142cb8e828f01613c25565b9650506102006142dd8e828f01613cf3565b9550506102206142ef8e828f01613cf3565b9450506102406143018e828f01613cf3565b9350506102608c01356001604060020a0381111561431e57600080fd5b61432a8e828f01613cff565b9250506102808c01356001604060020a03811115613f6757600080fd5b60006020828403121561435957600080fd5b6000613d788484613ce7565b60006020828403121561437757600080fd5b6000613d788484613d4e565b6000806040838503121561439657600080fd5b60006143a28585613cf3565b92505060206143b385828601613cf3565b9150509250929050565b6143c681615bf6565b82525050565b6143d581615bda565b6143de82611d59565b60005b8281101561440e576143f4858351614499565b6143fd82615bea565b6020959095019491506001016143e1565b5050505050565b61441e81615bda565b61442782611d59565b60005b8281101561440e5761443d858354614499565b61444682615bf0565b60209590950194915060010161442a565b61446081615be0565b61446982611d59565b60005b8281101561440e5761447f858351614499565b61448882615bea565b60209590950194915060010161446c565b6143c681611d59565b6143c681615c19565b6143c681615c24565b6143c681615c2f565b60006144c882615be6565b8084526144dc816020860160208601615c51565b6144e581615c81565b9093016020019392505050565b60108152608060020a6f696e73756666696369656e742077656902602082015260400190565b603d8152600080516020615d0c83398151915260208201527f6173736564206279203130206368616c6c656e676520706572696f6473000000604082015260600190565b604681527f6f6e636861696e207478436f756e74206d75737420626520686967686572206f60208201527f7220657175616c20746f207468652063757272656e74206f6e636861696e2074604082015260d260020a651e10dbdd5b9d02606082015260800190565b602181527f6f6e6c7920687562206f7220757365722063616e20656d707479207468726561602082015260fa60020a601902604082015260600190565b60158152605a60020a741dd95a481b5d5cdd0818994818dbdb9cd95c9d995902602082015260400190565b60118152607a60020a701cda59db985d1d5c99481a5b9d985b1a5902602082015260400190565b602d81527f6368616e6e656c206d616e616765722063616e206e6f742062652073656e64656020820152609960020a6c391037b9103932b1b2b4bb32b902604082015260600190565b602981527f6368616e6e656c20636c6f73696e672074696d65206d757374206e6f74206861602082015260ba60020a681d99481c185cdcd95902604082015260600190565b602581527f7573657220746f6b656e207769746864726177616c207472616e736665722066602082015260da60020a64185a5b195902604082015260600190565b602481527f72656365697665722062616c616e636573206d6179206e657665722064656372602082015260e060020a636561736502604082015260600190565b60158152605a60020a741a1d58881cda59db985d1d5c99481a5b9d985b1a5902602082015260400190565b601a81527f6368616e6e656c206d75737420626520696e2064697370757465000000000000602082015260400190565b603a81527f75706461746564207765692062616c616e636573206d757374206d617463682060208201527f73756d206f6620746872656164207765692062616c616e636573000000000000604082015260600190565b603381527f696e697469616c20746872656164207374617465206973206e6f7420636f6e746020820152606a60020a72185a5b9959081a5b881d1a1c995859149bdbdd02604082015260600190565b60128152607160020a7134b739bab33334b1b4b2b73a103a37b5b2b702602082015260400190565b60148152606160020a7331b430b73732b61036bab9ba1031329037b832b702602082015260400190565b602481527f6368616c6c656e6765722063616e206e6f74206265206578697420696e697469602082015260e160020a6330ba37b902604082015260600190565b60208082527f74687265616420636c6f73696e672074696d65206d757374206265207a65726f9082015260400190565b601a81527f73656e6465722063616e206e6f74206265207265636569766572000000000000602082015260400190565b600f8152608960020a6e2932b2b73a3930b73a1031b0b6361702602082015260400190565b604781527f73756d206f66207570646174656420746f6b656e2062616c616e636573206d7560208201527f7374206d617463682073656e646572277320696e697469616c20746f6b656e20604082015260c860020a6662616c616e636502606082015260800190565b60168152605260020a751d5cd95c881cda59db985d1d5c99481a5b9d985b1a5902602082015260400190565b604481527f687562436f6e747261637457697468647261773a20436f6e747261637420746f60208201527f6b656e2066756e6473206e6f742073756666696369656e7420746f2077697468604082015260e060020a636472617702606082015260800190565b602881527f696e73756666696369656e74207265736572766520746f6b656e7320666f7220602082015260c060020a676465706f7369747302604082015260600190565b60178152604860020a76757365722063616e6e6f7420656d70747920747769636502602082015260400190565b602b81527f687562436f6e747261637457697468647261773a20546f6b656e207472616e73602082015260a860020a6a666572206661696c75726502604082015260600190565b602b81527f63616e2774207374617274206578697420776974682074696d652d73656e7369602082015260a860020a6a746976652073746174657302604082015260600190565b603e81527f7570646174656420746f6b656e2062616c616e636573206d757374206d61746360208201527f682073756d206f662074687265616420746f6b656e2062616c616e6365730000604082015260600190565b60188152604260020a771d1bdad95b9cc81b5d5cdd0818994818dbdb9cd95c9d995902602082015260400190565b604281527f687562436f6e747261637457697468647261773a20436f6e747261637420776560208201527f692066756e6473206e6f742073756666696369656e7420746f20776974686472604082015260f060020a61617702606082015260800190565b602881527f74687265616420636c6f73696e672074696d65206d757374206e6f7420686176602082015260c260020a6719481c185cdcd95902604082015260600190565b602681527f696e697469616c2072656365697665722062616c616e636573206d7573742062602082015260d060020a6565207a65726f02604082015260600190565b602581527f6368616c6c656e676572206d757374206265206569746865722075736572206f602082015260d960020a643910343ab102604082015260600190565b604381527f73756d206f662075706461746564207765692062616c616e636573206d75737460208201527f206d617463682073656e646572277320696e697469616c207765692062616c61604082015260e860020a626e636502606082015260800190565b603d81527f676c6f62616c207478436f756e74206d7573742062652068696768657220746860208201527f616e207468652063757272656e7420676c6f62616c207478436f756e74000000604082015260600190565b602181527f6875622063616e206e6f742062652073656e646572206f722072656365697665602082015260f960020a603902604082015260600190565b604281527f73756d206f6620746872656164207765692062616c616e636573206d7573742060208201527f6d617463682073656e646572277320696e697469616c207765692062616c616e604082015260f060020a61636502606082015260800190565b60198152603a60020a781d5cd95c881d1bdad95b8819195c1bdcda5d0819985a5b195902602082015260400190565b602981527f746872656164206578697420696e69746961746f72206d757374206265207573602082015260b960020a6832b91037b910343ab102604082015260600190565b602581527f696e73756666696369656e7420726573657276652077656920666f7220646570602082015260d860020a646f7369747302604082015260600190565b60218152600080516020615c8c833981519152602082015260f860020a606502604082015260600190565b602481527f54687265616420636c6f73696e672074696d65206d7573742068617665207061602082015260e260020a631cdcd95902604082015260600190565b60138152606960020a723ab9b2b91031b0b7103737ba10313290343ab102602082015260400190565b604681527f73756d206f662074687265616420746f6b656e2062616c616e636573206d757360208201527f74206d617463682073656e646572277320696e697469616c20746f6b656e2062604082015260d060020a65616c616e636502606082015260800190565b602b81527f7468652074696d656f7574206d757374206265207a65726f206f72206e6f7420602082015260aa60020a6a1a185d99481c185cdcd95902604082015260600190565b602c81527f7570646174656420746872656164207478436f756e74206d7573742062652068602082015260a460020a6b06967686572207468616e20302604082015260600190565b602e81527f75736572205b73656e6465725d20746f6b656e207769746864726177616c20746020820152609260020a6d1c985b9cd9995c8819985a5b195902604082015260600190565b602281527f6578697420696e69746961746f72206d7573742062652075736572206f722068602082015260f160020a613ab102604082015260600190565b60278152600080516020615c8c833981519152602082015260c860020a666520706861736502604082015260600190565b601f81527f757365722063616e206e6f74206265206368616e6e656c206d616e6167657200602082015260400190565b60558152600080516020615d0c83398151915260208201527f6173736564206f72206d73672e73656e646572206d757374206265206e6f6e2d6040820152605860020a74657869742d696e6974696174696e6720706172747902606082015260800190565b603081527f75736572205b72656365697665725d20746f6b656e207769746864726177616c6020820152608260020a6f081d1c985b9cd9995c8819985a5b195902604082015260600190565b602e81527f6d73672e76616c7565206973206e6f7420657175616c20746f2070656e64696e6020820152609260020a6d19c81d5cd95c8819195c1bdcda5d02604082015260600190565b603d81527f746872656164207478436f756e74206d7573742062652068696768657220746860208201527f616e207468652063757272656e7420746872656164207478436f756e74000000604082015260600190565b603481527f6f6e6c79206875622c2073656e6465722c206f722072656365697665722063616020820152606160020a73371031b0b636103a3434b990333ab731ba34b7b702604082015260600190565b602681527f75736572206d757374206265207468726561642073656e646572206f72207265602082015260d160020a6531b2b4bb32b902604082015260600190565b6143c681615c3a565b602081016153a182846143bd565b92915050565b606081016153b582866143bd565b6153c260208301856143bd565b613d786040830184614499565b604081016153dd82856143bd565b613ba26020830184614499565b61016081016153f9828b6143bd565b615406602083018a614499565b61541360408301896143bd565b61542060608301886143cc565b61542d60a08301876143cc565b61543a60e0830186614415565b615448610120830185614499565b615456610140830184614499565b9998505050505050505050565b610100810161547282896143bd565b61547f6020830188614499565b61548c60408301876143bd565b6154996060830186614415565b6154a660a0830185614415565b6154b360e0830184614499565b979650505050505050565b61016081016154cd828b6143bd565b6154da602083018a614499565b6154136040830189614499565b61010081016154f682896143bd565b6155036020830188614499565b61548c604083018761538a565b6040810161551e8285614499565b8181036020830152613d7881846144bd565b6060810161553e8286614499565b818103602083015261555081856144bd565b9050613d7860408301846143bd565b60a0810161556d8288614499565b61557a6020830187614499565b61558760408301866143bd565b6155946060830185614499565b6155a160808301846144ab565b9695505050505050565b602081016153a182846144a2565b61022081016155c8828b6144b4565b6155d5602083018a6143cc565b6155e260608301896143cc565b6155ef60a0830188614457565b6155fd610120830187614457565b61560b6101a08301866143cc565b6156196101e0830185614499565b615456610200830184614499565b6102208101615636828b6144b4565b615643602083018a6143cc565b61565060608301896143cc565b61565d60a0830188614457565b61566b610120830187614457565b61560b6101a0830186614415565b60208082528101613ba281846144bd565b602080825281016153a1816144f2565b602080825281016153a181614518565b602080825281016153a18161455c565b602080825281016153a1816145c4565b602080825281016153a181614601565b602080825281016153a18161462c565b602080825281016153a181614653565b602080825281016153a18161469c565b602080825281016153a1816146e1565b602080825281016153a181614722565b602080825281016153a181614762565b602080825281016153a18161478d565b602080825281016153a1816147bd565b602080825281016153a181614813565b602080825281016153a181614862565b602080825281016153a18161488a565b602080825281016153a1816148b4565b602080825281016153a1816148f4565b602080825281016153a181614924565b602080825281016153a181614954565b602080825281016153a181614979565b602080825281016153a1816149e2565b602080825281016153a181614a0e565b602080825281016153a181614a74565b602080825281016153a181614ab8565b602080825281016153a181614ae5565b602080825281016153a181614b2c565b602080825281016153a181614b73565b602080825281016153a181614bc9565b602080825281016153a181614bf7565b602080825281016153a181614c5b565b602080825281016153a181614c9f565b602080825281016153a181614ce1565b602080825281016153a181614d22565b602080825281016153a181614d87565b602080825281016153a181614ddd565b602080825281016153a181614e1a565b602080825281016153a181614e7e565b602080825281016153a181614ead565b602080825281016153a181614ef2565b602080825281016153a181614f33565b602080825281016153a181614f5e565b602080825281016153a181614f9e565b602080825281016153a181614fc7565b602080825281016153a18161502f565b602080825281016153a181615076565b602080825281016153a1816150be565b602080825281016153a181615108565b602080825281016153a181615146565b602080825281016153a181615177565b602080825281016153a1816151a7565b602080825281016153a18161520c565b602080825281016153a181615258565b602080825281016153a1816152a2565b602080825281016153a1816152f8565b602080825281016153a181615348565b602081016153a18284614499565b60e08101615a268288614499565b615a3360208301876143bd565b615a406040830186614415565b615a4d6080830185614415565b6155a160c0830184614499565b604081016153dd8285614499565b60e08101615a76828a614499565b615a836020830189614499565b615a906040830188614499565b615a9d6060830187614499565b615aaa60808301866143bd565b615ab760a0830185614499565b615ac460c08301846144ab565b98975050505050505050565b60c08101615ade8289614499565b615aeb6020830188614499565b615af86040830187614499565b615b056060830186614499565b615b126080830185614499565b6154b360a0830184614499565b6101208101615b2e828961538a565b615b3b60208301886143cc565b615b4860608301876143cc565b615b5560a0830186614415565b615b6260e0830185614499565b6154b3610100830184614499565b6040518181016001604060020a0381118282101715615b8e57600080fd5b604052919050565b60006001604060020a03821115615bac57600080fd5b5060200290565b60006001604060020a03821115615bc957600080fd5b506020601f91909101601f19160190565b50600290565b50600490565b5190565b60200190565b60010190565b600160a060020a031690565b600060038210613ae657fe5b60ff1690565b151590565b60006153a182615bf6565b60006153a182615c02565b60006153a182611d59565b60006153a182615c0e565b82818337506000910152565b60005b83811015615c6c578181015183820152602001615c54565b83811115615c7b576000848401525b50505050565b601f01601f19169056006368616e6e656c206d75737420626520696e20746872656164206469737075746e65112e059a868cb1c7c4aed27e34fbbe470d2df0cbaa09bb5f82e5cba029fadbf69f39706ae3cb4e5b9dbca5780e14ba4968cdd060d5c3268f335ad6c25761eace9ecdebd30bbfc243bdc30bfa016abfa8f627654b4989da4620271dc77b1c6368616e6e656c20636c6f73696e672074696d65206d75737420686176652070ff678da893f9e68225fd9be0e51123341ba6d50fe0df41edebef4e9c0d242f77a265627a7a72305820346bdebc5b65e540f2c06b10af9e3b0da5200dccdafe3e47d580b94d094ebdf96c6578706572696d656e74616cf50037000000000000000000000000526d0cd57a8b977d3628f12cdeceab12dd49297c00000000000000000000000000000000000000000000000000000000000151800000000000000000000000006b01c3170ae1efebee1a3159172cb3f7a5ecf9e5
Deployed Bytecode
0x6080604052600436106101235763ffffffff60e060020a6000350416629e8690811461012557806301dd7da9146101505780630955acd41461017057806325c29be01461019057806332b573e1146101b0578063365a86fc146101c557806345a92009146101e75780634e2a5c5a14610219578063686bf4601461023957806369f817761461025957806372cc174c1461027957806374c25c20146102995780637651a86b146102cc5780637dce34f7146102ec5780639bcf63cd1461031d578063a1e1fe9314610332578063a3f4df7e14610352578063ad872d0314610374578063b04993ef14610389578063bab46259146103a9578063c8b2f7d6146103cb578063ea682e37146103eb578063f3f480d9146103fe578063ffa1ad7414610413575b005b34801561013157600080fd5b5061013a610428565b6040516101479190615a0a565b60405180910390f35b34801561015c57600080fd5b5061012361016b366004614383565b61042e565b34801561017c57600080fd5b5061012361018b36600461403b565b610604565b34801561019c57600080fd5b506101236101ab366004613f86565b61099b565b3480156101bc57600080fd5b5061013a610c1e565b3480156101d157600080fd5b506101da610c24565b6040516101479190615393565b3480156101f357600080fd5b50610207610202366004613d5a565b610c33565b60405161014796959493929190615ad0565b34801561022557600080fd5b50610123610234366004613d5a565b610d8f565b34801561024557600080fd5b50610123610254366004613e7e565b611159565b34801561026557600080fd5b50610123610274366004614246565b611396565b34801561028557600080fd5b50610123610294366004613d5a565b61168c565b3480156102a557600080fd5b506102b96102b4366004613d5a565b611818565b6040516101479796959493929190615a68565b3480156102d857600080fd5b506101236102e7366004613d5a565b611982565b3480156102f857600080fd5b5061030c610307366004613d5a565b611c8a565b60405161014795949392919061555f565b34801561032957600080fd5b5061013a611cc9565b34801561033e57600080fd5b5061012361034d366004614246565b611d5c565b34801561035e57600080fd5b50610367612198565b6040516101479190615679565b34801561038057600080fd5b5061013a6121c4565b34801561039557600080fd5b506101236103a4366004613d9e565b6121dc565b3480156103b557600080fd5b506103be612871565b60405161014791906155ab565b3480156103d757600080fd5b506101236103e6366004613d9e565b612880565b6101236103f9366004614152565b612aaf565b34801561040a57600080fd5b5061013a612daf565b34801561041f57600080fd5b50610367612db5565b60035481565b60075460ff161561045d5760405160e560020a62461bcd028152600401610454906157ba565b60405180910390fd5b6007805460ff1916600117905560005433600160a060020a039091161461048357600080fd5b8161048c6121c4565b10156104ad5760405160e560020a62461bcd0281526004016104549061585a565b806104b6611cc9565b10156104d75760405160e560020a62461bcd028152600401610454906157ea565b60008054604051600160a060020a039091169184156108fc02918591818181858888f19350505050158015610510573d6000803e3d6000fd5b5060025460005460405160e060020a63a9059cbb028152600160a060020a039283169263a9059cbb9261054a9291169085906004016153cf565b602060405180830381600087803b15801561056457600080fd5b505af1158015610578573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061059c9190810190614347565b15156105bd5760405160e560020a62461bcd0281526004016104549061581a565b7f60a3ff34ec09137572f54ff0fde3035ae459c9bebfdb1643a897de83211ebdf082826040516105ee929190615a5a565b60405180910390a150506007805460ff19169055565b600754600090819060ff161561062f5760405160e560020a62461bcd028152600401610454906157ba565b6007805460ff19166001179055600160a060020a038d16600090815260056020526040902091506002600c83015460ff16600281111561066b57fe5b1461068b5760405160e560020a62461bcd0281526004016104549061598a565b600054600160a060020a03163314806106ac575033600160a060020a038e16145b15156106cd5760405160e560020a62461bcd028152600401610454906158ea565b8b51600160a060020a038e8116911614806106f7575060208c0151600160a060020a038e81169116145b15156107185760405160e560020a62461bcd028152600401610454906159fa565b60208a015115801561072c57506020890151155b151561074d5760405160e560020a62461bcd0281526004016104549061587a565b8b51600160a060020a03166000908152600660205260408120908d60016020020151600160a060020a0316600160a060020a0316815260200190815260200160002060008c81526020019081526020016000209050806005015460001415156107cb5760405160e560020a62461bcd0281526004016104549061579a565b6107ef8c600060200201518d600160200201518d8d8d60008e8e8a60080154612dd7565b600084116108125760405160e560020a62461bcd0281526004016104549061595a565b89516108358760015b60200201518860005b60200201519063ffffffff6130c016565b146108555760405160e560020a62461bcd0281526004016104549061589a565b885161086b8660015b6020020151876000610824565b1461088b5760405160e560020a62461bcd028152600401610454906157ca565b8b516020808e015160408051928301905260008083526108b693928f918b918b918b91908b90612dd7565b6108c281876002613aac565b506108d36002808301908790613aac565b50600481018490556001546108ef90429063ffffffff6130c016565b60058201558b60016020020151600160a060020a03168c60006020020151600160a060020a0316600080516020615ccc8339815191528f8e6000809054906101000a9004600160a060020a0316600160a060020a031633600160a060020a03161461095b57600161095e565b60005b600487015460405161097a9493929189916002830191906154e7565b60405180910390a350506007805460ff191690555050505050505050505050565b60075460009060ff16156109c45760405160e560020a62461bcd028152600401610454906157ba565b6007805460ff1916600117905560005433600160a060020a0390911614806109f4575033600160a060020a038916145b80610a07575033600160a060020a038816145b1515610a285760405160e560020a62461bcd028152600401610454906159ea565b50600160a060020a038088166000908152600660209081526040808320938a16835292815282822088835290522060058101544210610a7c5760405160e560020a62461bcd0281526004016104549061586a565b60048101548311610aa25760405160e560020a62461bcd028152600401610454906159da565b610abc81600101548260005b01549063ffffffff6130c016565b610ac786600161085e565b14610ae75760405160e560020a62461bcd0281526004016104549061574a565b6003810154610afb90600283016000610aae565b6020850151610b0c90866000610824565b14610b2c5760405160e560020a62461bcd0281526004016104549061583a565b6001810154602086015110801590610b4c57506003810154602085015110155b1515610b6d5760405160e560020a62461bcd0281526004016104549061571a565b610b928888888888886020604051908101604052806000815250896000600102612dd7565b610b9e81866002613aac565b50610baf6002808301908690613aac565b5060048101839055604051600160a060020a0380891691908a16907f738f3bb8a8a2b4d0dc29a4076d3a4e41e510cd1044877421546903039766ad1990610c02908a903390879060028201908b90615a18565b60405180910390a350506007805460ff19169055505050505050565b60045481565b600054600160a060020a031681565b600080600080600080610c44613aea565b600160a060020a03881660009081526005602052604090819020815161016081019092528161010081018260038282826020028201915b815481526020019060010190808311610c7b5750505091835250506040805160608101918290526020909201919060038481019182845b815481526020019060010190808311610cb2575050509183525050604080518082019182905260209092019190600684019060029082845b815481526020019060010190808311610cea5750505091835250506008820154602082015260098201546040820152600a820154600160a060020a03166060820152600b8201546080820152600c82015460a09091019060ff166002811115610d4f57fe5b6002811115610d5a57fe5b9052508051805160208083015160409384015194820151805192810151940151929d909c50939a509850909650945092505050565b60075460009060ff1615610db85760405160e560020a62461bcd028152600401610454906157ba565b6007805460ff19166001179055600054600160a060020a0383811691161415610df65760405160e560020a62461bcd0281526004016104549061592a565b600160a060020a038216301415610e225760405160e560020a62461bcd0281526004016104549061599a565b50600160a060020a03811660009081526005602052604090206001600c82015460ff166002811115610e5057fe5b14610e705760405160e560020a62461bcd0281526004016104549061573a565b4281600b01541080610eb65750600a810154600160a060020a03163314801590610eb65750600054600160a060020a0316331480610eb6575033600160a060020a038316145b1515610ed75760405160e560020a62461bcd028152600401610454906159aa565b610f048160015b01548254610ef8908460025b01549063ffffffff6130dd16565b9063ffffffff6130dd16565b8160020155610f266003820160015b0154600383018054610ef8916002610eea565b6005820155610f4c8160015b0154610ef88360005b01546003549063ffffffff6130dd16565b6003556001810154604051600160a060020a0384169180156108fc02916000818181858888f19350505050158015610f88573d6000803e3d6000fd5b5060008181015560008160010155610fbd6003820160015b0154610ef86003840160005b01546004549063ffffffff6130dd16565b600455600254600160a060020a031663a9059cbb8360038401600101546040518363ffffffff1660e060020a028152600401610ffa9291906153cf565b602060405180830381600087803b15801561101457600080fd5b505af1158015611028573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061104c9190810190614347565b151561106d5760405160e560020a62461bcd0281526004016104549061570a565b600060038201819055600482018190556009820154111561109c57600c8101805460ff191660021790556110b0565b6000600b820155600c8101805460ff191690555b600a81018054600160a060020a0319169055600054600160a060020a0383811691600080516020615d2c833981519152911633146110ef5760016110f2565b60005b6040805180820182528554815260018601546020808301919091528251808401845260038801548152600488015491810191909152600887015460098801549351611143959460068a019291615b1f565b60405180910390a250506007805460ff19169055565b60075460009060ff16156111825760405160e560020a62461bcd028152600401610454906157ba565b6007805460ff1916600117905560005433600160a060020a03909116146111a857600080fd5b50600160a060020a038b1660009081526005602052604090206111d281878c8c8c8c8960016130f4565b604080518082018252600160a060020a03808f1682528d166020808301919091528251808201845260008082528451808601909552845260019184019190915261122d928d918d918d918d918d918d918d918d918d906133b8565b61123a818b8b8b8b613781565b6060880151604051600160a060020a038d169180156108fc02916000818181858888f19350505050158015611273573d6000803e3d6000fd5b50600254606088015160405160e060020a63a9059cbb028152600160a060020a039092169163a9059cbb916112ad918f91906004016153cf565b602060405180830381600087803b1580156112c757600080fd5b505af11580156112db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506112ff9190810190614347565b15156113205760405160e560020a62461bcd0281526004016104549061570a565b61132f60068201876002613aac565b506008810185905560098101849055604051600160a060020a038d1690600080516020615cec83398151915290611376906000908e908e908e908e908e908e908e906155b9565b60405180910390a250506007805460ff1916905550505050505050505050565b60075460009060ff16156113bf5760405160e560020a62461bcd028152600401610454906157ba565b506007805460ff191660011790558a51600160a060020a0316600090815260056020526040812090600c82015460ff1660028111156113fa57fe5b1461141a5760405160e560020a62461bcd0281526004016104549061577a565b600054600160a060020a031633148061143c57508b51600160a060020a031633145b151561145d5760405160e560020a62461bcd0281526004016104549061597a565b831561147e5760405160e560020a62461bcd0281526004016104549061582a565b6114b08c8c8c8c8c8c8c8c8c8c8c604080519081016040528060011515151581526020016001151515158152506133b8565b60068101548751116114d75760405160e560020a62461bcd028152600401610454906158aa565b6007810154602088015110156115025760405160e560020a62461bcd028152600401610454906156aa565b806002015461151b8c60015b60200201518d6000610824565b111561153c5760405160e560020a62461bcd028152600401610454906156ca565b60058101546115558b60015b60200201518c6000610824565b11156115765760405160e560020a62461bcd0281526004016104549061584a565b6007810154602088015114156115a457611591818c8b613852565b61159f816003018b8a613852565b6115bd565b6115af818c8b6138e0565b6115bd816003018b8a6138e0565b865160068201556008810186905560098101859055600a81018054600160a060020a031916331790556001546115f49042906130c0565b600b820155600c8101805460ff191660011790558b51600054600160a060020a0391821691600080516020615cac833981519152913391161461163857600161163b565b60005b6040805180820182528554815260018601546020808301919091528251808401845260038801548152600488015491810191909152600887015460098801549351611376959460068a019291615b1f565b60075460009060ff16156116b55760405160e560020a62461bcd028152600401610454906157ba565b6007805460ff19166001179055600054600160a060020a03838116911614156116f35760405160e560020a62461bcd0281526004016104549061592a565b600160a060020a03821630141561171f5760405160e560020a62461bcd0281526004016104549061599a565b50600160a060020a038116600090815260056020526040812090600c82015460ff16600281111561174c57fe5b1461176c5760405160e560020a62461bcd0281526004016104549061577a565b600054600160a060020a031633148061178d575033600160a060020a038316145b15156117ae5760405160e560020a62461bcd0281526004016104549061597a565b600a81018054600160a060020a031916331790556001546117d690429063ffffffff6130c016565b600b820155600c8101805460ff19166001179055600054600160a060020a0383811691600080516020615cac83398151915291339116146110ef5760016110f2565b600080600080600080600061182b613aea565b600160a060020a03891660009081526005602052604090819020815161016081019092528161010081018260038282826020028201915b8154815260200190600101908083116118625750505091835250506040805160608101918290526020909201919060038481019182845b815481526020019060010190808311611899575050509183525050604080518082019182905260209092019190600684019060029082845b8154815260200190600101908083116118d15750505091835250506008820154602082015260098201546040820152600a820154600160a060020a03166060820152600b8201546080820152600c82015460a09091019060ff16600281111561193657fe5b600281111561194157fe5b905250604081015180516020909101516060830151608084015160a085015160c086015160e090960151949f939e50919c509a509850919650945092505050565b6007546000908190819060ff16156119af5760405160e560020a62461bcd028152600401610454906157ba565b6007805460ff19166001179055600054600160a060020a03858116911614156119ed5760405160e560020a62461bcd0281526004016104549061592a565b600160a060020a038416301415611a195760405160e560020a62461bcd0281526004016104549061599a565b600160a060020a038416600090815260056020526040902092506002600c84015460ff166002811115611a4857fe5b14611a685760405160e560020a62461bcd0281526004016104549061590a565b42611a93611a82600a60015461394690919063ffffffff16565b600b8601549063ffffffff6130c016565b10611ab35760405160e560020a62461bcd0281526004016104549061569a565b611abe836002610f3b565b6003556002830154604051600160a060020a0386169180156108fc02916000818181858888f19350505050158015611afa573d6000803e3d6000fd5b508260020154915060008360020155611b17600384016002610fac565b6004908155600254600585015460405160e060020a63a9059cbb028152600160a060020a039092169263a9059cbb92611b549289929091016153cf565b602060405180830381600087803b158015611b6e57600080fd5b505af1158015611b82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611ba69190810190614347565b1515611bc75760405160e560020a62461bcd0281526004016104549061570a565b506005820180546000918290556009840182905560088401829055600b8401829055600c8401805460ff19169055604080518082018252855481526001860154602080830191909152825180840184526003880154815260048801549181019190915291519293600160a060020a038816937f02d2d0f262d032138bbd82feccd6d357a4441f394333cfa7d61792f44a70a0ed93611c72933393899389939160068d019181906154be565b60405180910390a250506007805460ff191690555050565b600560205260009081526040902060088101546009820154600a830154600b840154600c9094015492939192600160a060020a03909116919060ff1685565b6004805460025460405160e060020a6370a08231028152600093611d569392600160a060020a0316916370a0823191611d0491309101615393565b602060405180830381600087803b158015611d1e57600080fd5b505af1158015611d32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ef89190810190614365565b90505b90565b60075460009060ff1615611d855760405160e560020a62461bcd028152600401610454906157ba565b506007805460ff191660019081179091558b51600160a060020a0316600090815260056020526040902090600c82015460ff166002811115611dc357fe5b14611de35760405160e560020a62461bcd0281526004016104549061573a565b600b8101544210611e095760405160e560020a62461bcd028152600401610454906156fa565b600a810154600160a060020a0316331415611e395760405160e560020a62461bcd0281526004016104549061578a565b600054600160a060020a0316331480611e5b57508b51600160a060020a031633145b1515611e7c5760405160e560020a62461bcd0281526004016104549061588a565b8315611e9d5760405160e560020a62461bcd0281526004016104549061582a565b611ecf8c8c8c8c8c8c8c8c8c8c8c604080519081016040528060011515151581526020016001151515158152506133b8565b6006810154875111611ef65760405160e560020a62461bcd028152600401610454906158aa565b600781015460208801511015611f215760405160e560020a62461bcd028152600401610454906156aa565b8060020154611f318c600161150e565b1115611f525760405160e560020a62461bcd028152600401610454906156ca565b6005810154611f628b6001611548565b1115611f835760405160e560020a62461bcd0281526004016104549061584a565b600781015460208801511415611fb157611f9e818c8b613852565b611fac816003018b8a613852565b611fca565b611fbc818c8b6138e0565b611fca816003018b8a6138e0565b611fd5816001610ede565b8160020155611fe8600382016001610f13565b6005820155611ff8816001610f32565b6003558b516001820154604051600160a060020a039092169181156108fc0291906000818181858888f19350505050158015612038573d6000803e3d6000fd5b5060008181015560008160010155612054600382016001610fa0565b60049081556002548d518383015460405160e060020a63a9059cbb028152600160a060020a039093169363a9059cbb93612090939291016153cf565b602060405180830381600087803b1580156120aa57600080fd5b505af11580156120be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506120e29190810190614347565b15156121035760405160e560020a62461bcd0281526004016104549061570a565b6000600382018190556004820181905587516006830155600882018790556009820186905585111561214357600c8101805460ff19166002179055612157565b6000600b820155600c8101805460ff191690555b600a81018054600160a060020a03191690558b51600054600160a060020a0391821691600080516020615d2c8339815191529116331461163857600161163b565b60408051808201909152600f8152608960020a6e21b430b73732b61026b0b730b3b2b902602082015281565b600354600090611d569030319063ffffffff6130dd16565b600754600090819060ff16156122075760405160e560020a62461bcd028152600401610454906157ba565b6007805460ff19166001179055600160a060020a038a16600090815260056020526040902091506002600c83015460ff16600281111561224357fe5b146122635760405160e560020a62461bcd0281526004016104549061590a565b600054600160a060020a0316331480612284575033600160a060020a038b16145b15156122a55760405160e560020a62461bcd028152600401610454906156ba565b88600160a060020a03168a600160a060020a031614806122d6575087600160a060020a03168a600160a060020a0316145b15156122f75760405160e560020a62461bcd028152600401610454906159fa565b602086015115801561230b57506020850151155b151561232c5760405160e560020a62461bcd0281526004016104549061587a565b50600160a060020a038089166000908152600660209081526040808320938b1683529281528282208983529052206005810154158015906123705750428160050154105b15156123915760405160e560020a62461bcd0281526004016104549061591a565b8060060189600160a060020a03168b600160a060020a0316146123b55760016123b8565b60005b60ff16600281106123c557fe5b602081049091015460ff601f9092166101000a900416156123fb5760405160e560020a62461bcd0281526004016104549061580a565b612411898989898960008a8a8a60080154612dd7565b8551600182015461242490836000610aae565b146124445760405160e560020a62461bcd028152600401610454906158ca565b8451600382015461245a90600284016000610aae565b1461247a5760405160e560020a62461bcd0281526004016104549061593a565b6124928160010154610ef88360000154856002610eea565b82600201556124b86002820160010154610ef86002840160000154600386016002610eea565b600583015560018101546124d190610ef8836000610f3b565b600355600160a060020a038a81169089161415612527576001810154604051600160a060020a038c169180156108fc02916000818181858888f19350505050158015612521573d6000803e3d6000fd5b50612579565b88600160a060020a03168a600160a060020a03161415612579578054604051600160a060020a038c169180156108fc02916000818181858888f19350505050158015612577573d6000803e3d6000fd5b505b600381015461259090610ef8600284016000610fac565b600455600160a060020a038a8116908916141561265857600254600382015460405160e060020a63a9059cbb028152600160a060020a039092169163a9059cbb916125e0918e91906004016153cf565b602060405180830381600087803b1580156125fa57600080fd5b505af115801561260e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506126329190810190614347565b15156126535760405160e560020a62461bcd028152600401610454906159ba565b61271e565b88600160a060020a03168a600160a060020a0316141561271e57600280549082015460405160e060020a63a9059cbb028152600160a060020a039092169163a9059cbb916126ab918e91906004016153cf565b602060405180830381600087803b1580156126c557600080fd5b505af11580156126d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506126fd9190810190614347565b151561271e5760405160e560020a62461bcd0281526004016104549061596a565b6001816006018a600160a060020a03168c600160a060020a031614612744576001612747565b60005b60ff166002811061275457fe5b602091828204019190066101000a81548160ff02191690831515021790555061278b600183600901546130dd90919063ffffffff16565b6009830181905515156127b357600060088301819055600b830155600c8201805460ff191690555b87600160a060020a031689600160a060020a03167ff45587a14ff8928bdd940cbf0564b42320b5e46a8fdecaf8a98a9eab63ab1f968c8a33604080519081016040528089600001600060038110151561280857fe5b0154815260018a015460209182015260408051808201825260038c0154815260048c01549281019290925260088b015460098c0154915161285397969594939260068e0192916153ea565b60405180910390a350506007805460ff191690555050505050505050565b600254600160a060020a031681565b600754600090819060ff16156128ab5760405160e560020a62461bcd028152600401610454906157ba565b6007805460ff19166001179055600160a060020a038a16600090815260056020526040902091506002600c83015460ff1660028111156128e757fe5b146129075760405160e560020a62461bcd0281526004016104549061598a565b600054600160a060020a0316331480612928575033600160a060020a038b16145b15156129495760405160e560020a62461bcd028152600401610454906158ea565b88600160a060020a03168a600160a060020a0316148061297a575087600160a060020a03168a600160a060020a0316145b151561299b5760405160e560020a62461bcd028152600401610454906159fa565b60208601511580156129af57506020850151155b15156129d05760405160e560020a62461bcd0281526004016104549061587a565b50600160a060020a038089166000908152600660209081526040808320938b168352928152828220898352905220600581015415612a235760405160e560020a62461bcd0281526004016104549061579a565b612a39898989898960008a8a8a60080154612dd7565b612a4581876002613aac565b50612a566002808301908790613aac565b50600154612a6b90429063ffffffff6130c016565b60058201556004810154604051600160a060020a03808b1692908c1691600080516020615ccc83398151915291612853918f918d9133918991600283019190615463565b60075460009060ff1615612ad85760405160e560020a62461bcd028152600401610454906157ba565b6007805460ff1916600117905587600260200201513414612b0e5760405160e560020a62461bcd028152600401610454906159ca565b6005600033600160a060020a0316600160a060020a031681526020019081526020016000209050612b4681878c8c8c8c8960006130f4565b604080518082018252338152600160a060020a038d1660208083019190915282518082018452600080825284518086019095526001855291840191909152612ba0928d918d918d918d918d918d918d918d918d91906133b8565b600254604080890151905160e060020a6323b872dd028152600160a060020a03909216916323b872dd91612bda91339130916004016153a7565b602060405180830381600087803b158015612bf457600080fd5b505af1158015612c08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612c2c9190810190614347565b1515612c4d5760405160e560020a62461bcd028152600401610454906158da565b612c5a818b8b8b8b613781565b6060880151604051600160a060020a038d169180156108fc02916000818181858888f19350505050158015612c93573d6000803e3d6000fd5b50600254606088015160405160e060020a63a9059cbb028152600160a060020a039092169163a9059cbb91612ccd918f91906004016153cf565b602060405180830381600087803b158015612ce757600080fd5b505af1158015612cfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612d1f9190810190614347565b1515612d405760405160e560020a62461bcd0281526004016104549061570a565b612d4f60068201876002613aac565b5060088101859055600981018490556040513390600080516020615cec83398151915290612d90906001908e908e908e908e9060068a01908e908e90615627565b60405180910390a250506007805460ff19169055505050505050505050565b60015481565b604080518082019091526005815260d860020a64302e302e3102602082015281565b6000600160a060020a038a8116908a161415612e085760405160e560020a62461bcd028152600401610454906157aa565b600054600160a060020a038b8116911614801590612e345750600054600160a060020a038a8116911614155b1515612e555760405160e560020a62461bcd028152600401610454906158ba565b600160a060020a038a163014801590612e775750600160a060020a0389163014155b1515612e985760405160e560020a62461bcd028152600401610454906156ea565b308a8a8a8a8a8a6040516020018088600160a060020a0316600160a060020a0316606060020a02815260140187600160a060020a0316600160a060020a0316606060020a02815260140186600160a060020a0316600160a060020a0316606060020a02815260140185815260200184600260200280838360005b83811015612f2a578181015183820152602001612f12565b5050505090500183600260200280838360005b83811015612f55578181015183820152602001612f3d565b505050509050018281526020019750505050505050506040516020818303038152906040526040518082805190602001908083835b60208310612fa95780518252601f199092019160209182019101612f8a565b5181516020939093036101000a60001901801990911692169190911790526040519201829003822060e060020a631052506f028352945073b01c6adaf785f06f2c01bcfe782e30ceefa90a269350631052506f92506130119185915087908f90600401615530565b60206040518083038186803b15801561302957600080fd5b505af415801561303d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506130619190810190614347565b15156130825760405160e560020a62461bcd028152600401610454906156da565b81156130b457613093818584613974565b15156130b45760405160e560020a62461bcd0281526004016104549061575a565b50505050505050505050565b6000828201838110156130d257600080fd5b8091505b5092915050565b600080838311156130ed57600080fd5b5050900390565b6000600c89015460ff16600281111561310957fe5b146131295760405160e560020a62461bcd0281526004016104549061577a565b81158061313557508142105b15156131565760405160e560020a62461bcd0281526004016104549061594a565b600688015487511161317d5760405160e560020a62461bcd028152600401610454906158aa565b6007880154602088015110156131a85760405160e560020a62461bcd028152600401610454906156aa565b87600201546131b887600161081b565b11156131d95760405160e560020a62461bcd028152600401610454906156ca565b60058801546131e986600161085e565b111561320a5760405160e560020a62461bcd0281526004016104549061584a565b8015613289576132186121c4565b604085015161322990866000610824565b111561324a5760405160e560020a62461bcd028152600401610454906158fa565b613252611cc9565b604084015161326390856000610824565b11156132845760405160e560020a62461bcd028152600401610454906157fa565b6132df565b6132916121c4565b845111156132b45760405160e560020a62461bcd028152600401610454906158fa565b6132bc611cc9565b835111156132df5760405160e560020a62461bcd028152600401610454906157fa565b60608401516020808601519088015161330d92916133019182908b6000610824565b9063ffffffff6130c016565b604085015161332a906133018760005b60200201518c6002610aae565b101561334b5760405160e560020a62461bcd0281526004016104549061568a565b60608301516020808501519087015161336d92916133019182908a6000610824565b604084015161338d906133018660005b602002015160038d016002610aae565b10156133ae5760405160e560020a62461bcd0281526004016104549061576a565b5050505050505050565b600080548d51600160a060020a03908116911614156133ec5760405160e560020a62461bcd0281526004016104549061592a565b8c51600160a060020a03163014156134195760405160e560020a62461bcd0281526004016104549061599a565b308d8d8d8d8d8d8d8d8d604051602001808b600160a060020a0316600160a060020a0316606060020a0281526014018a600260200280838360005b8381101561346c578181015183820152602001613454565b5050505090500189600260200280838360005b8381101561349757818101518382015260200161347f565b5050505090500188600260200280838360005b838110156134c25781810151838201526020016134aa565b5050505090500187600460200280838360005b838110156134ed5781810151838201526020016134d5565b5050505090500186600460200280838360005b83811015613518578181015183820152602001613500565b5050505090500185600260200280838360005b8381101561354357818101518382015260200161352b565b5050505090500184600019166000191681526020018381526020018281526020019a50505050505050505050506040516020818303038152906040526040518082805190602001908083835b602083106135ae5780518252601f19909201916020918201910161358f565b5181516020939093036101000a600019018019909116921691909117905260405192018290039091209350849250600091506135e79050565b6020020151156136ad5760405160e060020a63dca9541902815273b01c6adaf785f06f2c01bcfe782e30ceefa90a269063dca954199061362d9084908890600401615510565b60206040518083038186803b15801561364557600080fd5b505af4158015613659573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061367d9190810190613d80565b600054600160a060020a039081169116146136ad5760405160e560020a62461bcd0281526004016104549061572a565b6020820151156137725760405160e060020a63dca9541902815273b01c6adaf785f06f2c01bcfe782e30ceefa90a269063dca95419906136f39084908790600401615510565b60206040518083038186803b15801561370b57600080fd5b505af415801561371f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506137439190810190613d80565b8d51600160a060020a039081169116146137725760405160e560020a62461bcd028152600401610454906157da565b50505050505050505050505050565b61378c858584613852565b61379a856003018483613852565b60608201516020830151604084015184516003546137c49493610ef89390928492613301916130c0565b60035560608101516020820151604083015183516004546137f19493610ef89390928492613301916130c0565b6004556060820151602083015160408401516138199291610ef891829061330188600061331d565b60028601556060810151602082015160408301516138439291610ef891829061330187600061337d565b60038601600201555050505050565b6020810151815111156138915761388a61388282600160200201518360005b60200201519063ffffffff6130dd16565b836000610824565b8355613896565b815183555b6060810151604082015111156138cf576138c46138bc8260036020020151836002613871565b836001610824565b8360015b01556138db565b60208201518360015b01555b505050565b6020810151815111156138f6578151835561390b565b80516139089061388290836001613871565b83555b6060810151604082015111156139285760208201518360016138c8565b61393e6138bc8260026020020151836003613871565b8360016138d8565b60008083151561395957600091506130d6565b5082820282848281151561396957fe5b04146130d257600080fd5b6000838160405b85518111613a9f5785810151915081831015613a1657604080516020808201869052818301859052825180830384018152606090920192839052815191929182918401908083835b602083106139e25780518252601f1990920191602091820191016139c3565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390209250613a97565b604080516020808201859052818301869052825180830384018152606090920192839052815191929182918401908083835b60208310613a675780518252601f199092019160209182019101613a48565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902092505b60200161397b565b5050919091149392505050565b8260028101928215613ada579160200282015b82811115613ada578251825591602001919060010190613abf565b50613ae6929150613b42565b5090565b6101a060405190810160405280613aff613b5c565b8152602001613b0c613b5c565b8152602001613b19613b7b565b815260006020820181905260408201819052606082018190526080820181905260a09091015290565b611d5991905b80821115613ae65760008155600101613b48565b6060604051908101604052806003906020820280388339509192915050565b60408051808201825290600290829080388339509192915050565b6000613ba28235615bf6565b9392505050565b6000613ba28251615bf6565b6000601f82018313613bc657600080fd5b6002613bd9613bd482615b96565b615b70565b91508183856020840282011115613bef57600080fd5b60005b83811015613c1b5781613c058882613b96565b8452506020928301929190910190600101613bf2565b5050505092915050565b6000601f82018313613c3657600080fd5b6002613c44613bd482615b96565b91508183856020840282011115613c5a57600080fd5b60005b83811015613c1b5781613c708882613cf3565b8452506020928301929190910190600101613c5d565b6000601f82018313613c9757600080fd5b6004613ca5613bd482615b96565b91508183856020840282011115613cbb57600080fd5b60005b83811015613c1b5781613cd18882613cf3565b8452506020928301929190910190600101613cbe565b6000613ba28251615c14565b6000613ba28235611d59565b6000601f82018313613d1057600080fd5b8135613d1e613bd482615bb3565b91508082526020830160208301858383011115613d3a57600080fd5b613d45838284615c45565b50505092915050565b6000613ba28251611d59565b600060208284031215613d6c57600080fd5b6000613d788484613b96565b949350505050565b600060208284031215613d9257600080fd5b6000613d788484613ba9565b600080600080600080600080610140898b031215613dbb57600080fd5b6000613dc78b8b613b96565b9850506020613dd88b828c01613b96565b9750506040613de98b828c01613b96565b9650506060613dfa8b828c01613cf3565b9550506080613e0b8b828c01613c25565b94505060c0613e1c8b828c01613c25565b9350506101008901356001604060020a03811115613e3957600080fd5b613e458b828c01613cff565b9250506101208901356001604060020a03811115613e6257600080fd5b613e6e8b828c01613cff565b9150509295985092959890939650565b60008060008060008060008060008060006102808c8e031215613ea057600080fd5b6000613eac8e8e613b96565b9b50506020613ebd8e828f01613b96565b9a50506040613ece8e828f01613c25565b9950506080613edf8e828f01613c25565b98505060c0613ef08e828f01613c86565b975050610140613f028e828f01613c86565b9650506101c0613f148e828f01613c25565b955050610200613f268e828f01613cf3565b945050610220613f388e828f01613cf3565b935050610240613f4a8e828f01613cf3565b9250506102608c01356001604060020a03811115613f6757600080fd5b613f738e828f01613cff565b9150509295989b509295989b9093969950565b6000806000806000806000610120888a031215613fa257600080fd5b6000613fae8a8a613b96565b9750506020613fbf8a828b01613b96565b9650506040613fd08a828b01613cf3565b9550506060613fe18a828b01613c25565b94505060a0613ff28a828b01613c25565b93505060e06140038a828b01613cf3565b9250506101008801356001604060020a0381111561402057600080fd5b61402c8a828b01613cff565b91505092959891949750929550565b60008060008060008060008060008060006102008c8e03121561405d57600080fd5b60006140698e8e613b96565b9b5050602061407a8e828f01613bb5565b9a5050606061408b8e828f01613cf3565b995050608061409c8e828f01613c25565b98505060c06140ad8e828f01613c25565b9750506101008c01356001604060020a038111156140ca57600080fd5b6140d68e828f01613cff565b9650506101208c01356001604060020a038111156140f357600080fd5b6140ff8e828f01613cff565b9550506101406141118e828f01613c25565b9450506101806141238e828f01613c25565b9350506101c06141358e828f01613cf3565b9250506101e08c01356001604060020a03811115613f6757600080fd5b6000806000806000806000806000806102608b8d03121561417257600080fd5b600061417e8d8d613b96565b9a5050602061418f8d828e01613c25565b99505060606141a08d828e01613c25565b98505060a06141b18d828e01613c86565b9750506101206141c38d828e01613c86565b9650506101a06141d58d828e01613c25565b9550506101e06141e78d828e01613cf3565b9450506102006141f98d828e01613cf3565b93505061022061420b8d828e01613cf3565b9250506102408b01356001604060020a0381111561422857600080fd5b6142348d828e01613cff565b9150509295989b9194979a5092959850565b60008060008060008060008060008060006102a08c8e03121561426857600080fd5b60006142748e8e613bb5565b9b505060406142858e828f01613c25565b9a505060806142968e828f01613c25565b99505060c06142a78e828f01613c86565b9850506101406142b98e828f01613c86565b9750506101c06142cb8e828f01613c25565b9650506102006142dd8e828f01613cf3565b9550506102206142ef8e828f01613cf3565b9450506102406143018e828f01613cf3565b9350506102608c01356001604060020a0381111561431e57600080fd5b61432a8e828f01613cff565b9250506102808c01356001604060020a03811115613f6757600080fd5b60006020828403121561435957600080fd5b6000613d788484613ce7565b60006020828403121561437757600080fd5b6000613d788484613d4e565b6000806040838503121561439657600080fd5b60006143a28585613cf3565b92505060206143b385828601613cf3565b9150509250929050565b6143c681615bf6565b82525050565b6143d581615bda565b6143de82611d59565b60005b8281101561440e576143f4858351614499565b6143fd82615bea565b6020959095019491506001016143e1565b5050505050565b61441e81615bda565b61442782611d59565b60005b8281101561440e5761443d858354614499565b61444682615bf0565b60209590950194915060010161442a565b61446081615be0565b61446982611d59565b60005b8281101561440e5761447f858351614499565b61448882615bea565b60209590950194915060010161446c565b6143c681611d59565b6143c681615c19565b6143c681615c24565b6143c681615c2f565b60006144c882615be6565b8084526144dc816020860160208601615c51565b6144e581615c81565b9093016020019392505050565b60108152608060020a6f696e73756666696369656e742077656902602082015260400190565b603d8152600080516020615d0c83398151915260208201527f6173736564206279203130206368616c6c656e676520706572696f6473000000604082015260600190565b604681527f6f6e636861696e207478436f756e74206d75737420626520686967686572206f60208201527f7220657175616c20746f207468652063757272656e74206f6e636861696e2074604082015260d260020a651e10dbdd5b9d02606082015260800190565b602181527f6f6e6c7920687562206f7220757365722063616e20656d707479207468726561602082015260fa60020a601902604082015260600190565b60158152605a60020a741dd95a481b5d5cdd0818994818dbdb9cd95c9d995902602082015260400190565b60118152607a60020a701cda59db985d1d5c99481a5b9d985b1a5902602082015260400190565b602d81527f6368616e6e656c206d616e616765722063616e206e6f742062652073656e64656020820152609960020a6c391037b9103932b1b2b4bb32b902604082015260600190565b602981527f6368616e6e656c20636c6f73696e672074696d65206d757374206e6f74206861602082015260ba60020a681d99481c185cdcd95902604082015260600190565b602581527f7573657220746f6b656e207769746864726177616c207472616e736665722066602082015260da60020a64185a5b195902604082015260600190565b602481527f72656365697665722062616c616e636573206d6179206e657665722064656372602082015260e060020a636561736502604082015260600190565b60158152605a60020a741a1d58881cda59db985d1d5c99481a5b9d985b1a5902602082015260400190565b601a81527f6368616e6e656c206d75737420626520696e2064697370757465000000000000602082015260400190565b603a81527f75706461746564207765692062616c616e636573206d757374206d617463682060208201527f73756d206f6620746872656164207765692062616c616e636573000000000000604082015260600190565b603381527f696e697469616c20746872656164207374617465206973206e6f7420636f6e746020820152606a60020a72185a5b9959081a5b881d1a1c995859149bdbdd02604082015260600190565b60128152607160020a7134b739bab33334b1b4b2b73a103a37b5b2b702602082015260400190565b60148152606160020a7331b430b73732b61036bab9ba1031329037b832b702602082015260400190565b602481527f6368616c6c656e6765722063616e206e6f74206265206578697420696e697469602082015260e160020a6330ba37b902604082015260600190565b60208082527f74687265616420636c6f73696e672074696d65206d757374206265207a65726f9082015260400190565b601a81527f73656e6465722063616e206e6f74206265207265636569766572000000000000602082015260400190565b600f8152608960020a6e2932b2b73a3930b73a1031b0b6361702602082015260400190565b604781527f73756d206f66207570646174656420746f6b656e2062616c616e636573206d7560208201527f7374206d617463682073656e646572277320696e697469616c20746f6b656e20604082015260c860020a6662616c616e636502606082015260800190565b60168152605260020a751d5cd95c881cda59db985d1d5c99481a5b9d985b1a5902602082015260400190565b604481527f687562436f6e747261637457697468647261773a20436f6e747261637420746f60208201527f6b656e2066756e6473206e6f742073756666696369656e7420746f2077697468604082015260e060020a636472617702606082015260800190565b602881527f696e73756666696369656e74207265736572766520746f6b656e7320666f7220602082015260c060020a676465706f7369747302604082015260600190565b60178152604860020a76757365722063616e6e6f7420656d70747920747769636502602082015260400190565b602b81527f687562436f6e747261637457697468647261773a20546f6b656e207472616e73602082015260a860020a6a666572206661696c75726502604082015260600190565b602b81527f63616e2774207374617274206578697420776974682074696d652d73656e7369602082015260a860020a6a746976652073746174657302604082015260600190565b603e81527f7570646174656420746f6b656e2062616c616e636573206d757374206d61746360208201527f682073756d206f662074687265616420746f6b656e2062616c616e6365730000604082015260600190565b60188152604260020a771d1bdad95b9cc81b5d5cdd0818994818dbdb9cd95c9d995902602082015260400190565b604281527f687562436f6e747261637457697468647261773a20436f6e747261637420776560208201527f692066756e6473206e6f742073756666696369656e7420746f20776974686472604082015260f060020a61617702606082015260800190565b602881527f74687265616420636c6f73696e672074696d65206d757374206e6f7420686176602082015260c260020a6719481c185cdcd95902604082015260600190565b602681527f696e697469616c2072656365697665722062616c616e636573206d7573742062602082015260d060020a6565207a65726f02604082015260600190565b602581527f6368616c6c656e676572206d757374206265206569746865722075736572206f602082015260d960020a643910343ab102604082015260600190565b604381527f73756d206f662075706461746564207765692062616c616e636573206d75737460208201527f206d617463682073656e646572277320696e697469616c207765692062616c61604082015260e860020a626e636502606082015260800190565b603d81527f676c6f62616c207478436f756e74206d7573742062652068696768657220746860208201527f616e207468652063757272656e7420676c6f62616c207478436f756e74000000604082015260600190565b602181527f6875622063616e206e6f742062652073656e646572206f722072656365697665602082015260f960020a603902604082015260600190565b604281527f73756d206f6620746872656164207765692062616c616e636573206d7573742060208201527f6d617463682073656e646572277320696e697469616c207765692062616c616e604082015260f060020a61636502606082015260800190565b60198152603a60020a781d5cd95c881d1bdad95b8819195c1bdcda5d0819985a5b195902602082015260400190565b602981527f746872656164206578697420696e69746961746f72206d757374206265207573602082015260b960020a6832b91037b910343ab102604082015260600190565b602581527f696e73756666696369656e7420726573657276652077656920666f7220646570602082015260d860020a646f7369747302604082015260600190565b60218152600080516020615c8c833981519152602082015260f860020a606502604082015260600190565b602481527f54687265616420636c6f73696e672074696d65206d7573742068617665207061602082015260e260020a631cdcd95902604082015260600190565b60138152606960020a723ab9b2b91031b0b7103737ba10313290343ab102602082015260400190565b604681527f73756d206f662074687265616420746f6b656e2062616c616e636573206d757360208201527f74206d617463682073656e646572277320696e697469616c20746f6b656e2062604082015260d060020a65616c616e636502606082015260800190565b602b81527f7468652074696d656f7574206d757374206265207a65726f206f72206e6f7420602082015260aa60020a6a1a185d99481c185cdcd95902604082015260600190565b602c81527f7570646174656420746872656164207478436f756e74206d7573742062652068602082015260a460020a6b06967686572207468616e20302604082015260600190565b602e81527f75736572205b73656e6465725d20746f6b656e207769746864726177616c20746020820152609260020a6d1c985b9cd9995c8819985a5b195902604082015260600190565b602281527f6578697420696e69746961746f72206d7573742062652075736572206f722068602082015260f160020a613ab102604082015260600190565b60278152600080516020615c8c833981519152602082015260c860020a666520706861736502604082015260600190565b601f81527f757365722063616e206e6f74206265206368616e6e656c206d616e6167657200602082015260400190565b60558152600080516020615d0c83398151915260208201527f6173736564206f72206d73672e73656e646572206d757374206265206e6f6e2d6040820152605860020a74657869742d696e6974696174696e6720706172747902606082015260800190565b603081527f75736572205b72656365697665725d20746f6b656e207769746864726177616c6020820152608260020a6f081d1c985b9cd9995c8819985a5b195902604082015260600190565b602e81527f6d73672e76616c7565206973206e6f7420657175616c20746f2070656e64696e6020820152609260020a6d19c81d5cd95c8819195c1bdcda5d02604082015260600190565b603d81527f746872656164207478436f756e74206d7573742062652068696768657220746860208201527f616e207468652063757272656e7420746872656164207478436f756e74000000604082015260600190565b603481527f6f6e6c79206875622c2073656e6465722c206f722072656365697665722063616020820152606160020a73371031b0b636103a3434b990333ab731ba34b7b702604082015260600190565b602681527f75736572206d757374206265207468726561642073656e646572206f72207265602082015260d160020a6531b2b4bb32b902604082015260600190565b6143c681615c3a565b602081016153a182846143bd565b92915050565b606081016153b582866143bd565b6153c260208301856143bd565b613d786040830184614499565b604081016153dd82856143bd565b613ba26020830184614499565b61016081016153f9828b6143bd565b615406602083018a614499565b61541360408301896143bd565b61542060608301886143cc565b61542d60a08301876143cc565b61543a60e0830186614415565b615448610120830185614499565b615456610140830184614499565b9998505050505050505050565b610100810161547282896143bd565b61547f6020830188614499565b61548c60408301876143bd565b6154996060830186614415565b6154a660a0830185614415565b6154b360e0830184614499565b979650505050505050565b61016081016154cd828b6143bd565b6154da602083018a614499565b6154136040830189614499565b61010081016154f682896143bd565b6155036020830188614499565b61548c604083018761538a565b6040810161551e8285614499565b8181036020830152613d7881846144bd565b6060810161553e8286614499565b818103602083015261555081856144bd565b9050613d7860408301846143bd565b60a0810161556d8288614499565b61557a6020830187614499565b61558760408301866143bd565b6155946060830185614499565b6155a160808301846144ab565b9695505050505050565b602081016153a182846144a2565b61022081016155c8828b6144b4565b6155d5602083018a6143cc565b6155e260608301896143cc565b6155ef60a0830188614457565b6155fd610120830187614457565b61560b6101a08301866143cc565b6156196101e0830185614499565b615456610200830184614499565b6102208101615636828b6144b4565b615643602083018a6143cc565b61565060608301896143cc565b61565d60a0830188614457565b61566b610120830187614457565b61560b6101a0830186614415565b60208082528101613ba281846144bd565b602080825281016153a1816144f2565b602080825281016153a181614518565b602080825281016153a18161455c565b602080825281016153a1816145c4565b602080825281016153a181614601565b602080825281016153a18161462c565b602080825281016153a181614653565b602080825281016153a18161469c565b602080825281016153a1816146e1565b602080825281016153a181614722565b602080825281016153a181614762565b602080825281016153a18161478d565b602080825281016153a1816147bd565b602080825281016153a181614813565b602080825281016153a181614862565b602080825281016153a18161488a565b602080825281016153a1816148b4565b602080825281016153a1816148f4565b602080825281016153a181614924565b602080825281016153a181614954565b602080825281016153a181614979565b602080825281016153a1816149e2565b602080825281016153a181614a0e565b602080825281016153a181614a74565b602080825281016153a181614ab8565b602080825281016153a181614ae5565b602080825281016153a181614b2c565b602080825281016153a181614b73565b602080825281016153a181614bc9565b602080825281016153a181614bf7565b602080825281016153a181614c5b565b602080825281016153a181614c9f565b602080825281016153a181614ce1565b602080825281016153a181614d22565b602080825281016153a181614d87565b602080825281016153a181614ddd565b602080825281016153a181614e1a565b602080825281016153a181614e7e565b602080825281016153a181614ead565b602080825281016153a181614ef2565b602080825281016153a181614f33565b602080825281016153a181614f5e565b602080825281016153a181614f9e565b602080825281016153a181614fc7565b602080825281016153a18161502f565b602080825281016153a181615076565b602080825281016153a1816150be565b602080825281016153a181615108565b602080825281016153a181615146565b602080825281016153a181615177565b602080825281016153a1816151a7565b602080825281016153a18161520c565b602080825281016153a181615258565b602080825281016153a1816152a2565b602080825281016153a1816152f8565b602080825281016153a181615348565b602081016153a18284614499565b60e08101615a268288614499565b615a3360208301876143bd565b615a406040830186614415565b615a4d6080830185614415565b6155a160c0830184614499565b604081016153dd8285614499565b60e08101615a76828a614499565b615a836020830189614499565b615a906040830188614499565b615a9d6060830187614499565b615aaa60808301866143bd565b615ab760a0830185614499565b615ac460c08301846144ab565b98975050505050505050565b60c08101615ade8289614499565b615aeb6020830188614499565b615af86040830187614499565b615b056060830186614499565b615b126080830185614499565b6154b360a0830184614499565b6101208101615b2e828961538a565b615b3b60208301886143cc565b615b4860608301876143cc565b615b5560a0830186614415565b615b6260e0830185614499565b6154b3610100830184614499565b6040518181016001604060020a0381118282101715615b8e57600080fd5b604052919050565b60006001604060020a03821115615bac57600080fd5b5060200290565b60006001604060020a03821115615bc957600080fd5b506020601f91909101601f19160190565b50600290565b50600490565b5190565b60200190565b60010190565b600160a060020a031690565b600060038210613ae657fe5b60ff1690565b151590565b60006153a182615bf6565b60006153a182615c02565b60006153a182611d59565b60006153a182615c0e565b82818337506000910152565b60005b83811015615c6c578181015183820152602001615c54565b83811115615c7b576000848401525b50505050565b601f01601f19169056006368616e6e656c206d75737420626520696e20746872656164206469737075746e65112e059a868cb1c7c4aed27e34fbbe470d2df0cbaa09bb5f82e5cba029fadbf69f39706ae3cb4e5b9dbca5780e14ba4968cdd060d5c3268f335ad6c25761eace9ecdebd30bbfc243bdc30bfa016abfa8f627654b4989da4620271dc77b1c6368616e6e656c20636c6f73696e672074696d65206d75737420686176652070ff678da893f9e68225fd9be0e51123341ba6d50fe0df41edebef4e9c0d242f77a265627a7a72305820346bdebc5b65e540f2c06b10af9e3b0da5200dccdafe3e47d580b94d094ebdf96c6578706572696d656e74616cf50037
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000526d0cd57a8b977d3628f12cdeceab12dd49297c00000000000000000000000000000000000000000000000000000000000151800000000000000000000000006b01c3170ae1efebee1a3159172cb3f7a5ecf9e5
-----Decoded View---------------
Arg [0] : _hub (address): 0x526d0cd57a8b977D3628f12cDeceAb12dd49297C
Arg [1] : _challengePeriod (uint256): 86400
Arg [2] : _tokenAddress (address): 0x6B01c3170ae1EFEBEe1a3159172CB3F7A5ECf9E5
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000526d0cd57a8b977d3628f12cdeceab12dd49297c
Arg [1] : 0000000000000000000000000000000000000000000000000000000000015180
Arg [2] : 0000000000000000000000006b01c3170ae1efebee1a3159172cb3f7a5ecf9e5
Swarm Source
bzzr://346bdebc5b65e540f2c06b10af9e3b0da5200dccdafe3e47d580b94d094ebdf9
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ 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.