Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
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.
Similar Match Source Code This contract matches the deployed Bytecode of the Source Code for Contract 0x4e72b11B...0FCd0dEf4 The constructor portion of the code might be different and could alter the actual behaviour of the contract
Contract Name:
SubmitHandler
Compiler Version
v0.5.12+commit.7709ece9
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2020-09-11 */ // File: contracts/lib/SafeMath.sol pragma solidity ^0.5.12; /** * @title SafeMath * @dev Math operations with safety checks that revert on error */ 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; } /** * @dev Multiplies two numbers, reverts on overflow. */ function mul64(uint64 a, uint64 b) internal pure returns (uint64) { // 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; } uint64 c = a * b; require(c / a == b); return c; } /** * @dev Integer division of two numbers truncating the quotient, reverts on division by zero. */ function div64(uint64 a, uint64 b) internal pure returns (uint64) { require(b > 0); // Solidity only automatically asserts when dividing by 0 uint64 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 sub64(uint64 a, uint64 b) internal pure returns (uint64) { require(b <= a); uint64 c = a - b; return c; } /** * @dev Adds two numbers, reverts on overflow. */ function add64(uint64 a, uint64 b) internal pure returns (uint64) { uint64 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 mod64(uint64 a, uint64 b) internal pure returns (uint64) { require(b != 0); return a % b; } } // File: contracts/lib/Math.sol pragma solidity ^0.5.12; /** * @title Math * @dev Assorted math operations */ library Math { function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow, so we distribute return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2); } // return ceil(n/d) function divCeil(uint256 n, uint256 d) internal pure returns (uint256) { return n % d == 0 ? n / d : n / d + 1; } } // File: contracts/lib/RLP.sol pragma solidity ^0.5.12; /** * @title RLPReader * @dev RLPReader is used to read and parse RLP encoded data in memory. * @author Andreas Olofsson ([email protected]) */ library RLP { uint constant DATA_SHORT_START = 0x80; uint constant DATA_LONG_START = 0xB8; uint constant LIST_SHORT_START = 0xC0; uint constant LIST_LONG_START = 0xF8; uint constant DATA_LONG_OFFSET = 0xB7; uint constant LIST_LONG_OFFSET = 0xF7; struct RLPItem { uint _unsafeMemPtr; // Pointer to the RLP-encoded bytes. uint _unsafeLength; // Number of bytes. This is the full length of the string. } struct Iterator { RLPItem _unsafeItem; // Item that's being iterated over. uint _unsafeNextPtr; // Position of the next item in the list. } /* RLPItem */ /// @dev Creates an RLPItem from an array of RLP encoded bytes. /// @param self The RLP encoded bytes. /// @return An RLPItem function toRLPItem(bytes memory self) internal pure returns (RLPItem memory) { uint len = self.length; uint memPtr; assembly { memPtr := add(self, 0x20) } return RLPItem(memPtr, len); } /// @dev Get the list of sub-items from an RLP encoded list. /// Warning: This requires passing in the number of items. /// @param self The RLP item. /// @return Array of RLPItems. function toList(RLPItem memory self, uint256 numItems) internal pure returns (RLPItem[] memory list) { list = new RLPItem[](numItems); Iterator memory it = iterator(self); uint idx; while (idx < numItems) { list[idx] = next(it); idx++; } } /// @dev Decode an RLPItem into a uint. This will not work if the /// RLPItem is a list. /// @param self The RLPItem. /// @return The decoded string. function toUint(RLPItem memory self) internal pure returns (uint data) { (uint rStartPos, uint len) = _decode(self); assembly { data := div(mload(rStartPos), exp(256, sub(32, len))) } } /// @dev Decode an RLPItem into an address. This will not work if the /// RLPItem is a list. /// @param self The RLPItem. /// @return The decoded string. function toAddress(RLPItem memory self) internal pure returns (address data) { (uint rStartPos,) = _decode(self); assembly { data := div(mload(rStartPos), exp(256, 12)) } } /// @dev Create an iterator. /// @param self The RLP item. /// @return An 'Iterator' over the item. function iterator(RLPItem memory self) private pure returns (Iterator memory it) { uint ptr = self._unsafeMemPtr + _payloadOffset(self); it._unsafeItem = self; it._unsafeNextPtr = ptr; } /* Iterator */ function next(Iterator memory self) private pure returns (RLPItem memory subItem) { uint ptr = self._unsafeNextPtr; uint itemLength = _itemLength(ptr); subItem._unsafeMemPtr = ptr; subItem._unsafeLength = itemLength; self._unsafeNextPtr = ptr + itemLength; } function hasNext(Iterator memory self) private pure returns (bool) { RLPItem memory item = self._unsafeItem; return self._unsafeNextPtr < item._unsafeMemPtr + item._unsafeLength; } // Get the payload offset. function _payloadOffset(RLPItem memory self) private pure returns (uint) { uint b0; uint memPtr = self._unsafeMemPtr; assembly { b0 := byte(0, mload(memPtr)) } if (b0 < DATA_SHORT_START) return 0; if (b0 < DATA_LONG_START || (b0 >= LIST_SHORT_START && b0 < LIST_LONG_START)) return 1; if (b0 < LIST_SHORT_START) return b0 - DATA_LONG_OFFSET + 1; return b0 - LIST_LONG_OFFSET + 1; } // Get the full length of an RLP item. function _itemLength(uint memPtr) private pure returns (uint len) { uint b0; assembly { b0 := byte(0, mload(memPtr)) } if (b0 < DATA_SHORT_START) len = 1; else if (b0 < DATA_LONG_START) len = b0 - DATA_SHORT_START + 1; } // Get start position and length of the data. function _decode(RLPItem memory self) private pure returns (uint memPtr, uint len) { uint b0; uint start = self._unsafeMemPtr; assembly { b0 := byte(0, mload(start)) } if (b0 < DATA_SHORT_START) { memPtr = start; len = 1; return (memPtr, len); } if (b0 < DATA_LONG_START) { len = self._unsafeLength - 1; memPtr = start + 1; } else { uint bLen; assembly { bLen := sub(b0, 0xB7) // DATA_LONG_OFFSET } len = self._unsafeLength - 1 - bLen; memPtr = start + bLen + 1; } return (memPtr, len); } /// @dev Return the RLP encoded bytes. /// @param self The RLPItem. /// @return The bytes. function toBytes(RLPItem memory self) internal pure returns (bytes memory bts) { uint len = self._unsafeLength; if (len == 0) return bts; bts = new bytes(len); _copyToBytes(self._unsafeMemPtr, bts, len); } // Assumes that enough memory has been allocated to store in target. function _copyToBytes(uint btsPtr, bytes memory tgt, uint btsLen) private pure { // Exploiting the fact that 'tgt' was the last thing to be allocated, // we can write entire words, and just overwrite any excess. assembly { { // evm operations on words let words := div(add(btsLen, 31), 32) let rOffset := btsPtr let wOffset := add(tgt, 0x20) for { let i := 0 } // start at arr + 0x20 -> first byte corresponds to length lt(i, words) { i := add(i, 1) } { let offset := mul(i, 0x20) mstore(add(wOffset, offset), mload(add(rOffset, offset))) } mstore(add(tgt, add(0x20, mload(tgt))), 0) } } } } // File: contracts/lib/RLPEncode.sol pragma solidity ^0.5.12; /** * @title A simple RLP encoding library * @author Bakaoh */ library RLPEncode { uint8 constant STRING_OFFSET = 0x80; uint8 constant LIST_OFFSET = 0xc0; /** * @notice Encode string item * @param self The string (ie. byte array) item to encode * @return The RLP encoded string in bytes */ function encodeBytes(bytes memory self) internal pure returns (bytes memory) { if (self.length == 1 && self[0] <= 0x7f) { return self; } return mergeBytes(encodeLength(self.length, STRING_OFFSET), self); } /** * @notice Encode address * @param self The address to encode * @return The RLP encoded address in bytes */ function encodeAddress(address self) internal pure returns (bytes memory) { bytes memory b; assembly { let m := mload(0x40) mstore(add(m, 20), xor(0x140000000000000000000000000000000000000000, self)) mstore(0x40, add(m, 52)) b := m } return encodeBytes(b); } /** * @notice Encode uint * @param self The uint to encode * @return The RLP encoded uint in bytes */ function encodeUint(uint self) internal pure returns (bytes memory) { return encodeBytes(toBinary(self)); } /** * @notice Encode int * @param self The int to encode * @return The RLP encoded int in bytes */ function encodeInt(int self) internal pure returns (bytes memory) { return encodeUint(uint(self)); } /** * @notice Encode bool * @param self The bool to encode * @return The RLP encoded bool in bytes */ function encodeBool(bool self) internal pure returns (bytes memory) { bytes memory rs = new bytes(1); if (self) { rs[0] = bytes1(uint8(1)); } return rs; } /** * @notice Encode list of items * @param self The list of items to encode, each item in list must be already encoded * @return The RLP encoded list of items in bytes */ function encodeList(bytes[] memory self) internal pure returns (bytes memory) { bytes memory payload = new bytes(0); for (uint i = 0; i < self.length; i++) { payload = mergeBytes(payload, self[i]); } return mergeBytes(encodeLength(payload.length, LIST_OFFSET), payload); } /** * @notice Concat two bytes arrays * @dev This should be optimize with assembly to save gas costs * @param param1 The first bytes array * @param param2 The second bytes array * @return The merged bytes array */ function mergeBytes(bytes memory param1, bytes memory param2) internal pure returns (bytes memory) { bytes memory merged = new bytes(param1.length + param2.length); uint k = 0; uint i; for (i = 0; i < param1.length; i++) { merged[k] = param1[i]; k++; } for (i = 0; i < param2.length; i++) { merged[k] = param2[i]; k++; } return merged; } /** * @notice Encode the first byte, followed by the `length` in binary form if `length` is more than 55. * @param length The length of the string or the payload * @param offset `STRING_OFFSET` if item is string, `LIST_OFFSET` if item is list * @return RLP encoded bytes */ function encodeLength(uint length, uint offset) internal pure returns (bytes memory) { require(length < 256**8, "input too long"); bytes memory rs = new bytes(1); if (length <= 55) { rs[0] = byte(uint8(length + offset)); return rs; } bytes memory bl = toBinary(length); rs[0] = byte(uint8(bl.length + offset + 55)); return mergeBytes(rs, bl); } /** * @notice Encode integer in big endian binary form with no leading zeroes * @dev This should be optimize with assembly to save gas costs * @param x The integer to encode * @return RLP encoded bytes */ function toBinary(uint x) internal pure returns (bytes memory) { uint i; bytes memory b = new bytes(32); assembly { mstore(add(b, 32), x) } for (i = 0; i < 32; i++) { if (b[i] != 0) { break; } } bytes memory rs = new bytes(32 - i); for (uint j = 0; j < rs.length; j++) { rs[j] = b[i++]; } return rs; } } // File: contracts/lib/BMT.sol pragma solidity ^0.5.12; library BMT { // TODO: remove recursive call function getRoot(bytes32[] memory level) internal view returns (bytes32) { if (level.length == 1) return level[0]; bytes32[] memory nextLevel = new bytes32[]((level.length + 1) / 2); uint i; for (; i + 1 < level.length; i += 2) { nextLevel[i/2] = keccak256(abi.encodePacked(level[i], level[i+1])); } if (level.length % 2 == 1) { nextLevel[i/2] = keccak256( abi.encodePacked(level[level.length - 1], level[level.length - 1]) ); } return getRoot(nextLevel); } function checkMembership( bytes32 leaf, uint256 index, bytes32 rootHash, bytes memory proof ) internal pure returns (bool) { require(proof.length % 32 == 0); uint256 numElements = proof.length / 32; require(numElements < 16); bytes32 proofElement; bytes32 computedHash = leaf; for (uint256 i = 32; i <= 32 * numElements; i += 32) { assembly { proofElement := mload(add(proof, i)) } if (index % 2 == 0) { computedHash = keccak256(abi.encodePacked(computedHash, proofElement)); } else { computedHash = keccak256(abi.encodePacked(proofElement, computedHash)); } index = index / 2; } return computedHash == rootHash; } } // File: contracts/RequestableI.sol pragma solidity ^0.5.12; interface RequestableI { function applyRequestInRootChain( bool isExit, uint256 requestId, address requestor, bytes32 trieKey, bytes calldata trieValue ) external returns (bool success); function applyRequestInChildChain( bool isExit, uint256 requestId, address requestor, bytes32 trieKey, bytes calldata trieValue ) external returns (bool success); } // File: contracts/lib/Data.sol pragma solidity ^0.5.12; // import "../patricia_tree/PatriciaTree.sol"; // use binary merkle tree library Data { using SafeMath for uint; using SafeMath for uint64; using Math for *; using RLP for *; using RLPEncode for *; using BMT for *; // solium-disable max-len bytes4 public constant APPLY_IN_CHILDCHAIN_SIGNATURE = bytes4(keccak256("applyRequestInChildChain(bool,uint256,address,bytes32,bytes)")); bytes4 public constant APPLY_IN_ROOTCHAIN_SIGNATURE = bytes4(keccak256("applyRequestInRootChain(bool,uint256,address,bytes32,bytes)")); // solium-enable max-len address public constant NA = address(0); uint public constant NA_TX_GAS_PRICE = 1e9; uint public constant NA_TX_GAS_LIMIT = 100000; // How many requests can be included in a single request block function MAX_REQUESTS() internal pure returns (uint) { // TODO: use 100 in production mode // return 1000; return 20; } // Timeout for URB submission function URE_TIMEOUT() internal pure returns (uint) { return 1 hours; } function decodePos(uint _pos) internal pure returns (uint v1, uint v2) { assembly { v1 := div(_pos, exp(2, 128)) v2 := and(_pos, sub(exp(2, 128), 1)) } } /** * highestFinalizedBlock * firstEpochNumber * blockToRenew 0 means no renew required * forkedBlock forked block number due to URB submission * last finalized block is forkedBlockNumber - 1 * urbEpochNumber * lastEpoch * lastBlock * lastFinalizedBlock * timestamp * firstEnterEpoch epoch number of first enter request epoch * lastEnterEpoch epoch number of last enter request epoch * nextBlockToRebase * rebased true if all blocks are rebased * epochs epochs in this fork * blocks blocks in this fork */ struct Fork { // uint64 blockToRenew; uint64 forkedBlock; // TODO: change to forkedEpoch uint64 firstEpoch; uint64 lastEpoch; uint64 firstBlock; uint64 lastBlock; uint64 lastFinalizedEpoch; uint64 lastFinalizedBlock; uint64 timestamp; uint64 firstEnterEpoch; uint64 lastEnterEpoch; uint64 nextBlockToRebase; bool rebased; mapping (uint => Epoch) epochs; mapping (uint => PlasmaBlock) blocks; } function getForkedEpoch(Fork storage self) internal view returns (uint64) { require(self.forkedBlock != 0); return self.blocks[self.forkedBlock].epochNumber; } /** * @notice Insert a block (ORB / NRB) into the fork. */ function insertBlock( Fork storage _f, bytes32 _statesRoot, bytes32 _transactionsRoot, bytes32 _receiptsRoot, bool _isRequest, bool _userActivated, bool _rebase ) internal returns (uint epochNumber, uint blockNumber) { epochNumber = _f.lastEpoch; blockNumber = _f.lastBlock.add(1); Data.Epoch storage epoch = _f.epochs[epochNumber]; if (blockNumber == epoch.endBlockNumber + 1) { epochNumber += 1; _f.lastEpoch = uint64(epochNumber); epoch = _f.epochs[epochNumber]; } require(epoch.startBlockNumber <= blockNumber); require(_rebase || epoch.endBlockNumber >= blockNumber); require(epoch.isRequest == _isRequest); require(epoch.userActivated == _userActivated); Data.PlasmaBlock storage b = _f.blocks[blockNumber]; b.epochNumber = uint64(epochNumber); b.statesRoot = _statesRoot; b.transactionsRoot = _transactionsRoot; b.receiptsRoot = _receiptsRoot; b.timestamp = uint64(block.timestamp); b.isRequest = _isRequest; b.userActivated = _userActivated; if (_isRequest) { b.requestBlockId = uint64(epoch.RE.firstRequestBlockId + blockNumber - epoch.startBlockNumber); } _f.lastBlock = uint64(blockNumber); return (epochNumber, blockNumber); } /** * TODO: implement insert rebased non-request epoch * @notice Insert non-request epoch into the fork. */ function insertNRE( Fork storage _f, uint _epochNumber, bytes32 _epochStateRoot, bytes32 _epochTransactionsRoot, bytes32 _epochReceiptsRoot, uint _startBlockNumber, uint _endBlockNumber ) internal { require(_f.lastEpoch.add(1) == _epochNumber); require(_f.lastBlock.add(1) == _startBlockNumber); Data.Epoch storage epoch = _f.epochs[_epochNumber]; require(!epoch.isRequest); require(!epoch.userActivated); require(!epoch.rebase); require(epoch.startBlockNumber == _startBlockNumber); require(epoch.endBlockNumber == _endBlockNumber); epoch.NRE.epochStateRoot = _epochStateRoot; epoch.NRE.epochTransactionsRoot = _epochTransactionsRoot; epoch.NRE.epochReceiptsRoot = _epochReceiptsRoot; epoch.NRE.submittedAt = uint64(block.timestamp); _f.lastEpoch = uint64(_epochNumber); _f.lastBlock = uint64(_endBlockNumber); } function getLastEpochNumber(Fork storage _f, bool _isRequest) internal returns (uint) { if (_f.epochs[_f.lastEpoch].isRequest == _isRequest) { return _f.lastEpoch; } return _f.lastEpoch - 1; } // function getFirstNotFinalizedEpochNumber(Fork storage _f, bool _isRequest) internal returns (uint) { // if (_f.epochs[_f.lastEpoch].isRequest == _isRequest) { // return _f.lastEpoch; // } // return _f.lastEpoch - 1; // } /** * @notice Update nextBlockToRebase to next request block containing enter request. * If all ORBs are rebased, return true. */ function checkNextORBToRebase( Fork storage _cur, Fork storage _pre, RequestBlock[] storage _rbs ) internal returns (bool finished) { uint blockNumber = _cur.nextBlockToRebase; uint epochNumber = _pre.blocks[_cur.nextBlockToRebase].epochNumber; // uint lastEpochNumber = getLastEpochNumber(_pre, true); while (_pre.epochs[epochNumber].initialized) { // at the end of epoch if (_pre.epochs[epochNumber].endBlockNumber <= blockNumber) { epochNumber += 2; blockNumber = _pre.epochs[epochNumber].startBlockNumber; } // skip until epoch has enter request while (_pre.epochs[epochNumber].RE.numEnter == 0 && _pre.epochs[epochNumber].initialized) { epochNumber += 2; blockNumber = _pre.epochs[epochNumber].startBlockNumber; } // short circuit if all OREs are empty or has no enter if (!_pre.epochs[epochNumber].initialized) { return true; } // skip blocks without enter request uint endBlockNumber = _pre.epochs[epochNumber].endBlockNumber; while (blockNumber <= endBlockNumber) { if (_rbs[_pre.blocks[blockNumber].requestBlockId].numEnter > 0) { break; } blockNumber += 1; } // continue if there is no block containing enter request if (blockNumber > endBlockNumber) { epochNumber += 2; blockNumber = _pre.epochs[epochNumber].startBlockNumber; continue; } // target block number is found _cur.nextBlockToRebase = uint64(blockNumber); return false; } // ready to prepare NRE return true; } /** * @notice Update nextBlockToRebase to next non request block * If all NRBs are rebased, return true. * TODO What if no ORE' ? */ function checkNextNRBToRebase( Fork storage _cur, Fork storage _pre ) internal returns (bool finished) { uint blockNumber = _cur.nextBlockToRebase; uint epochNumber = _pre.blocks[blockNumber].epochNumber; // at the end of epoch if (_pre.epochs[epochNumber].endBlockNumber <= blockNumber) { epochNumber += 2; blockNumber = _pre.epochs[epochNumber].startBlockNumber; } else { blockNumber += 1; } // short circit if all NRE's are rebased if (!_pre.epochs[epochNumber].initialized) { _cur.nextBlockToRebase = 0; return true; } // short circuit if block is not submitted if (_pre.blocks[blockNumber].timestamp == 0) { _cur.nextBlockToRebase = 0; return true; } _cur.nextBlockToRebase = uint64(blockNumber); return false; } /** * * startBlockNumber first block number of the epoch. * endBlockNumber last block number of the epoch. 0 if the epoch is ORE' / NRE' until ORE' is filled. * timestamp timestamp when the epoch is initialized. * required for URB / ORB * epochStateRoot merkle root of [block.stateRoot] for block in the epoch. * epochTransactionsRoot merkle root of [block.transactionsRoot] for block in the epoch. * epochReceiptsRoot merkle root of [block.receiptsRoot] for block in the epoch. * isEmpty true if request epoch has no request block * also and requestStart == requestEnd == previousEpoch.RE.requestEnd * and startBlockNumber == endBlockNumber == previousEpoch.endBlockNumber * and firstRequestBlockId == previousEpoch.firstRequestBlockId * initialized true if epoch is initialized * isRequest true in case of URB / ORB * userActivated true in case of URB * rebase true in case of ORE' or NRE' */ struct Epoch { uint64 startBlockNumber; uint64 endBlockNumber; uint64 timestamp; bool isEmpty; bool initialized; bool isRequest; bool userActivated; bool rebase; RequestEpochMeta RE; NonRequestEpochMeta NRE; } struct NonRequestEpochMeta { bytes32 epochStateRoot; bytes32 epochTransactionsRoot; bytes32 epochReceiptsRoot; uint64 submittedAt; uint64 finalizedAt; bool finalized; bool challenging; bool challenged; } /** * requestStart first request id. * requestEnd last request id. * firstRequestBlockId first id of RequestBlock[] * if epochs is ORE', copy from last request epoch in previous fork * numEnter number of enter request * nextEnterEpoch next request epoch including enter request * nextEpoch next non-empty request epoch */ struct RequestEpochMeta { uint64 requestStart; uint64 requestEnd; uint64 firstRequestBlockId; uint64 numEnter; uint64 nextEnterEpoch; uint64 nextEpoch; } // function noExit(Epoch storage self) internal returns (bool) { // if (self.rebase) return true; // return self.RE.requestEnd.sub64(self.RE.requestStart).add64(1) == self.RE.firstRequestBlockId; // } function getNumBlocks(Epoch storage _e) internal view returns (uint) { if (_e.isEmpty || _e.rebase && _e.endBlockNumber == 0) return 0; return _e.endBlockNumber + 1 - _e.startBlockNumber; } function getNumRequests(Epoch storage _e) internal view returns (uint) { if (_e.isEmpty || _e.rebase && _e.endBlockNumber == 0) return 0; return _e.RE.requestEnd + 1 - _e.RE.requestStart; } function calcNumBlock(uint _rs, uint _re) internal pure returns (uint) { return _re.sub(_rs).add(1).divCeil(MAX_REQUESTS()); } /** * epochNumber * requestBlockId id of RequestBlock[] * timestamp * referenceBlock block number in previous fork * statesRoot * transactionsRoot * receiptsRoot * isRequest true in case of URB & OR * userActivated true in case of URB * challenged true if it is challenge * challenging true if it is being challenged * finalized true if it is successfully finalize */ struct PlasmaBlock { uint64 epochNumber; uint64 requestBlockId; uint64 timestamp; uint64 finalizedAt; uint64 referenceBlock; bytes32 statesRoot; bytes32 transactionsRoot; bytes32 receiptsRoot; bool isRequest; bool userActivated; bool challenged; bool challenging; bool finalized; } /** * * timestamp * isExit * isTransfer * finalized true if request is finalized * challenged * value ether amount in wei * requestor * to requestable contract in root chain * trieKey * trieValue * hash keccak256 hash of request transaction (in plasma chain) */ struct Request { uint64 timestamp; bool isExit; bool isTransfer; bool finalized; bool challenged; uint128 value; address payable requestor; address to; bytes32 trieKey; bytes32 hash; bytes trieValue; } function applyRequestInRootChain( Request memory self, uint _requestId ) internal returns (bool) { require(gasleft() > NA_TX_GAS_LIMIT + 5000); return RequestableI(self.to).applyRequestInRootChain( self.isExit, _requestId, self.requestor, self.trieKey, self.trieValue ); } function toChildChainRequest( Request memory self, address _to ) internal pure returns (Request memory out) { out.isExit = self.isExit; out.isTransfer = self.isTransfer; out.requestor = self.requestor; // Enter request of EtherToken mints PETH to requestor. if (!self.isExit && self.isTransfer) { out.to = self.requestor; bytes memory b = self.trieValue; uint128 v; assembly { v := mload(add(b, 0x20)) } require(v > 0); // no trieKey and trieValue for EtherToken enter out.value = uint128(v); } else { out.to = _to; out.value = self.value; out.trieKey = self.trieKey; out.trieValue = self.trieValue; } } /** * @notice return tx.data */ function getData( Request memory self, uint _requestId, bool _rootchain ) internal pure returns (bytes memory out) { if (self.isTransfer && !self.isExit) { return out; } bytes4 funcSig = _rootchain ? APPLY_IN_ROOTCHAIN_SIGNATURE : APPLY_IN_CHILDCHAIN_SIGNATURE; out = abi.encodePacked( funcSig, abi.encode( bytes32(uint(self.isExit ? 1 : 0)), _requestId, uint256(uint160(self.requestor)), self.trieKey, self.trieValue ) ); } /** * @notice convert Request to TX */ function toTX( Request memory self, uint _requestId, bool _rootchain ) internal pure returns (TX memory out) { out.gasPrice = NA_TX_GAS_PRICE; out.gasLimit = uint64(NA_TX_GAS_LIMIT); out.to = self.to; out.value = self.value; out.data = getData(self, _requestId, _rootchain); } /** * submitted true if no more request can be inserted * because epoch is initialized * epochNumber non request epoch number where the request is created * requestStart first request id * requestEnd last request id * trie patricia tree contract address */ struct RequestBlock { bool submitted; uint64 numEnter; uint64 epochNumber; uint64 requestStart; uint64 requestEnd; address trie; } // function noExit(RequestBlock storage self) internal returns (bool) { // return self.RE.requestEnd.sub64(self.RE.requestStart).add64(1) == self.RE.firstRequestBlockId; // } function init(RequestBlock storage self) internal { /* use binary merkle tree instead of patricia tree if (self.trie == address(0)) { self.trie = new PatriciaTree(); } */ } function addRequest( RequestBlock storage self, Request storage _rootchainRequest, // request in root chain Request memory _childchainRequest, // request in child chain uint _requestId ) internal { _rootchainRequest.hash = hash(toTX(_childchainRequest, _requestId, false)); /* use binary merkle tree instead of patricia tree require(self.trie != address(0)); uint txIndex = _requestId.sub(self.RE.requestStart); bytes memory key = txIndex.encodeUint(); bytes memory value = toBytes(toTX(_request, _requestId, false)); PatriciaTree(self.trie).insert(key, value); self.transactionsRoot = PatriciaTree(self.trie).getRootHash(); */ } /* * TX for Ethereum transaction */ struct TX { uint64 nonce; uint256 gasPrice; uint64 gasLimit; address to; uint256 value; bytes data; uint256 v; uint256 r; uint256 s; } function isNATX(TX memory self) internal pure returns (bool) { return self.v == 0 && self.r == 0 && self.s == 0; } // function toTX(bytes memory self) internal pure returns (TX memory out) { // RLP.RLPItem[] memory packArr = self.toRLPItem().toList(9); // out.nonce = uint64(packArr[0].toUint()); // out.gasPrice = packArr[1].toUint(); // out.gasLimit = uint64(packArr[2].toUint()); // out.to = packArr[3].toAddress(); // out.value = packArr[4].toUint(); // out.data = packArr[5].toBytes(); // out.v = packArr[6].toUint(); // out.r = packArr[7].toUint(); // out.s = packArr[8].toUint(); // } /** * @notice Convert TX to RLP-encoded bytes */ function toBytes(TX memory self) internal pure returns (bytes memory out) { bytes[] memory packArr = new bytes[](9); packArr[0] = self.nonce.encodeUint(); packArr[1] = self.gasPrice.encodeUint(); packArr[2] = self.gasLimit.encodeUint(); packArr[3] = self.to.encodeAddress(); packArr[4] = self.value.encodeUint(); packArr[5] = self.data.encodeBytes(); packArr[6] = self.v.encodeUint(); packArr[7] = self.r.encodeUint(); packArr[8] = self.s.encodeUint(); return packArr.encodeList(); } function hash(TX memory self) internal pure returns (bytes32) { bytes memory txBytes = toBytes(self); return keccak256(txBytes); } /** * Transaction Receipt */ struct Log { address contractAddress; bytes32[] topics; bytes data; } struct Receipt { uint64 status; uint64 cumulativeGasUsed; bytes bloom; // 2048 bloom bits, byte[256] Log[] logs; } function toReceipt(bytes memory self) internal pure returns (Receipt memory r) { RLP.RLPItem[] memory items = self.toRLPItem().toList(4); r.status = uint64(items[0].toUint()); r.cumulativeGasUsed = uint64(items[1].toUint()); r.bloom = items[2].toBytes(); // TODO: parse Logs r.logs = new Log[](0); } function toReceiptStatus(bytes memory self) internal pure returns (uint) { RLP.RLPItem[] memory items = self.toRLPItem().toList(4); return items[0].toUint(); } /** * Helpers */ /** * @notice Checks transaction root of a request block */ function _checkTxRoot( bytes32 _transactionsRoot, RequestBlock storage _rb, Request[] storage _rs, bool _skipExit ) internal { uint s = _rb.requestStart; uint e = _rb.requestEnd; uint n = _skipExit ? _rb.numEnter : e - s + 1; require(n > 0); bytes32[] memory hashes = new bytes32[](n); // TODO: optimize to reduce gas uint j = s; for (uint i = s; i <= e; i++) { if (!_skipExit || !_rs[i].isExit) { hashes[j - s] = _rs[i].hash; j++; } } require(hashes.getRoot() == _transactionsRoot); /* use binary merkle tree instead of patricia tree Data.RequestBlock storage ORB = ORBs[fork.blocks[blockNumber].requestBlockId]; require(_transactionsRoot == ORB.transactionsRoot); */ } } // File: contracts/lib/Address.sol // https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/utils/Address.sol pragma solidity ^0.5.12; /** * Utility library of inline functions on addresses */ library Address { /** * Returns whether the target address is a contract * @dev This function will return false if invoked during the constructor of a contract, * as the code is not actually created until after the constructor finishes. * @param account address of the account to check * @return whether the target address is a contract */ function isContract(address account) internal view returns (bool) { uint256 size; // XXX Currently there is no better way to check if there is a contract in an address // than to check the size of the code at that address. // See https://ethereum.stackexchange.com/a/14016/36603 // for more details about how this works. // TODO Check this again before the Serenity release, because all addresses will be // contracts then. // solium-disable-next-line security/no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } } // File: contracts/Layer2Storage.sol pragma solidity ^0.5.12; contract Layer2Storage { /* * Storage */ bool public development; // dev mode address public operator; address public epochHandler; address public submitHandler; address public etherToken; address public seigManager; // 1 epoch = N NRBs or k URBs or k ORBs. // N consecutive NRBs must be submitted in an epoch. In case of request block, // massive requests can be included in k ORBs, and k is determined when // N NRBs are submitted or when preparing URBs submission. uint public NRELength; // Increase for each URB uint public currentFork; // First not-empty request epochs of a fork mapping (uint => uint) public firstFilledORENumber; mapping (uint => Data.Fork) public forks; // Enter & Exit requests for ORB / URB Data.Request[] public EROs; Data.Request[] public ERUs; // Consecutive request block. The fork where they are in is defined in Data.PlasmaBlock Data.RequestBlock[] public ORBs; Data.RequestBlock[] public URBs; // count enter requests for epoch uint public numEnterForORB; // epoch number of last non-empty request epoch. mapping(uint => uint) public lastNonEmptyRequestEpoch; // epoch number of first non-empty request epoch. mapping(uint => uint) public firstNonEmptyRequestEpoch; // Last applied request uint public lastAppliedForkNumber; uint public lastAppliedEpochNumber; uint public lastAppliedBlockNumber; // solium-disable mixedcase uint public EROIdToFinalize; uint public ERUIdToFinalize; // solium-enable mixedcase // uint public finalizableEROId = 2^256 - 1; // uint public finalizableERUId = 2^256 - 1; // Requestable contract address in child chain mapping (address => address) public requestableContracts; /* * Constant */ address constant public NULL_ADDRESS = 0x0000000000000000000000000000000000000000; // Cost parameters for development and test uint public constant COST_ERO = 0; uint public constant COST_ERU = 0; uint public constant COST_URB_PREPARE = 0; uint public constant COST_URB = 0; uint public constant COST_ORB = 0; uint public constant COST_NRB = 0; uint public constant PREPARE_TIMEOUT = 60; // 60 sec for dev // Challenge periods for computation and withholding uint public constant CP_COMPUTATION = 15; // 15 sec for dev uint public constant CP_WITHHOLDING = 20; // 20 sec for dev uint public constant CP_EXIT = 10; // 10 sec for dev // TODO: develop more concrete cost model // Cost parameters for production // uint public constant COST_ERO = 0.1 ether; // cost for invalid exit // uint public constant COST_ERU = 0.2 ether; // cost for fork & rebase // uint public constant COST_URB_PREPARE = 0.1 ether; // cost for URB prepare // uint public constant COST_URB = 0.9 ether; // cost for fork & rebase // uint public constant COST_ORB = 0.1 ether; // cost for invalid computation // uint public constant COST_NRB = 0.1 ether; // cost for invalid computation // uint public constant PREPARE_TIMEOUT = 1 hours; // // Challenge periods for computation and withholding // uint public constant CP_COMPUTATION = 1 days; // uint public constant CP_WITHHOLDING = 7 days; // uint public constant CP_EXIT = 1 days; // Gas limit for request trasaction uint public constant REQUEST_GAS = 100000; bool public constant isLayer2 = true; } // File: contracts/Layer2Event.sol pragma solidity ^0.5.12; contract Layer2Event { event OperatorChanged(address _newOperator); event SessionTimeout(bool userActivated); event Forked(uint newFork, uint epochNumber, uint forkedBlockNumber); /** * epochNumber the number of prepared epoch * startBlockNumber first block number of the epoch. * endBlockNumber last block number of the epoch. It is 0 for ORE' and NRE'. * requestStart first request id of the epoch. * requestEnd last request id of the epoch. * epochIsEmpty true if epoch doesn't have block. * isRequest true for ORE and URE. * userActivated true for URE. */ event EpochPrepared( uint forkNumber, uint epochNumber, uint startBlockNumber, uint endBlockNumber, uint requestStart, uint requestEnd, bool epochIsEmpty, bool isRequest, bool userActivated, bool rebase ); event EpochFilling( uint forkNumber, uint epochNumber ); event EpochFilled( uint forkNumber, uint epochNumber ); event EpochRebased( uint forkNumber, uint epochNumber, uint startBlockNumber, uint endBlockNumber, uint requestStart, uint requestEnd, bool epochIsEmpty, bool isRequest, bool userActivated ); event BlockSubmitted( uint fork, uint epochNumber, uint blockNumber, bool isRequest, bool userActivated ); event RequestCreated( uint requestId, address requestor, address to, uint weiAmount, bytes32 trieKey, bytes trieValue, bool isExit, bool userActivated ); event ERUCreated( uint requestId, address requestor, address to, bytes trieKey, bytes32 trieValue ); event BlockFinalized(uint forkNumber, uint blockNumber); event EpochFinalized( uint forkNumber, uint epochNumber, uint startBlockNumber, uint endBlockNumber ); // emit when exit is finalized. _userActivated is true for ERU event RequestFinalized(uint requestId, bool userActivated); event RequestApplied(uint requestId, bool userActivated); event RequestChallenged(uint requestId, bool userActivated); event RequestableContractMapped(address contractInRootchain, address contractInChildchain); } // File: contracts/Layer2Base.sol pragma solidity ^0.5.12; /** * @notice Layer2Base provides functions to be delegated to other handlers, * EpochHandler, SubmitHandler. */ contract Layer2Base is Layer2Storage, Layer2Event { /** * Constants */ // solium-disable mixedcase // EpochHandler functions bytes4 constant PREPARE_TO_SUTMIBT_ORB_SIG = bytes4(keccak256("prepareORE()")); bytes4 constant PREPARE_TO_SUTMIBT_NRB_SIG = bytes4(keccak256("prepareNRE()")); bytes4 constant PREPARE_TO_SUTMIBT_URB_SIG = bytes4(keccak256("prepareToSubmitURB()")); bytes4 constant PREPARE_ORE_AFTER_URE_SIG = bytes4(keccak256("prepareOREAfterURE()")); bytes4 constant PREPARE_NRE_AFTER_URE_SIG = bytes4(keccak256("prepareNREAfterURE()")); // SubmitHandler functions bytes4 constant SUBMIT_NRE_SIG = bytes4(keccak256("submitNRE(uint256,uint256,bytes32,bytes32,bytes32)")); bytes4 constant SUBMIT_ORB_SIG = bytes4(keccak256("submitORB(uint256,bytes32,bytes32,bytes32)")); bytes4 constant SUBMIT_URB_SIG = bytes4(keccak256("submitURB(uint256,bytes32,bytes32,bytes32)")); // solium-endable mixedcase /** * Functions */ // delegate to epoch handler function _delegatePrepareORE() internal { // solium-disable-next-line security/no-low-level-calls, max-len, no-unused-vars (bool success, bytes memory returnData) = epochHandler.delegatecall(abi.encodeWithSelector(PREPARE_TO_SUTMIBT_ORB_SIG)); require(success); } // delegate to epoch handler function _delegatePrepareNRE() internal { // solium-disable-next-line security/no-low-level-calls, max-len, no-unused-vars (bool success, bytes memory returnData) = epochHandler.delegatecall(abi.encodeWithSelector(PREPARE_TO_SUTMIBT_NRB_SIG)); // (bool success, bytes memory returnData) = epochHandler.delegatecall(abi.encodeWithSelector(PREPARE_TO_SUTMIBT_NRB_SIG)); require(success); } // delegate to epoch handler function _delegatePrepareToSubmitURB() internal { // solium-disable-next-line security/no-low-level-calls, max-len, no-unused-vars (bool success, bytes memory returnData) = epochHandler.delegatecall(abi.encodeWithSelector(PREPARE_TO_SUTMIBT_URB_SIG)); // (bool success, bytes memory returnData) = epochHandler.delegatecall(abi.encodeWithSelector(PREPARE_TO_SUTMIBT_NRB_SIG)); require(success); } // delegate to epoch handler function _delegatePrepareOREAfterURE() internal { // solium-disable-next-line security/no-low-level-calls, max-len, no-unused-vars (bool success, bytes memory returnData) = epochHandler.delegatecall(abi.encodeWithSelector(PREPARE_ORE_AFTER_URE_SIG)); require(success); } // delegate to epoch handler function _delegatePrepareNREAfterURE() internal { // solium-disable-next-line security/no-low-level-calls, max-len, no-unused-vars (bool success, bytes memory returnData) = epochHandler.delegatecall(abi.encodeWithSelector(PREPARE_NRE_AFTER_URE_SIG)); require(success); } // delegate to submit handler function _delegateSubmitNRE( uint _pos1, // forknumber + epochNumber uint _pos2, // startBlockNumber + endBlockNumber bytes32 _epochStateRoot, bytes32 _epochTransactionsRoot, bytes32 _epochReceiptsRoot ) internal returns (bool success) { // solium-disable-next-line security/no-low-level-calls, max-len, no-unused-vars (bool success, bytes memory returnData) = submitHandler.delegatecall(abi.encodeWithSelector( SUBMIT_NRE_SIG, _pos1, _pos2, _epochStateRoot, _epochTransactionsRoot, _epochReceiptsRoot )); require(success); return true; } // delegate to submit handler function _delegateSubmitORB( uint _pos, bytes32 _statesRoot, bytes32 _transactionsRoot, bytes32 _receiptsRoot ) internal returns (bool success) { // solium-disable-next-line security/no-low-level-calls, max-len, no-unused-vars (bool success, bytes memory returnData) = submitHandler.delegatecall(abi.encodeWithSelector( SUBMIT_ORB_SIG, _pos, _statesRoot, _transactionsRoot, _receiptsRoot )); require(success); return true; } // delegate to submit handler function _delegateSubmitURB( uint _pos, bytes32 _statesRoot, bytes32 _transactionsRoot, bytes32 _receiptsRoot ) internal returns (bool success) { // solium-disable-next-line security/no-low-level-calls, max-len, no-unused-vars (bool success, bytes memory returnData) = submitHandler.delegatecall(abi.encodeWithSelector( SUBMIT_URB_SIG, _pos, _statesRoot, _transactionsRoot, _receiptsRoot )); require(success); return true; } } // File: contracts/stake/interfaces/SeigManagerI.sol pragma solidity ^0.5.12; interface SeigManagerI { function registry() external view returns (address); function depositManager() external view returns (address); function ton() external view returns (address); function wton() external view returns (address); function powerton() external view returns (address); function tot() external view returns (address); function coinages(address layer2) external view returns (address); function commissionRates(address layer2) external view returns (uint256); function lastCommitBlock(address layer2) external view returns (uint256); function seigPerBlock() external view returns (uint256); function lastSeigBlock() external view returns (uint256); function pausedBlock() external view returns (uint256); function unpausedBlock() external view returns (uint256); function DEFAULT_FACTOR() external view returns (uint256); function deployCoinage(address layer2) external returns (bool); function setCommissionRate(address layer2, uint256 commission, bool isCommissionRateNegative) external returns (bool); function uncomittedStakeOf(address layer2, address account) external view returns (uint256); function stakeOf(address layer2, address account) external view returns (uint256); function additionalTotBurnAmount(address layer2, address account, uint256 amount) external view returns (uint256 totAmount); function onTransfer(address sender, address recipient, uint256 amount) external returns (bool); function updateSeigniorage() external returns (bool); function onDeposit(address layer2, address account, uint256 amount) external returns (bool); function onWithdraw(address layer2, address account, uint256 amount) external returns (bool); } // File: contracts/handlers/SubmitHandler.sol pragma solidity ^0.5.12; contract SubmitHandler is Layer2Storage, Layer2Event, Layer2Base { using SafeMath for uint; using SafeMath for uint64; using Math for *; using Data for *; using Address for address; using BMT for *; constructor(address _epochHandler) public { epochHandler = _epochHandler; submitHandler = address(this); } function submitNRE( uint _pos1, // forknumber + epochNumber uint _pos2, // startBlockNumber + endBlockNumber bytes32 _epochStateRoot, bytes32 _epochTransactionsRoot, bytes32 _epochReceiptsRoot ) public payable returns (bool success) { (uint forkNumber, uint epochNumber) = _pos1.decodePos(); require(currentFork == forkNumber, "currentFork == forkNumber"); (uint startBlockNumber, uint endBlockNumber) = _pos2.decodePos(); forks[forkNumber].insertNRE( epochNumber, _epochStateRoot, _epochTransactionsRoot, _epochReceiptsRoot, startBlockNumber, endBlockNumber ); _delegatePrepareORE(); if (address(seigManager) != address(0)) { require(SeigManagerI(seigManager).updateSeigniorage()); } return true; } function submitORB( uint _pos, bytes32 _statesRoot, bytes32 _transactionsRoot, bytes32 _receiptsRoot ) public payable returns (bool success) { uint forkNumber; uint blockNumber; (forkNumber, blockNumber) = _pos.decodePos(); require(currentFork == forkNumber); require(forks[forkNumber].lastBlock + 1 == blockNumber); Data.Fork storage curFork = forks[forkNumber]; uint epochNumber; uint requestBlockId; // If not forked or already rebased if (forkNumber == 0 || forks[forkNumber - 1].forkedBlock != 0 && curFork.rebased) { (epochNumber, blockNumber) = curFork.insertBlock( _statesRoot, _transactionsRoot, _receiptsRoot, true, false, false ); if (!development) { _transactionsRoot._checkTxRoot( ORBs[curFork.blocks[curFork.lastBlock].requestBlockId], EROs, false ); } requestBlockId = curFork.blocks[blockNumber].requestBlockId; // accunulate # of enters into epoch curFork.epochs[epochNumber].RE.numEnter += ORBs[requestBlockId].numEnter; emit BlockSubmitted( forkNumber, epochNumber, blockNumber, true, false ); if (blockNumber == curFork.epochs[epochNumber].endBlockNumber) { _delegatePrepareNRE(); } if (address(seigManager) != address(0)) { require(SeigManagerI(seigManager).updateSeigniorage()); } return true; } // Otherwise, compare to block in previous fork (epochNumber, blockNumber) = curFork.insertBlock( _statesRoot, _transactionsRoot, _receiptsRoot, true, false, true ); Data.Fork storage preFork = forks[forkNumber - 1]; Data.PlasmaBlock storage curBlock = curFork.blocks[blockNumber]; curBlock.referenceBlock = curFork.nextBlockToRebase; curBlock.requestBlockId = preFork.blocks[curFork.nextBlockToRebase].requestBlockId; if (!development) { _transactionsRoot._checkTxRoot( ORBs[curBlock.requestBlockId], EROs, true ); } emit BlockSubmitted( forkNumber, epochNumber, blockNumber, true, false ); // if ORB' is filled. if (curFork.checkNextORBToRebase(preFork, ORBs)) { curFork.epochs[epochNumber].endBlockNumber = uint64(blockNumber); emit EpochRebased( forkNumber, epochNumber, curFork.epochs[epochNumber].startBlockNumber, blockNumber, curFork.epochs[epochNumber].RE.requestStart, 0, false, true, false ); _delegatePrepareNREAfterURE(); } if (address(seigManager) != address(0)) { require(SeigManagerI(seigManager).updateSeigniorage()); } return true; } function submitURB( uint _pos, bytes32 _statesRoot, bytes32 _transactionsRoot, bytes32 _receiptsRoot ) public payable returns (bool success) { uint forkNumber; uint blockNumber; (forkNumber, blockNumber) = _pos.decodePos(); bool firstURB = currentFork + 1 == forkNumber; require(firstURB || currentFork == forkNumber); Data.Fork storage fork = forks[forkNumber]; if (firstURB) { currentFork = forkNumber; fork = forks[forkNumber]; require(fork.timestamp + Data.URE_TIMEOUT() > block.timestamp); // check block number require(blockNumber == fork.firstBlock); emit Forked(forkNumber, fork.lastEpoch, fork.firstBlock); } else { // check block number require(blockNumber == fork.lastBlock.add64(1)); } Data.Epoch storage epoch = fork.epochs[fork.lastEpoch]; require(epoch.isRequest); require(epoch.userActivated); Data.PlasmaBlock storage b = fork.blocks[blockNumber]; b.epochNumber = fork.lastEpoch; b.statesRoot = _statesRoot; b.transactionsRoot = _transactionsRoot; b.receiptsRoot = _receiptsRoot; b.timestamp = uint64(block.timestamp); b.isRequest = true; b.userActivated = true; fork.lastBlock = uint64(blockNumber); if (!development) { _transactionsRoot._checkTxRoot( URBs[fork.blocks[fork.lastBlock].requestBlockId], ERUs, false ); } emit BlockSubmitted( forkNumber, fork.lastEpoch, blockNumber, true, true ); // TODO: use internal function to avoide stack too deep error if (blockNumber == epoch.endBlockNumber) { _delegatePrepareOREAfterURE(); } if (address(seigManager) != address(0)) { require(SeigManagerI(seigManager).updateSeigniorage()); } return true; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_epochHandler","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"forkNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"BlockFinalized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"fork","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"epochNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"blockNumber","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isRequest","type":"bool"},{"indexed":false,"internalType":"bool","name":"userActivated","type":"bool"}],"name":"BlockSubmitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":false,"internalType":"address","name":"requestor","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"bytes","name":"trieKey","type":"bytes"},{"indexed":false,"internalType":"bytes32","name":"trieValue","type":"bytes32"}],"name":"ERUCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"forkNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"epochNumber","type":"uint256"}],"name":"EpochFilled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"forkNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"epochNumber","type":"uint256"}],"name":"EpochFilling","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"forkNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"epochNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startBlockNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endBlockNumber","type":"uint256"}],"name":"EpochFinalized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"forkNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"epochNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startBlockNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endBlockNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"requestStart","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"requestEnd","type":"uint256"},{"indexed":false,"internalType":"bool","name":"epochIsEmpty","type":"bool"},{"indexed":false,"internalType":"bool","name":"isRequest","type":"bool"},{"indexed":false,"internalType":"bool","name":"userActivated","type":"bool"},{"indexed":false,"internalType":"bool","name":"rebase","type":"bool"}],"name":"EpochPrepared","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"forkNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"epochNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startBlockNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endBlockNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"requestStart","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"requestEnd","type":"uint256"},{"indexed":false,"internalType":"bool","name":"epochIsEmpty","type":"bool"},{"indexed":false,"internalType":"bool","name":"isRequest","type":"bool"},{"indexed":false,"internalType":"bool","name":"userActivated","type":"bool"}],"name":"EpochRebased","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newFork","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"epochNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"forkedBlockNumber","type":"uint256"}],"name":"Forked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_newOperator","type":"address"}],"name":"OperatorChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"userActivated","type":"bool"}],"name":"RequestApplied","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"userActivated","type":"bool"}],"name":"RequestChallenged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":false,"internalType":"address","name":"requestor","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"weiAmount","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"trieKey","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"trieValue","type":"bytes"},{"indexed":false,"internalType":"bool","name":"isExit","type":"bool"},{"indexed":false,"internalType":"bool","name":"userActivated","type":"bool"}],"name":"RequestCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"userActivated","type":"bool"}],"name":"RequestFinalized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"contractInRootchain","type":"address"},{"indexed":false,"internalType":"address","name":"contractInChildchain","type":"address"}],"name":"RequestableContractMapped","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"userActivated","type":"bool"}],"name":"SessionTimeout","type":"event"},{"constant":true,"inputs":[],"name":"COST_ERO","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"COST_ERU","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"COST_NRB","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"COST_ORB","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"COST_URB","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"COST_URB_PREPARE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"CP_COMPUTATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"CP_EXIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"CP_WITHHOLDING","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"EROIdToFinalize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"EROs","outputs":[{"internalType":"uint64","name":"timestamp","type":"uint64"},{"internalType":"bool","name":"isExit","type":"bool"},{"internalType":"bool","name":"isTransfer","type":"bool"},{"internalType":"bool","name":"finalized","type":"bool"},{"internalType":"bool","name":"challenged","type":"bool"},{"internalType":"uint128","name":"value","type":"uint128"},{"internalType":"address payable","name":"requestor","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes32","name":"trieKey","type":"bytes32"},{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"bytes","name":"trieValue","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ERUIdToFinalize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"ERUs","outputs":[{"internalType":"uint64","name":"timestamp","type":"uint64"},{"internalType":"bool","name":"isExit","type":"bool"},{"internalType":"bool","name":"isTransfer","type":"bool"},{"internalType":"bool","name":"finalized","type":"bool"},{"internalType":"bool","name":"challenged","type":"bool"},{"internalType":"uint128","name":"value","type":"uint128"},{"internalType":"address payable","name":"requestor","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes32","name":"trieKey","type":"bytes32"},{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"bytes","name":"trieValue","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"NRELength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"NULL_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"ORBs","outputs":[{"internalType":"bool","name":"submitted","type":"bool"},{"internalType":"uint64","name":"numEnter","type":"uint64"},{"internalType":"uint64","name":"epochNumber","type":"uint64"},{"internalType":"uint64","name":"requestStart","type":"uint64"},{"internalType":"uint64","name":"requestEnd","type":"uint64"},{"internalType":"address","name":"trie","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"PREPARE_TIMEOUT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"REQUEST_GAS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"URBs","outputs":[{"internalType":"bool","name":"submitted","type":"bool"},{"internalType":"uint64","name":"numEnter","type":"uint64"},{"internalType":"uint64","name":"epochNumber","type":"uint64"},{"internalType":"uint64","name":"requestStart","type":"uint64"},{"internalType":"uint64","name":"requestEnd","type":"uint64"},{"internalType":"address","name":"trie","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"currentFork","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"development","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"epochHandler","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"etherToken","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"firstFilledORENumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"firstNonEmptyRequestEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"forks","outputs":[{"internalType":"uint64","name":"forkedBlock","type":"uint64"},{"internalType":"uint64","name":"firstEpoch","type":"uint64"},{"internalType":"uint64","name":"lastEpoch","type":"uint64"},{"internalType":"uint64","name":"firstBlock","type":"uint64"},{"internalType":"uint64","name":"lastBlock","type":"uint64"},{"internalType":"uint64","name":"lastFinalizedEpoch","type":"uint64"},{"internalType":"uint64","name":"lastFinalizedBlock","type":"uint64"},{"internalType":"uint64","name":"timestamp","type":"uint64"},{"internalType":"uint64","name":"firstEnterEpoch","type":"uint64"},{"internalType":"uint64","name":"lastEnterEpoch","type":"uint64"},{"internalType":"uint64","name":"nextBlockToRebase","type":"uint64"},{"internalType":"bool","name":"rebased","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isLayer2","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastAppliedBlockNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastAppliedEpochNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastAppliedForkNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"lastNonEmptyRequestEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"numEnterForORB","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"operator","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"requestableContracts","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"seigManager","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"submitHandler","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_pos1","type":"uint256"},{"internalType":"uint256","name":"_pos2","type":"uint256"},{"internalType":"bytes32","name":"_epochStateRoot","type":"bytes32"},{"internalType":"bytes32","name":"_epochTransactionsRoot","type":"bytes32"},{"internalType":"bytes32","name":"_epochReceiptsRoot","type":"bytes32"}],"name":"submitNRE","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_pos","type":"uint256"},{"internalType":"bytes32","name":"_statesRoot","type":"bytes32"},{"internalType":"bytes32","name":"_transactionsRoot","type":"bytes32"},{"internalType":"bytes32","name":"_receiptsRoot","type":"bytes32"}],"name":"submitORB","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_pos","type":"uint256"},{"internalType":"bytes32","name":"_statesRoot","type":"bytes32"},{"internalType":"bytes32","name":"_transactionsRoot","type":"bytes32"},{"internalType":"bytes32","name":"_receiptsRoot","type":"bytes32"}],"name":"submitURB","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"payable":true,"stateMutability":"payable","type":"function"}]
Deployed Bytecode
0x6080604052600436106102305760003560e01c8063a820c0671161012e578063c8ad329f116100ab578063e259faf71161006f578063e259faf71461077b578063e7b88b8014610790578063ea7f22a8146107a5578063f4f31de4146107cf578063fb788a27146107f957610230565b8063c8ad329f146106f4578063ca6f638014610709578063d691acd814610235578063da0185f814610733578063de0ce17d1461076657610230565b8063b6715647116100f2578063b671564714610616578063b8066bcb14610640578063c0e8606414610655578063c2bc88fa146106ca578063c54626cc146106df57610230565b8063a820c067146104a1578063ab96da2d146104d0578063b17fa6e9146104e5578063b2ae9ba814610235578063b443f3cc146104fa57610230565b8063570ca735116101bc5780638155717d116101805780638155717d14610462578063882eed2c146104775780638b5172d0146102355780638eb288ca1461048c57806394be3aa51461023557610230565b8063570ca735146103ae5780636f3e4b90146103df5780636fb7f5581461040e57806372ecb9a8146104235780637b929c271461044d57610230565b8063183d2d1c11610203578063183d2d1c146102cf578063192adc5b1461023557806323691566146102e45780632dc6bb7b146102f95780634ba3a1261461030e57610230565b8063033cfbed1461023557806308c4fff01461025c5780630eaf45a814610271578063164bc2ae146102ba575b600080fd5b34801561024157600080fd5b5061024a61080e565b60408051918252519081900360200190f35b34801561026857600080fd5b5061024a610813565b6102a6600480360360a081101561028757600080fd5b5080359060208101359060408101359060608101359060800135610818565b604080519115158252519081900360200190f35b3480156102c657600080fd5b5061024a610956565b3480156102db57600080fd5b5061024a61095c565b3480156102f057600080fd5b5061024a610962565b34801561030557600080fd5b5061024a610968565b34801561031a57600080fd5b506103386004803603602081101561033157600080fd5b503561096e565b604080516001600160401b039d8e1681529b8d1660208d0152998c168b8b0152978b1660608b0152958a1660808a015293891660a089015291881660c0880152871660e0870152861661010086015285166101208501529093166101408301529115156101608201529051908190036101800190f35b3480156103ba57600080fd5b506103c36109e5565b604080516001600160a01b039092168252519081900360200190f35b6102a6600480360360808110156103f557600080fd5b50803590602081013590604081013590606001356109f9565b34801561041a57600080fd5b506103c3610d8f565b34801561042f57600080fd5b5061024a6004803603602081101561044657600080fd5b5035610d9e565b34801561045957600080fd5b506102a6610db0565b34801561046e57600080fd5b5061024a610db9565b34801561048357600080fd5b506102a6610dbe565b34801561049857600080fd5b5061024a610dc3565b6102a6600480360360808110156104b757600080fd5b5080359060208101359060408101359060600135610dca565b3480156104dc57600080fd5b5061024a61133a565b3480156104f157600080fd5b5061024a611340565b34801561050657600080fd5b506105246004803603602081101561051d57600080fd5b5035611345565b604080516001600160401b038d1681528b15156020808301919091528b151592820192909252891515606082015288151560808201526001600160801b03881660a08201526001600160a01b0380881660c0830152861660e082015261010081018590526101208101849052610160610140820181815284519183019190915283519192909161018084019185019080838360005b838110156105d15781810151838201526020016105b9565b50505050905090810190601f1680156105fe5780820380516001836020036101000a031916815260200191505b509c5050505050505050505050505060405180910390f35b34801561062257600080fd5b5061024a6004803603602081101561063957600080fd5b5035611466565b34801561064c57600080fd5b506103c3611478565b34801561066157600080fd5b5061067f6004803603602081101561067857600080fd5b5035611487565b6040805196151587526001600160401b03958616602088015293851686850152918416606086015290921660808401526001600160a01b0390911660a0830152519081900360c00190f35b3480156106d657600080fd5b5061024a6114ee565b3480156106eb57600080fd5b5061024a6114f3565b34801561070057600080fd5b5061024a6114f9565b34801561071557600080fd5b5061024a6004803603602081101561072c57600080fd5b50356114ff565b34801561073f57600080fd5b506103c36004803603602081101561075657600080fd5b50356001600160a01b0316611511565b34801561077257600080fd5b506103c361080e565b34801561078757600080fd5b506103c361152c565b34801561079c57600080fd5b506103c361153b565b3480156107b157600080fd5b5061067f600480360360208110156107c857600080fd5b503561154a565b3480156107db57600080fd5b50610524600480360360208110156107f257600080fd5b5035611557565b34801561080557600080fd5b5061024a611564565b600081565b600f81565b60008060006108268861156a565b915091508160065414610880576040805162461bcd60e51b815260206004820152601960248201527f63757272656e74466f726b203d3d20666f726b4e756d62657200000000000000604482015290519081900360640190fd5b60008061088c8961156a565b600086815260086020526040902091935091506108b490848a8a8a878763ffffffff61158016565b6108bc6116c6565b6004546001600160a01b031615610946576004805460408051633b253c2b60e11b815290516001600160a01b039092169263764a78569282820192602092908290030181600087803b15801561091157600080fd5b505af1158015610925573d6000803e3d6000fd5b505050506040513d602081101561093b57600080fd5b505161094657600080fd5b5060019998505050505050505050565b60105481565b60065481565b600d5481565b60135481565b6008602052600090815260409020805460018201546002909201546001600160401b0380831693600160401b808504831694600160801b808204851695600160c01b92839004861695858116958581048216958482048316959182900483169484841694918204841693908204169160ff9104168c565b60005461010090046001600160a01b031681565b6000806000610a078761156a565b600654919350915060010182148080610a21575082600654145b610a2a57600080fd5b60008381526008602052604090208115610af657506006839055600083815260086020526040902042610a5b6117cb565b6001830154600160c01b90046001600160401b03160111610a7b57600080fd5b8054600160c01b90046001600160401b03168314610a9857600080fd5b8054604080518681526001600160401b03600160801b840481166020830152600160c01b90930490921682820152517f0647d42ab02f6e0ae76959757dcb6aa6feac1d4ba6f077f1223fb4b1b429f06c9181900360600190a1610b2b565b600181810154610b17916001600160401b039091169063ffffffff6117d116565b6001600160401b03168314610b2b57600080fd5b8054600160801b90046001600160401b0316600090815260038201602052604090208054600160d01b900460ff16610b6257600080fd5b8054600160d81b900460ff16610b7757600080fd5b600084815260048381016020526040822084548154600283018e9055600383018d90559282018b9055600160801b908190046001600160401b0390811667ffffffffffffffff199485161767ffffffffffffffff60801b19164282169290920291909117825560058201805461010060ff19909116600190811761ff001916919091179091558601805490931690881617909155905460ff16610c725760018301546001600160401b039081166000908152600485016020526040902054600c8054610c72939192600160401b9004909116908110610c5257fe5b6000918252602082208c9260029092020190600a9063ffffffff6117f616565b825460408051888152600160801b9092046001600160401b031660208301528181018790526001606083018190526080830152517f3d4a04291c66b06f39a4ecb817875b12b5485a05ec563133a56a905305c48e559160a0908290030190a18154600160401b90046001600160401b0316851415610cf257610cf2611918565b6004546001600160a01b031615610d7c576004805460408051633b253c2b60e11b815290516001600160a01b039092169263764a78569282820192602092908290030181600087803b158015610d4757600080fd5b505af1158015610d5b573d6000803e3d6000fd5b505050506040513d6020811015610d7157600080fd5b5051610d7c57600080fd5b600196505050505050505b949350505050565b6004546001600160a01b031681565b60076020526000908152604090205481565b60005460ff1681565b600a81565b600181565b620186a081565b6000806000610dd88761156a565b60065491935091508214610deb57600080fd5b60008281526008602052604090206001908101546001600160401b03908116909101168114610e1957600080fd5b60008281526008602052604081209080841580610e67575060001985016000908152600860205260409020546001600160401b031615801590610e6757506002830154600160c01b900460ff165b1561109257610e83838a8a8a600160008063ffffffff6119ac16565b60005490955090925060ff16610ef15760018301546001600160401b039081166000908152600485016020526040902054600b8054610ef1939192600160401b9004909116908110610ed157fe5b6000918252602082208b926002909202019060099063ffffffff6117f616565b506000838152600483016020526040902054600b8054600160401b9092046001600160401b03169182908110610f2357fe5b60009182526020808320600292909202909101548483526003860182526040808420600190810180546001600160c01b0381166101009095046001600160401b03908116600160c01b9283900482160116029390931790925580518981529283018690528281018890526060830191909152608082019290925290517f3d4a04291c66b06f39a4ecb817875b12b5485a05ec563133a56a905305c48e559160a0908290030190a16000828152600384016020526040902054600160401b90046001600160401b0316841415610ffa57610ffa611bb7565b6004546001600160a01b031615611084576004805460408051633b253c2b60e11b815290516001600160a01b039092169263764a78569282820192602092908290030181600087803b15801561104f57600080fd5b505af1158015611063573d6000803e3d6000fd5b505050506040513d602081101561107957600080fd5b505161108457600080fd5b600195505050505050610d87565b6110a9838a8a8a600160008163ffffffff6119ac16565b600019870160009081526008602090815260408083208484526004808a01845282852060028b01805460018301805467ffffffffffffffff19166001600160401b03600160801b9384900481169190911790915591540481168752918301909452918420548354600160401b918290049093160267ffffffffffffffff60401b199092169190911782559154929750929450919060ff16611186578054600b805461118692600160401b90046001600160401b031690811061116757fe5b600091825260209091208c91600202016009600163ffffffff6117f616565b6040805188815260208101869052808201889052600160608201526000608082015290517f3d4a04291c66b06f39a4ecb817875b12b5485a05ec563133a56a905305c48e559181900360a00190a16111e68583600b63ffffffff611c4316565b1561129e576000848152600386016020908152604080832080546001600160401b03808c16600160401b0267ffffffffffffffff60401b199092169190911780835560019283015484518e81529586018b905290821685850152606085018c905216608084015260a0830184905260c0830184905260e083015261010082019290925290517f030c1c69405c93021f28f57557240dee939a320b826a1fd0d39bf6e629ecab47918190036101200190a161129e611e6e565b6004546001600160a01b031615611328576004805460408051633b253c2b60e11b815290516001600160a01b039092169263764a78569282820192602092908290030181600087803b1580156112f357600080fd5b505af1158015611307573d6000803e3d6000fd5b505050506040513d602081101561131d57600080fd5b505161132857600080fd5b5060019b9a5050505050505050505050565b60055481565b601481565b6009818154811061135257fe5b6000918252602091829020600691909102018054600180830154600280850154600386015460048701546005880180546040805161010099831615999099026000190190911695909504601f81018b90048b0288018b019095528487526001600160401b0388169a50600160401b880460ff9081169a600160481b8a0482169a600160501b8b0483169a600160581b810490931699600160601b9093046001600160801b0316986001600160a01b039081169897169690939183018282801561145c5780601f106114315761010080835404028352916020019161145c565b820191906000526020600020905b81548152906001019060200180831161143f57829003601f168201915b505050505090508b565b600e6020526000908152604090205481565b6003546001600160a01b031681565b600c818154811061149457fe5b60009182526020909120600290910201805460019091015460ff821692506001600160401b036101008304811692600160481b8104821692600160881b9091048216918116906001600160a01b03600160401b9091041686565b603c81565b60145481565b60115481565b600f6020526000908152604090205481565b6015602052600090815260409020546001600160a01b031681565b6002546001600160a01b031681565b6001546001600160a01b031681565b600b818154811061149457fe5b600a818154811061135257fe5b60125481565b600160801b8104916001600160801b0390911690565b8654869061159f90600160801b90046001600160401b03166001611f02565b146115a957600080fd5b60018781015483916115ca916001600160401b03169063ffffffff611f0216565b146115d457600080fd5b600086815260038801602052604090208054600160d01b900460ff16156115fa57600080fd5b8054600160d81b900460ff161561161057600080fd5b8054600160e01b900460ff161561162657600080fd5b80546001600160401b0316831461163c57600080fd5b8054600160401b90046001600160401b0316821461165957600080fd5b60038101959095556004850193909355506005830155600690910180546001600160401b0342811667ffffffffffffffff19928316179092558454938216600160801b0267ffffffffffffffff60801b199094169390931784556001939093018054919093169116179055565b600154604080516b707265706172654f5245282960a01b8152815190819003600c018120600482526024820183526020820180516001600160e01b03166001600160e01b0319909216919091178152915181516000946060946001600160a01b039091169392918291908083835b602083106117535780518252601f199092019160209182019101611734565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d80600081146117b3576040519150601f19603f3d011682016040523d82523d6000602084013e6117b8565b606091505b5091509150816117c757600080fd5b5050565b610e1090565b60008282016001600160401b0380851690821610156117ef57600080fd5b9392505050565b825460018401546001600160401b03600160881b9092048216911660008361182357828203600101611834565b855461010090046001600160401b03165b90506000811161184357600080fd5b60608160405190808252806020026020018201604052801561186f578160200160208202803883390190505b50905083805b8481116118f8578615806118ad575087818154811061189057fe5b6000918252602090912060069091020154600160401b900460ff16155b156118f0578781815481106118be57fe5b90600052602060002090600602016004015483878403815181106118de57fe5b60209081029190910101526001909101905b600101611875565b508861190383611f14565b1461190d57600080fd5b505050505050505050565b6001546040805173707265706172654f52454166746572555245282960601b81528151908190036014018120600482526024820183526020820180516001600160e01b03166001600160e01b0319909216919091178152915181516000946060946001600160a01b03909116939291829190808383602083106117535780518252601f199092019160209182019101611734565b86546001808901546001600160401b03600160801b9093048316926000926119dd929091169063ffffffff611f0216565b600083815260038b016020526040902080549192509060016001600160401b03600160401b90920482160116821415611a4e575088546001600160401b03600193909301928316600160801b0267ffffffffffffffff60801b19909116178955600082815260038a01602052604090205b80546001600160401b0316821015611a6557600080fd5b8380611a8257508054600160401b90046001600160401b03168211155b611a8b57600080fd5b805460ff600160d01b90910416151586151514611aa757600080fd5b805460ff600160d81b90910416151585151514611ac357600080fd5b600082815260048b810160205260409091208054600282018c9055600382018b905591810189905567ffffffffffffffff199091166001600160401b038581169190911767ffffffffffffffff60801b1916600160801b42929092169190910217815560058101805460ff1916881580159190911761ff0019166101008915150217909155611b8b5781546001830154825467ffffffffffffffff60401b1916600160401b6001600160401b03938416600160801b9093048416870192909203909216021781555b5050600198909801805467ffffffffffffffff19166001600160401b038a161790559795505050505050565b600154604080516b707265706172654e5245282960a01b8152815190819003600c018120600482526024820183526020820180516001600160e01b03166001600160e01b0319909216919091178152915181516000946060946001600160a01b03909116939291829190808383602083106117535780518252601f199092019160209182019101611734565b60028301546001600160401b03600160801b909104811660008181526004850160205260408120549092165b6000818152600386016020526040902054600160c81b900460ff1615611e62576000818152600386016020526040902054600160401b90046001600160401b03168210611cd65760020160008181526003860160205260409020546001600160401b031691505b5b6000818152600386016020526040902060010154600160c01b90046001600160401b0316158015611d1f57506000818152600386016020526040902054600160c81b900460ff165b15611d485760020160008181526003860160205260409020546001600160401b03169150611cd7565b6000818152600386016020526040902054600160c81b900460ff16611d72576001925050506117ef565b6000818152600386016020526040902054600160401b90046001600160401b03165b808311611dfe57600083815260048701602052604081205486548791600160401b90046001600160401b0316908110611dc957fe5b600091825260209091206002909102015461010090046001600160401b03161115611df357611dfe565b600183019250611d94565b80831115611e2b575060020160008181526003860160205260409020546001600160401b03169150611c6f565b50506002850180546001600160401b03909216600160801b0267ffffffffffffffff60801b199092169190911790555060006117ef565b50600195945050505050565b6001546040805173707265706172654e52454166746572555245282960601b81528151908190036014018120600482526024820183526020820180516001600160e01b03166001600160e01b0319909216919091178152915181516000946060946001600160a01b03909116939291829190808383602083106117535780518252601f199092019160209182019101611734565b6000828201838110156117ef57600080fd5b6000815160011415611f3c5781600081518110611f2d57fe5b602002602001015190506120ab565b60606002835160010181611f4c57fe5b04604051908082528060200260200182016040528015611f76578160200160208202803883390190505b50905060005b835181600101101561200957838181518110611f9457fe5b6020026020010151848260010181518110611fab57fe5b60200260200101516040516020018083815260200182815260200192505050604051602081830303815290604052805190602001208260028381611feb57fe5b0481518110611ff657fe5b6020908102919091010152600201611f7c565b600284518161201457fe5b066001141561209d578360018551038151811061202d57fe5b60200260200101518460018651038151811061204557fe5b6020026020010151604051602001808381526020018281526020019250505060405160208183030381529060405280519060200120826002838161208557fe5b048151811061209057fe5b6020026020010181815250505b6120a682611f14565b925050505b91905056fea265627a7a723158205d858117d36f538e918004091ae6e1ea36aa0e6cbeb8d335f0054124d395284e64736f6c634300050c0032
Deployed Bytecode Sourcemap
51620:6157:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40937:41;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40937:41:0;;;:::i;:::-;;;;;;;;;;;;;;;;41219:40;;8:9:-1;5:2;;;30:1;27;20:12;5:2;41219:40:0;;;:::i;51967:852::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;51967:852:0;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;40242:33;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40242:33:0;;;:::i;39467:23::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39467:23:0;;;:::i;39956:26::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39956:26:0;;;:::i;40391:27::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40391:27:0;;;:::i;39601:40::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39601:40:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;39601:40:0;;:::i;:::-;;;;-1:-1:-1;;;;;39601:40:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38992:23;;8:9:-1;5:2;;;30:1;27;20:12;5:2;38992:23:0;;;:::i;:::-;;;;-1:-1:-1;;;;;38992:23:0;;;;;;;;;;;;;;55828:1946;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;55828:1946:0;;;;;;;;;;;;;;;;;:::i;39115:26::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39115:26:0;;;:::i;39544:50::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39544:50:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;39544:50:0;;:::i;38952:23::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;38952:23:0;;;:::i;41345:33::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;41345:33:0;;;:::i;42347:36::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;42347:36:0;;;:::i;42299:41::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;42299:41:0;;;:::i;52825:2997::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;52825:2997:0;;;;;;;;;;;;;;;;;:::i;39411:21::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39411:21:0;;;:::i;41282:40::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;41282:40:0;;;:::i;39690:26::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39690:26:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;39690:26:0;;:::i;:::-;;;;-1:-1:-1;;;;;39690:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;39690:26:0;;;;;;-1:-1:-1;;;;;39690:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;39690:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40041:53;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40041:53:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;40041:53:0;;:::i;39085:25::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39085:25:0;;;:::i;39881:31::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39881:31:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;39881:31:0;;:::i;:::-;;;;;;;;;-1:-1:-1;;;;;39881:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;39881:31:0;;;;;;;;;;;;;;;;41097:41;;8:9:-1;5:2;;;30:1;27;20:12;5:2;41097:41:0;;;:::i;40423:27::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40423:27:0;;;:::i;40280:34::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40280:34:0;;;:::i;40154:54::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40154:54:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;40154:54:0;;:::i;40635:56::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40635:56:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;40635:56:0;-1:-1:-1;;;;;40635:56:0;;:::i;40726:81::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40726:81:0;;;:::i;39052:28::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39052:28:0;;;:::i;39020:27::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39020:27:0;;;:::i;39845:31::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39845:31:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;39845:31:0;;:::i;39721:26::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39721:26:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;39721:26:0;;:::i;40319:34::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40319:34:0;;;:::i;40937:41::-;40977:1;40937:41;:::o;41219:40::-;41257:2;41219:40;:::o;51967:852::-;52229:12;52254:15;52271:16;52291:17;:5;:15;:17::i;:::-;52253:55;;;;52338:10;52323:11;;:25;52315:63;;;;;-1:-1:-1;;;52315:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;52388:21;52411:19;52434:17;:5;:15;:17::i;:::-;52460;;;;:5;:17;;;;;52387:64;;-1:-1:-1;52387:64:0;-1:-1:-1;52460:184:0;;52496:11;52516:15;52540:22;52571:18;52387:64;;52460:184;:27;:184;:::i;:::-;52653:21;:19;:21::i;:::-;52695:11;;-1:-1:-1;;;;;52695:11:0;52687:34;52683:111;;52753:11;;;52740:45;;;-1:-1:-1;;;52740:45:0;;;;-1:-1:-1;;;;;52753:11:0;;;;52740:43;;:45;;;;;;;;;;;;52753:11;;52740:45;;;5:2:-1;;;;30:1;27;20:12;5:2;52740:45:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;52740:45:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;52740:45:0;52732:54;;;;;;-1:-1:-1;52809:4:0;;51967:852;-1:-1:-1;;;;;;;;;51967:852:0:o;40242:33::-;;;;:::o;39467:23::-;;;;:::o;39956:26::-;;;;:::o;40391:27::-;;;;:::o;39601:40::-;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;39601:40:0;;;;-1:-1:-1;;;39601:40:0;;;;;;-1:-1:-1;;;39601:40:0;;;;;;-1:-1:-1;;;39601:40:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;38992:23::-;;;;;;-1:-1:-1;;;;;38992:23:0;;:::o;55828:1946::-;55993:12;56017:15;56039:16;56092;:4;:14;:16::i;:::-;56135:11;;56064:44;;-1:-1:-1;56064:44:0;-1:-1:-1;56149:1:0;56135:15;:29;;;;56179:37;;;56206:10;56191:11;;:25;56179:37;56171:46;;;;;;56226:22;56251:17;;;:5;:17;;;;;56277:406;;;;-1:-1:-1;56300:11:0;:24;;;56340:17;;;;:5;:17;;;;;56414:15;56393:18;:16;:18::i;:::-;56376:14;;;;-1:-1:-1;;;56376:14:0;;-1:-1:-1;;;;;56376:14:0;:35;:53;56368:62;;;;;;56493:15;;-1:-1:-1;;;56493:15:0;;-1:-1:-1;;;;;56493:15:0;56478:30;;56470:39;;;;;;56544:14;;56525:51;;;;;;-1:-1:-1;;;;;;;;56544:14:0;;;;56525:51;;;;-1:-1:-1;;;56560:15:0;;;;;;56525:51;;;;;;;;;;;;;;56277:406;;;56672:1;56651:14;;;;:23;;-1:-1:-1;;;;;56651:14:0;;;;:23;:20;:23;:::i;:::-;-1:-1:-1;;;;;56636:38:0;:11;:38;56628:47;;;;;;56730:14;;-1:-1:-1;;;56730:14:0;;-1:-1:-1;;;;;56730:14:0;56691:24;56718:27;;;:11;;;:27;;;;;56762:15;;-1:-1:-1;;;56762:15:0;;;;56754:24;;;;;;56793:19;;-1:-1:-1;;;56793:19:0;;;;56785:28;;;;;;56822:26;56851:24;;;:11;;;;:24;;;;;56900:14;;56884:30;;56921:12;;;:26;;;56954:18;;;:38;;;56999:14;;;:30;;;-1:-1:-1;;;56900:14:0;;;;-1:-1:-1;;;;;56900:14:0;;;-1:-1:-1;;56884:30:0;;;;-1:-1:-1;;;;57036:37:0;57057:15;57036:37;;;;;;;;;;;;57080:11;;;:18;;56900:14;-1:-1:-1;;57080:18:0;;;-1:-1:-1;57080:18:0;;;-1:-1:-1;;57105:22:0;;;;;;;;57136:14;;:36;;;;;;;;;;;;57186:11;;57080:18;57186:11;57181:164;;57266:14;;;;-1:-1:-1;;;;;57266:14:0;;;57254:27;;;;:11;;;:27;;;;;:42;57249:4;:48;;57208:129;;57249:4;;-1:-1:-1;;;57254:42:0;;;;;;57249:48;;;;;;;;;;;;;57208:17;;57249:48;;;;;;57308:4;;57208:129;:30;:129;:::i;:::-;57400:14;;57358:109;;;;;;-1:-1:-1;;;57400:14:0;;;-1:-1:-1;;;;;57400:14:0;57358:109;;;;;;;;;;57443:4;57358:109;;;;;;;;;;;;;;;;;;;;;57562:20;;-1:-1:-1;;;57562:20:0;;-1:-1:-1;;;;;57562:20:0;57547:35;;57543:87;;;57593:29;:27;:29::i;:::-;57650:11;;-1:-1:-1;;;;;57650:11:0;57642:34;57638:111;;57708:11;;;57695:45;;;-1:-1:-1;;;57695:45:0;;;;-1:-1:-1;;;;;57708:11:0;;;;57695:43;;:45;;;;;;;;;;;;57708:11;;57695:45;;;5:2:-1;;;;30:1;27;20:12;5:2;57695:45:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;57695:45:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;57695:45:0;57687:54;;;;;;57764:4;57757:11;;;;;;;;55828:1946;;;;;;;:::o;39115:26::-;;;-1:-1:-1;;;;;39115:26:0;;:::o;39544:50::-;;;;;;;;;;;;;:::o;38952:23::-;;;;;;:::o;41345:33::-;41376:2;41345:33;:::o;42347:36::-;42379:4;42347:36;:::o;42299:41::-;42334:6;42299:41;:::o;52825:2997::-;52990:12;53014:15;53036:16;53089;:4;:14;:16::i;:::-;53122:11;;53061:44;;-1:-1:-1;53061:44:0;-1:-1:-1;53122:25:0;;53114:34;;;;;;53163:17;;;;:5;:17;;;;;:27;;;;;-1:-1:-1;;;;;53163:27:0;;;:31;;;:46;;;53155:55;;;;;;53219:25;53247:17;;;:5;:17;;;;;;53219:25;53369:15;;;:76;;-1:-1:-1;;;53394:14:0;;53388:21;;;;:5;:21;;;;;:33;-1:-1:-1;;;;;53388:33:0;:38;;;;:57;;-1:-1:-1;53430:15:0;;;;-1:-1:-1;;;53430:15:0;;;;53388:57;53365:1063;;;53485:149;:7;53515:11;53537:17;53565:13;53589:4;53604:5;;53485:149;:19;:149;:::i;:::-;53650:11;;53456:178;;-1:-1:-1;53456:178:0;;-1:-1:-1;53650:11:0;;53645:182;;53737:17;;;;-1:-1:-1;;;;;53737:17:0;;;53722:33;;;;:14;;;:33;;;;;:48;53717:4;:54;;53674:143;;53717:4;;-1:-1:-1;;;53722:48:0;;;;;;53717:54;;;;;;;;;;;;;53674:17;;53717:54;;;;;;53784:4;;53674:143;:30;:143;:::i;:::-;-1:-1:-1;53854:27:0;;;;:14;;;:27;;;;;:42;53994:4;:20;;-1:-1:-1;;;53854:42:0;;;-1:-1:-1;;;;;53854:42:0;;;;53994:20;;;;;;;;;;;;;;;;;;;;;;:29;53951:27;;;:14;;;:27;;;;;;53994:29;53951:30;;;:72;;-1:-1:-1;;;;;53951:72:0;;53994:29;;;;-1:-1:-1;;;;;53994:29:0;;;-1:-1:-1;;;53951:72:0;;;;;;;;;;;;;;;;54039:119;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54188:27;;;;:14;;;:27;;;;;:42;-1:-1:-1;;;54188:42:0;;-1:-1:-1;;;;;54188:42:0;54173:57;;54169:105;;;54243:21;:19;:21::i;:::-;54296:11;;-1:-1:-1;;;;;54296:11:0;54288:34;54284:115;;54356:11;;;54343:45;;;-1:-1:-1;;;54343:45:0;;;;-1:-1:-1;;;;;54356:11:0;;;;54343:43;;:45;;;;;;;;;;;;54356:11;;54343:45;;;5:2:-1;;;;30:1;27;20:12;5:2;54343:45:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;54343:45:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;54343:45:0;54335:54;;;;;;54416:4;54409:11;;;;;;;;;53365:1063;54518:134;:7;54546:11;54566:17;54592:13;54614:4;54627:5;54614:4;54518:134;:19;:134;:::i;:::-;-1:-1:-1;;54695:14:0;;54661:25;54689:21;;;:5;:21;;;;;;;;54753:27;;;:14;;;;:27;;;;;54815:25;;;;;54708:1;54789:23;;:51;;-1:-1:-1;;54789:51:0;-1:-1:-1;;;;;;;;54815:25:0;;;;;;54789:51;;;;;;;54888:25;;;;;54873:41;;:14;;;:41;;;;;;:56;54847:82;;-1:-1:-1;;;54873:56:0;;;;;;;54847:82;-1:-1:-1;;;;54847:82:0;;;;;;;;;54943:11;;54489:163;;-1:-1:-1;54489:163:0;;-1:-1:-1;54689:21:0;54753:27;54943:11;;54938:144;;55011:23;;55006:4;:29;;54965:109;;-1:-1:-1;;;55011:23:0;;-1:-1:-1;;;;;55011:23:0;;55006:29;;;;;;;;;;;;;;54965:17;;55006:29;;;55046:4;55061;54965:109;:30;:109;:::i;:::-;55095:107;;;;;;;;;;;;;;;;;;55177:4;55095:107;;;;55190:5;55095:107;;;;;;;;;;;;;;;55242:43;:7;55271;55280:4;55242:43;:28;:43;:::i;:::-;55238:440;;;55296:27;;;;:14;;;:27;;;;;;;;:64;;-1:-1:-1;;;;;55296:64:0;;;-1:-1:-1;;;55296:64:0;-1:-1:-1;;;;55296:64:0;;;;;;;;;;-1:-1:-1;55519:30:0;;;:43;55376:254;;;;;;;;;;;55442:44;;;55376:254;;;;;;;;;;55519:43;55376:254;;;;;;;;;;;;;;;;;;;;55296:64;55376:254;;;;;;;;;;;;;;;;;55641:29;:27;:29::i;:::-;55698:11;;-1:-1:-1;;;;;55698:11:0;55690:34;55686:111;;55756:11;;;55743:45;;;-1:-1:-1;;;55743:45:0;;;;-1:-1:-1;;;;;55756:11:0;;;;55743:43;;:45;;;;;;;;;;;;55756:11;;55743:45;;;5:2:-1;;;;30:1;27;20:12;5:2;55743:45:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;55743:45:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;55743:45:0;55735:54;;;;;;-1:-1:-1;55812:4:0;;52825:2997;-1:-1:-1;;;;;;;;;;;52825:2997:0:o;39411:21::-;;;;:::o;41282:40::-;41320:2;41282:40;:::o;39690:26::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;39690:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;39690:26:0;;;-1:-1:-1;;;;39690:26:0;;;;;;;-1:-1:-1;;;39690:26:0;;;;;-1:-1:-1;;;39690:26:0;;;;;-1:-1:-1;;;39690:26:0;;;;;;-1:-1:-1;;;39690:26:0;;;-1:-1:-1;;;;;39690:26:0;;-1:-1:-1;;;;;39690:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;40041:53::-;;;;;;;;;;;;;:::o;39085:25::-;;;-1:-1:-1;;;;;39085:25:0;;:::o;39881:31::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;39881:31:0;;;;;;-1:-1:-1;;;39881:31:0;;;;;-1:-1:-1;;;39881:31:0;;;;;;;;;-1:-1:-1;;;;;;;;39881:31:0;;;;;:::o;41097:41::-;41136:2;41097:41;:::o;40423:27::-;;;;:::o;40280:34::-;;;;:::o;40154:54::-;;;;;;;;;;;;;:::o;40635:56::-;;;;;;;;;;;;-1:-1:-1;;;;;40635:56:0;;:::o;39052:28::-;;;-1:-1:-1;;;;;39052:28:0;;:::o;39020:27::-;;;-1:-1:-1;;;;;39020:27:0;;:::o;39845:31::-;;;;;;;;;;39721:26;;;;;;;;;;40319:34;;;;:::o;18520:180::-;-1:-1:-1;;;18622:22:0;;;-1:-1:-1;;;;;18658:30:0;;;;18607:88::o;21618:942::-;21876:12;;21899;;21876:19;;-1:-1:-1;;;21876:12:0;;-1:-1:-1;;;;;21876:12:0;21893:1;21876:16;:19::i;:::-;:35;21868:44;;;;;;21944:1;21927:12;;;;21950:17;;21927:19;;-1:-1:-1;;;;;21927:12:0;;:19;:16;:19;:::i;:::-;:40;21919:49;;;;;;21977:24;22004:23;;;:9;;;:23;;;;;22045:15;;-1:-1:-1;;;22045:15:0;;;;22044:16;22036:25;;;;;;22077:19;;-1:-1:-1;;;22077:19:0;;;;22076:20;22068:29;;;;;;22113:12;;-1:-1:-1;;;22113:12:0;;;;22112:13;22104:22;;;;;;22143;;-1:-1:-1;;;;;22143:22:0;:43;;22135:52;;;;;;22202:20;;-1:-1:-1;;;22202:20:0;;-1:-1:-1;;;;;22202:20:0;:39;;22194:48;;;;;;22251:9;;;:42;;;;22300:31;;;:56;;;;-1:-1:-1;22363:27:0;;;:48;22418:21;;;;:47;;-1:-1:-1;;;;;22449:15:0;22418:47;;-1:-1:-1;;22418:47:0;;;;;;;22474:35;;;;;-1:-1:-1;;;22474:35:0;-1:-1:-1;;;;22474:35:0;;;;;;;;;22300:31;22516:12;;;;:38;;;;;;;;;;;21618:942::o;46037:281::-;46212:12;;45214:25;;;-1:-1:-1;;;45214:25:0;;;;;;;;;;;;22:32:-1;6:49;;46238:50:0;;;;;49:4:-1;25:18;;61:17;;-1:-1;;;;;182:15;-1:-1;;;;;;46238:50:0;;;179:29:-1;;;;160:49;;46212:77:0;;;;46171:12;;46185:23;;-1:-1:-1;;;;;46212:12:0;;;;45214:25;46212:77;;;25:18:-1;46212:77:0;;25:18:-1;36:153;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;46212:77:0;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;46170:119:0;;;;46304:7;46296:16;;;;;;46037:281;;:::o;18435:79::-;18501:7;18435:79;:::o;2922:134::-;2980:6;3006:5;;;-1:-1:-1;;;;;3026:6:0;;;;;;;;3018:15;;;;;;3049:1;2922:134;-1:-1:-1;;;2922:134:0:o;36807:810::-;36971:16;;37003:14;;;;-1:-1:-1;;;;;;;;36971:16:0;;;;;;37003:14;36962:6;37033:9;:36;;37064:1;37060;:5;37068:1;37060:9;37033:36;;;37045:12;;;;;-1:-1:-1;;;;;37045:12:0;37033:36;37024:45;;37090:1;37086;:5;37078:14;;;;;;37101:23;37141:1;37127:16;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;37127:16:0;-1:-1:-1;37101:42:0;-1:-1:-1;37198:1:0;;37206:142;37228:1;37223;:6;37206:142;;37250:9;37249:10;:28;;;;37264:3;37268:1;37264:6;;;;;;;;;;;;;;;;;;;;;:13;-1:-1:-1;;;37264:13:0;;;;37263:14;37249:28;37245:96;;;37306:3;37310:1;37306:6;;;;;;;;;;;;;;;;;;:11;;;37290:6;37301:1;37297;:5;37290:13;;;;;;;;;;;;;;;;;:27;37328:3;;;;;37245:96;37231:3;;37206:142;;;;37384:17;37364:16;:6;:14;:16::i;:::-;:37;37356:46;;;;;;36807:810;;;;;;;;;:::o;47260:288::-;47443:12;;45470:33;;;-1:-1:-1;;;45470:33:0;;;;;;;;;;;;22:32:-1;6:49;;47469::0;;;;;49:4:-1;25:18;;61:17;;-1:-1;;;;;182:15;-1:-1;;;;;;47469:49:0;;;179:29:-1;;;;160:49;;47443:76:0;;;;47402:12;;47416:23;;-1:-1:-1;;;;;47443:12:0;;;;45470:33;47443:76;;;25:18:-1;47443:76:0;;25:18:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;20146:1341:0;20435:12;;20485:1;20468:12;;;;-1:-1:-1;;;;;;;;20435:12:0;;;;;;20375:16;;20468:19;;:12;;;;:19;:16;:19;:::i;:::-;20496:24;20523:22;;;:9;;;:22;;;;;20573:20;;20454:33;;-1:-1:-1;20523:22:0;20596:1;-1:-1:-1;;;;;;;;20573:20:0;;;;;:24;20558:39;;;20554:160;;;-1:-1:-1;20633:34:0;;-1:-1:-1;;;;;20623:1:0;20608:16;;;;20633:34;;;-1:-1:-1;;;20633:34:0;-1:-1:-1;;;;20633:34:0;;;;;;:12;20684:22;;;:9;;;:22;;;;;20554:160;20730:22;;-1:-1:-1;;;;;20730:22:0;:37;-1:-1:-1;20730:37:0;20722:46;;;;;;20783:7;:46;;;-1:-1:-1;20794:20:0;;-1:-1:-1;;;20794:20:0;;-1:-1:-1;;;;;20794:20:0;-1:-1:-1;;20794:35:0;20783:46;20775:55;;;;;;20847:15;;;-1:-1:-1;;;20847:15:0;;;;:29;;;;;;20839:38;;;;;;20892:19;;;-1:-1:-1;;;20892:19:0;;;;:37;;;;;;20884:46;;;;;;20939:26;20968:22;;;:9;;;;:22;;;;;;20999:35;;21041:12;;;:26;;;21074:18;;;:38;;;21119:14;;;:30;;;-1:-1:-1;;20999:35:0;;;-1:-1:-1;;;;;20999:35:0;;;;;;;-1:-1:-1;;;;21156:37:0;-1:-1:-1;;;21177:15:0;21156:37;;;;;;;;;;;21200:11;;;:24;;-1:-1:-1;;21200:24:0;;;;;;;;;-1:-1:-1;;21231:32:0;20999:35;21231:32;;;;;;;;21272:127;;21368:22;;;21323:8;;:28;21297:94;;-1:-1:-1;;;;21297:94:0;-1:-1:-1;;;;;;;;21368:22:0;;;-1:-1:-1;;;21323:28:0;;;;;:42;;:67;;;;21297:94;;;;;;;21272:127;-1:-1:-1;;21407:12:0;;;;;:34;;-1:-1:-1;;21407:34:0;-1:-1:-1;;;;;21407:34:0;;;;;20146:1341;;-1:-1:-1;;;;;;20146:1341:0:o;46356:410::-;46531:12;;45297:25;;;-1:-1:-1;;;45297:25:0;;;;;;;;;;;;22:32:-1;6:49;;46557:50:0;;;;;49:4:-1;25:18;;61:17;;-1:-1;;;;;182:15;-1:-1;;;;;;46557:50:0;;;179:29:-1;;;;160:49;;46531:77:0;;;;46490:12;;46504:23;;-1:-1:-1;;;;;46531:12:0;;;;45297:25;46531:77;;;25:18:-1;46531:77:0;;25:18:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;23200:1695:0;23376:22;;;;-1:-1:-1;;;;;;;;23376:22:0;;;;;23335:13;23424:35;;;:11;;;:35;;;;;:47;23335:13;;23424:47;23543:1298;23550:24;;;;:11;;;:24;;;;;:36;-1:-1:-1;;;23550:36:0;;;;23543:1298;;;23631:24;;;;:11;;;:24;;;;;:39;-1:-1:-1;;;23631:39:0;;-1:-1:-1;;;;;23631:39:0;-1:-1:-1;;23627:163:0;;23713:1;23698:16;23739:24;;;;:11;;;:24;;;;;:41;-1:-1:-1;;;;;23739:41:0;;-1:-1:-1;23627:163:0;23845:193;23852:24;;;;:11;;;:24;;;;;:27;;:36;-1:-1:-1;;;23852:36:0;;-1:-1:-1;;;;;23852:36:0;:41;:81;;;;-1:-1:-1;23897:24:0;;;;:11;;;:24;;;;;:36;-1:-1:-1;;;23897:36:0;;;;23852:81;23845:193;;;23961:1;23946:16;23987:24;;;;:11;;;:24;;;;;:41;-1:-1:-1;;;;;23987:41:0;;-1:-1:-1;23845:193:0;;;24115:24;;;;:11;;;:24;;;;;:36;-1:-1:-1;;;24115:36:0;;;;24110:75;;24171:4;24164:11;;;;;;24110:75;24239:19;24261:24;;;:11;;;:24;;;;;:39;-1:-1:-1;;;24261:39:0;;-1:-1:-1;;;;;24261:39:0;24309:179;24331:14;24316:11;:29;24309:179;;24419:1;24367:24;;;:11;;;:24;;;;;:39;24362:45;;;;-1:-1:-1;;;24367:39:0;;-1:-1:-1;;;;;24367:39:0;;24362:45;;;;;;;;;;;;;;;;;;;:54;;;;-1:-1:-1;;;;;24362:54:0;:58;24358:94;;;24435:5;;24358:94;24477:1;24462:16;;;;24309:179;;;24581:14;24567:11;:28;24563:156;;;-1:-1:-1;24623:1:0;24608:16;24649:24;;;;:11;;;:24;;;;;:41;-1:-1:-1;;;;;24649:41:0;;-1:-1:-1;24701:8:0;;24563:156;-1:-1:-1;;24768:22:0;;;:44;;-1:-1:-1;;;;;24768:44:0;;;-1:-1:-1;;;24768:44:0;-1:-1:-1;;;;24768:44:0;;;;;;;;;-1:-1:-1;;24821:12:0;;23543:1298;-1:-1:-1;24885:4:0;;23200:1695;-1:-1:-1;;;;;23200:1695:0:o;47586:288::-;47769:12;;45560:33;;;-1:-1:-1;;;45560:33:0;;;;;;;;;;;;22:32:-1;6:49;;47795::0;;;;;49:4:-1;25:18;;61:17;;-1:-1;;;;;182:15;-1:-1;;;;;;47795:49:0;;;179:29:-1;;;;160:49;;47769:76:0;;;;47728:12;;47742:23;;-1:-1:-1;;;;;47769:12:0;;;;45560:33;47769:76;;;25:18:-1;47769:76:0;;25:18:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;1360:136:0;1418:7;1446:5;;;1466:6;;;;1458:15;;;;;15564:556;15643:7;15666:5;:12;15682:1;15666:17;15662:38;;;15692:5;15698:1;15692:8;;;;;;;;;;;;;;15685:15;;;;15662:38;15709:26;15773:1;15753:5;:12;15768:1;15753:16;15752:22;;;;;;15738:37;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;15738:37:0;;15709:66;;15782:6;15797:120;15812:5;:12;15804:1;15808;15804:5;:20;15797:120;;;15887:5;15893:1;15887:8;;;;;;;;;;;;;;15897:5;15903:1;15905;15903:3;15897:10;;;;;;;;;;;;;;15870:38;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;15870:38:0;;;15860:49;;;;;;15843:9;15855:1;15853;:3;;;;;;15843:14;;;;;;;;;;;;;;;;;:66;15831:1;15826:6;15797:120;;;15944:1;15929:5;:12;:16;;;;;;15949:1;15929:21;15925:156;;;16015:5;16036:1;16021:5;:12;:16;16015:23;;;;;;;;;;;;;;16040:5;16061:1;16046:5;:12;:16;16040:23;;;;;;;;;;;;;;15998:66;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;15998:66:0;;;15978:95;;;;;;15961:9;15973:1;15971;:3;;;;;;15961:14;;;;;;;;;;;;;:112;;;;;15925:156;16096:18;16104:9;16096:7;:18::i;:::-;16089:25;;;;15564:556;;;;:::o
Swarm Source
bzzr://5d858117d36f538e918004091ae6e1ea36aa0e6cbeb8d335f0054124d395284e
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
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.