Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 25,439 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Append Sequencer... | 14570883 | 956 days ago | IN | 0 ETH | 0.02144132 | ||||
Append Sequencer... | 14570867 | 956 days ago | IN | 0 ETH | 0.02103196 | ||||
Append Sequencer... | 14570839 | 956 days ago | IN | 0 ETH | 0.02418291 | ||||
Append Sequencer... | 14570828 | 956 days ago | IN | 0 ETH | 0.01639289 | ||||
Append Sequencer... | 14570762 | 956 days ago | IN | 0 ETH | 0.01903475 | ||||
Append Sequencer... | 14570726 | 956 days ago | IN | 0 ETH | 0.01591192 | ||||
Append Sequencer... | 14570694 | 956 days ago | IN | 0 ETH | 0.01609296 | ||||
Append Sequencer... | 14570667 | 956 days ago | IN | 0 ETH | 0.02045079 | ||||
Append Sequencer... | 14570598 | 956 days ago | IN | 0 ETH | 0.02325122 | ||||
Append Sequencer... | 14570595 | 956 days ago | IN | 0 ETH | 0.01751114 | ||||
Append Sequencer... | 14570471 | 956 days ago | IN | 0 ETH | 0.01677669 | ||||
Append Sequencer... | 14570462 | 956 days ago | IN | 0 ETH | 0.01654189 | ||||
Append Sequencer... | 14570455 | 956 days ago | IN | 0 ETH | 0.01311135 | ||||
Append Sequencer... | 14570447 | 956 days ago | IN | 0 ETH | 0.02556756 | ||||
Append Sequencer... | 14570442 | 956 days ago | IN | 0 ETH | 0.01742228 | ||||
Append Sequencer... | 14570394 | 956 days ago | IN | 0 ETH | 0.0123324 | ||||
Append Sequencer... | 14570342 | 956 days ago | IN | 0 ETH | 0.00947062 | ||||
Append Sequencer... | 14570306 | 956 days ago | IN | 0 ETH | 0.01231929 | ||||
Append Sequencer... | 14570265 | 956 days ago | IN | 0 ETH | 0.01323357 | ||||
Append Sequencer... | 14570205 | 956 days ago | IN | 0 ETH | 0.0109135 | ||||
Append Sequencer... | 14570132 | 956 days ago | IN | 0 ETH | 0.01453872 | ||||
Append Sequencer... | 14570100 | 956 days ago | IN | 0 ETH | 0.01297923 | ||||
Append Sequencer... | 14570053 | 956 days ago | IN | 0 ETH | 0.01372544 | ||||
Append Sequencer... | 14570019 | 956 days ago | IN | 0 ETH | 0.01367344 | ||||
Append Sequencer... | 14570006 | 956 days ago | IN | 0 ETH | 0.01599377 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
CanonicalTransactionChain
Compiler Version
v0.8.9+commit.e5eed63a
Optimization Enabled:
Yes with 10000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; /* Library Imports */ import { AddressAliasHelper } from "../../standards/AddressAliasHelper.sol"; import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol"; import { Lib_AddressResolver } from "../../libraries/resolver/Lib_AddressResolver.sol"; /* Interface Imports */ import { ICanonicalTransactionChain } from "./ICanonicalTransactionChain.sol"; import { IChainStorageContainer } from "./IChainStorageContainer.sol"; /** * @title CanonicalTransactionChain * @dev The Canonical Transaction Chain (CTC) contract is an append-only log of transactions * which must be applied to the rollup state. It defines the ordering of rollup transactions by * writing them to the 'CTC:batches' instance of the Chain Storage Container. * The CTC also allows any account to 'enqueue' an L2 transaction, which will require that the * Sequencer will eventually append it to the rollup state. * * Runtime target: EVM */ contract CanonicalTransactionChain is ICanonicalTransactionChain, Lib_AddressResolver { /************* * Constants * *************/ // L2 tx gas-related uint256 public constant MIN_ROLLUP_TX_GAS = 100000; uint256 public constant MAX_ROLLUP_TX_SIZE = 50000; // The approximate cost of calling the enqueue function uint256 public enqueueGasCost; // The ratio of the cost of L1 gas to the cost of L2 gas uint256 public l2GasDiscountDivisor; // The amount of L2 gas which can be forwarded to L2 without spam prevention via 'gas burn'. // Calculated as the product of l2GasDiscountDivisor * enqueueGasCost. // See comments in enqueue() for further detail. uint256 public enqueueL2GasPrepaid; //default l2 chain id uint256 constant public DEFAULT_CHAINID = 1088; // Encoding-related (all in bytes) uint256 internal constant BATCH_CONTEXT_SIZE = 16; uint256 internal constant BATCH_CONTEXT_LENGTH_POS = 12; uint256 internal constant BATCH_CONTEXT_START_POS = 15; uint256 internal constant TX_DATA_HEADER_SIZE = 3; uint256 internal constant BYTES_TILL_TX_DATA = 65; /************* * Variables * *************/ uint256 public maxTransactionGasLimit; /*************** * Queue State * ***************/ mapping(uint256=>uint40) private _nextQueueIndex; // index of the first queue element not yet included mapping(uint256=>Lib_OVMCodec.QueueElement[]) queueElements; /*************** * Constructor * ***************/ constructor( address _libAddressManager, uint256 _maxTransactionGasLimit, uint256 _l2GasDiscountDivisor, uint256 _enqueueGasCost ) Lib_AddressResolver(_libAddressManager) { maxTransactionGasLimit = _maxTransactionGasLimit; l2GasDiscountDivisor = _l2GasDiscountDivisor; enqueueGasCost = _enqueueGasCost; enqueueL2GasPrepaid = _l2GasDiscountDivisor * _enqueueGasCost; } /********************** * Function Modifiers * **********************/ /** * Modifier to enforce that, if configured, only the Burn Admin may * successfully call a method. */ modifier onlyBurnAdmin() { require(msg.sender == libAddressManager.owner(), "Only callable by the Burn Admin."); _; } /******************************* * Authorized Setter Functions * *******************************/ /** * Allows the Burn Admin to update the parameters which determine the amount of gas to burn. * The value of enqueueL2GasPrepaid is immediately updated as well. */ function setGasParams(uint256 _l2GasDiscountDivisor, uint256 _enqueueGasCost) external onlyBurnAdmin { enqueueGasCost = _enqueueGasCost; l2GasDiscountDivisor = _l2GasDiscountDivisor; // See the comment in enqueue() for the rationale behind this formula. enqueueL2GasPrepaid = _l2GasDiscountDivisor * _enqueueGasCost; emit L2GasParamsUpdated(l2GasDiscountDivisor, enqueueGasCost, enqueueL2GasPrepaid); } /******************** * Public Functions * ********************/ /** * Accesses the batch storage container. * @return Reference to the batch storage container. */ function batches() public view returns (IChainStorageContainer) { return IChainStorageContainer(resolve("ChainStorageContainer-CTC-batches")); } /** * Accesses the queue storage container. * @return Reference to the queue storage container. */ function queue() public view returns (IChainStorageContainer) { return IChainStorageContainer(resolve("ChainStorageContainer-CTC-queue")); } /** * Retrieves the total number of elements submitted. * @return _totalElements Total submitted elements. */ function getTotalElements() public view returns (uint256 _totalElements) { (uint40 totalElements, , , ) = _getBatchExtraData(); return uint256(totalElements); } /** * Retrieves the total number of batches submitted. * @return _totalBatches Total submitted batches. */ function getTotalBatches() public view returns (uint256 _totalBatches) { return batches().length(); } /** * Returns the index of the next element to be enqueued. * @return Index for the next queue element. */ function getNextQueueIndex() public view returns (uint40) { return _nextQueueIndex[DEFAULT_CHAINID]; } /** * Returns the timestamp of the last transaction. * @return Timestamp for the last transaction. */ function getLastTimestamp() public view returns (uint40) { (, , uint40 lastTimestamp, ) = _getBatchExtraData(); return lastTimestamp; } /** * Returns the blocknumber of the last transaction. * @return Blocknumber for the last transaction. */ function getLastBlockNumber() public view returns (uint40) { (, , , uint40 lastBlockNumber) = _getBatchExtraData(); return lastBlockNumber; } /** * Gets the queue element at a particular index. * @param _index Index of the queue element to access. * @return _element Queue element at the given index. */ function getQueueElement(uint256 _index) public view returns (Lib_OVMCodec.QueueElement memory _element) { return queueElements[DEFAULT_CHAINID][_index]; } /** * Get the number of queue elements which have not yet been included. * @return Number of pending queue elements. */ function getNumPendingQueueElements() public view returns (uint40) { return uint40(queueElements[DEFAULT_CHAINID].length) - _nextQueueIndex[DEFAULT_CHAINID]; } /** * Retrieves the length of the queue, including * both pending and canonical transactions. * @return Length of the queue. */ function getQueueLength() public view returns (uint40) { return uint40(queueElements[DEFAULT_CHAINID].length); } /** * Adds a transaction to the queue. * @param _target Target L2 contract to send the transaction to. * @param _gasLimit Gas limit for the enqueued L2 transaction. * @param _data Transaction data. */ function enqueue( address _target, uint256 _gasLimit, bytes memory _data ) external { enqueueByChainId(DEFAULT_CHAINID, _target, _gasLimit, _data); } /** * Allows the sequencer to append a batch of transactions. * @dev This function uses a custom encoding scheme for efficiency reasons. * .param _shouldStartAtElement Specific batch we expect to start appending to. * .param _totalElementsToAppend Total number of batch elements we expect to append. * .param _contexts Array of batch contexts. * .param _transactionDataFields Array of raw transaction data. */ function appendSequencerBatch() external { uint40 shouldStartAtElement; uint24 totalElementsToAppend; uint24 numContexts; assembly { shouldStartAtElement := shr(216, calldataload(4)) totalElementsToAppend := shr(232, calldataload(9)) numContexts := shr(232, calldataload(12)) } require( shouldStartAtElement == getTotalElements(), "Actual batch start index does not match expected start index." ); require( msg.sender == resolve("OVM_Sequencer"), "Function can only be called by the Sequencer." ); uint40 nextTransactionPtr = uint40( BATCH_CONTEXT_START_POS + BATCH_CONTEXT_SIZE * numContexts ); require(msg.data.length >= nextTransactionPtr, "Not enough BatchContexts provided."); // Counter for number of sequencer transactions appended so far. uint32 numSequencerTransactions = 0; // Cache the _nextQueueIndex storage variable to a temporary stack variable. // This is safe as long as nothing reads or writes to the storage variable // until it is updated by the temp variable. uint40 nextQueueIndex = _nextQueueIndex[DEFAULT_CHAINID]; BatchContext memory curContext; for (uint32 i = 0; i < numContexts; i++) { BatchContext memory nextContext = _getBatchContext(i); // Now we can update our current context. curContext = nextContext; // Process sequencer transactions first. numSequencerTransactions += uint32(curContext.numSequencedTransactions); // Now process any subsequent queue transactions. nextQueueIndex += uint40(curContext.numSubsequentQueueTransactions); } require( nextQueueIndex <= queueElements[DEFAULT_CHAINID].length, "Attempted to append more elements than are available in the queue." ); // Generate the required metadata that we need to append this batch uint40 numQueuedTransactions = totalElementsToAppend - numSequencerTransactions; uint40 blockTimestamp; uint40 blockNumber; if (curContext.numSubsequentQueueTransactions == 0) { // The last element is a sequencer tx, therefore pull timestamp and block number from // the last context. blockTimestamp = uint40(curContext.timestamp); blockNumber = uint40(curContext.blockNumber); } else { // The last element is a queue tx, therefore pull timestamp and block number from the // queue element. // curContext.numSubsequentQueueTransactions > 0 which means that we've processed at // least one queue element. We increment nextQueueIndex after processing each queue // element, so the index of the last element we processed is nextQueueIndex - 1. Lib_OVMCodec.QueueElement memory lastElement = queueElements[DEFAULT_CHAINID][nextQueueIndex - 1]; blockTimestamp = lastElement.timestamp; blockNumber = lastElement.blockNumber; } // Cache the previous blockhash to ensure all transaction data can be retrieved efficiently. _appendBatch( blockhash(block.number - 1), totalElementsToAppend, numQueuedTransactions, blockTimestamp, blockNumber ); emit SequencerBatchAppended( nextQueueIndex - numQueuedTransactions, numQueuedTransactions, getTotalElements(), DEFAULT_CHAINID ); // Update the _nextQueueIndex storage variable. _nextQueueIndex[DEFAULT_CHAINID] = nextQueueIndex; } /********************** * Internal Functions * **********************/ /** * Returns the BatchContext located at a particular index. * @param _index The index of the BatchContext * @return The BatchContext at the specified index. */ function _getBatchContext(uint256 _index) internal pure returns (BatchContext memory) { uint256 contextPtr = 15 + _index * BATCH_CONTEXT_SIZE; uint256 numSequencedTransactions; uint256 numSubsequentQueueTransactions; uint256 ctxTimestamp; uint256 ctxBlockNumber; assembly { numSequencedTransactions := shr(232, calldataload(contextPtr)) numSubsequentQueueTransactions := shr(232, calldataload(add(contextPtr, 3))) ctxTimestamp := shr(216, calldataload(add(contextPtr, 6))) ctxBlockNumber := shr(216, calldataload(add(contextPtr, 11))) } return BatchContext({ numSequencedTransactions: numSequencedTransactions, numSubsequentQueueTransactions: numSubsequentQueueTransactions, timestamp: ctxTimestamp, blockNumber: ctxBlockNumber }); } /** * Parses the batch context from the extra data. * @return Total number of elements submitted. * @return Index of the next queue element. */ function _getBatchExtraData() internal view returns ( uint40, uint40, uint40, uint40 ) { bytes27 extraData = batches().getGlobalMetadata(); uint40 totalElements; uint40 nextQueueIndex; uint40 lastTimestamp; uint40 lastBlockNumber; // solhint-disable max-line-length assembly { extraData := shr(40, extraData) totalElements := and( extraData, 0x000000000000000000000000000000000000000000000000000000FFFFFFFFFF ) nextQueueIndex := shr( 40, and(extraData, 0x00000000000000000000000000000000000000000000FFFFFFFFFF0000000000) ) lastTimestamp := shr( 80, and(extraData, 0x0000000000000000000000000000000000FFFFFFFFFF00000000000000000000) ) lastBlockNumber := shr( 120, and(extraData, 0x000000000000000000000000FFFFFFFFFF000000000000000000000000000000) ) } // solhint-enable max-line-length return (totalElements, nextQueueIndex, lastTimestamp, lastBlockNumber); } /** * Encodes the batch context for the extra data. * @param _totalElements Total number of elements submitted. * @param _nextQueueIdx Index of the next queue element. * @param _timestamp Timestamp for the last batch. * @param _blockNumber Block number of the last batch. * @return Encoded batch context. */ function _makeBatchExtraData( uint40 _totalElements, uint40 _nextQueueIdx, uint40 _timestamp, uint40 _blockNumber ) internal pure returns (bytes27) { bytes27 extraData; assembly { extraData := _totalElements extraData := or(extraData, shl(40, _nextQueueIdx)) extraData := or(extraData, shl(80, _timestamp)) extraData := or(extraData, shl(120, _blockNumber)) extraData := shl(40, extraData) } return extraData; } /** * Inserts a batch into the chain of batches. * @param _transactionRoot Root of the transaction tree for this batch. * @param _batchSize Number of elements in the batch. * @param _numQueuedTransactions Number of queue transactions in the batch. * @param _timestamp The latest batch timestamp. * @param _blockNumber The latest batch blockNumber. */ function _appendBatch( bytes32 _transactionRoot, uint256 _batchSize, uint256 _numQueuedTransactions, uint40 _timestamp, uint40 _blockNumber ) internal { IChainStorageContainer batchesRef = batches(); (uint40 totalElements, uint40 nextQueueIndex, , ) = _getBatchExtraData(); Lib_OVMCodec.ChainBatchHeader memory header = Lib_OVMCodec.ChainBatchHeader({ batchIndex: batchesRef.length(), batchRoot: _transactionRoot, batchSize: _batchSize, prevTotalElements: totalElements, extraData: hex"" }); emit TransactionBatchAppended( DEFAULT_CHAINID, header.batchIndex, header.batchRoot, header.batchSize, header.prevTotalElements, header.extraData ); bytes32 batchHeaderHash = Lib_OVMCodec.hashBatchHeader(header); bytes27 latestBatchContext = _makeBatchExtraData( totalElements + uint40(header.batchSize), nextQueueIndex + uint40(_numQueuedTransactions), _timestamp, _blockNumber ); batchesRef.push(batchHeaderHash, latestBatchContext); } //added chain id for public function /** * Retrieves the total number of elements submitted. * @return _totalElements Total submitted elements. */ function getTotalElementsByChainId(uint256 _chainId) override public view returns ( uint256 _totalElements ) { (uint40 totalElements,,,) = _getBatchExtraDataByChainId(_chainId); return uint256(totalElements); } /** * Retrieves the total number of batches submitted. * @return _totalBatches Total submitted batches. */ function getTotalBatchesByChainId(uint256 _chainId) override public view returns ( uint256 _totalBatches ) { return batches().lengthByChainId(_chainId); } /** * Returns the index of the next element to be enqueued. * @return Index for the next queue element. */ function getNextQueueIndexByChainId(uint256 _chainId) override public view returns ( uint40 ) { (,uint40 nextQueueIndex,,) = _getBatchExtraDataByChainId(_chainId); return nextQueueIndex; } /** * Returns the timestamp of the last transaction. * @return Timestamp for the last transaction. */ function getLastTimestampByChainId(uint256 _chainId) override public view returns ( uint40 ) { (,,uint40 lastTimestamp,) = _getBatchExtraDataByChainId(_chainId); return lastTimestamp; } /** * Returns the blocknumber of the last transaction. * @return Blocknumber for the last transaction. */ function getLastBlockNumberByChainId(uint256 _chainId) override public view returns ( uint40 ) { (,,,uint40 lastBlockNumber) = _getBatchExtraDataByChainId(_chainId); return lastBlockNumber; } /** * Gets the queue element at a particular index. * @param _index Index of the queue element to access. * @return _element Queue element at the given index. */ function getQueueElementByChainId( uint256 _chainId, uint256 _index ) override public view returns ( Lib_OVMCodec.QueueElement memory _element ) { return queueElements[_chainId][_index]; } /** * Get the number of queue elements which have not yet been included. * @return Number of pending queue elements. */ function getNumPendingQueueElementsByChainId( uint256 _chainId ) override public view returns ( uint40 ) { return uint40(queueElements[_chainId].length) - _nextQueueIndex[_chainId]; } /** * Retrieves the length of the queue, including * both pending and canonical transactions. * @return Length of the queue. */ function getQueueLengthByChainId( uint256 _chainId ) override public view returns ( uint40 ) { return uint40(queueElements[_chainId].length); } /** * Adds a transaction to the queue. * @param _target Target L2 contract to send the transaction to. * @param _gasLimit Gas limit for the enqueued L2 transaction. * @param _data Transaction data. */ function enqueueByChainId( uint256 _chainId, address _target, uint256 _gasLimit, bytes memory _data ) override public { require(msg.sender == resolve("Proxy__OVM_L1CrossDomainMessenger"), "only the cross domain messenger can enqueue"); require( _data.length <= MAX_ROLLUP_TX_SIZE, "Transaction data size exceeds maximum for rollup transaction." ); require( _gasLimit <= maxTransactionGasLimit, "Transaction gas limit exceeds maximum for rollup transaction." ); require( _gasLimit >= MIN_ROLLUP_TX_GAS, "Transaction gas limit too low to enqueue." ); // Apply an aliasing unless msg.sender == tx.origin. This prevents an attack in which a // contract on L1 has the same address as a contract on L2 but doesn't have the same code. // We can safely ignore this for EOAs because they're guaranteed to have the same "code" // (i.e. no code at all). This also makes it possible for users to interact with contracts // on L2 even when the Sequencer is down. address sender; if (msg.sender == tx.origin) { sender = msg.sender; } else { sender = AddressAliasHelper.applyL1ToL2Alias(msg.sender); } bytes32 transactionHash = keccak256( abi.encode( sender, _target, _gasLimit, _data ) ); queueElements[_chainId].push( Lib_OVMCodec.QueueElement({ transactionHash: transactionHash, timestamp: uint40(block.timestamp), blockNumber: uint40(block.number) }) ); // The underlying queue data structure stores 2 elements // per insertion, so to get the real queue length we need // to divide by 2 and subtract 1. uint256 queueIndex = queueElements[_chainId].length - 1; emit TransactionEnqueued( _chainId, sender, _target, _gasLimit, _data, queueIndex, block.timestamp ); } function uint2str(uint _i) internal pure returns (string memory _uintAsString) { if (_i == 0) { return "0"; } uint j = _i; uint len; while (j != 0) { len++; j /= 10; } bytes memory bstr = new bytes(len); uint k = len; while (_i != 0) { k = k-1; uint8 temp = (48 + uint8(_i - _i / 10 * 10)); bytes1 b1 = bytes1(temp); bstr[k] = b1; _i /= 10; } return string(bstr); } /** * Allows the sequencer to append a batch of transactions. * @dev This function uses a custom encoding scheme for efficiency reasons. * .param _shouldStartAtElement Specific batch we expect to start appending to. * .param _totalElementsToAppend Total number of batch elements we expect to append. * .param _contexts Array of batch contexts. * .param _transactionDataFields Array of raw transaction data. */ function appendSequencerBatchByChainId() override public { uint256 _chainId; uint40 shouldStartAtElement; uint24 totalElementsToAppend; uint24 numContexts; assembly { _chainId := calldataload(4) shouldStartAtElement := shr(216, calldataload(36)) totalElementsToAppend := shr(232, calldataload(41)) numContexts := shr(232, calldataload(44)) } require( shouldStartAtElement == getTotalElementsByChainId(_chainId), "Actual batch start index does not match expected start index." ); require( msg.sender == resolve(string(abi.encodePacked(uint2str(_chainId),"_MVM_Sequencer"))), "Function can only be called by the Sequencer." ); require( numContexts > 0, "Must provide at least one batch context." ); require( totalElementsToAppend > 0, "Must append at least one element." ); uint40 nextTransactionPtr = uint40( BATCH_CONTEXT_START_POS + BATCH_CONTEXT_SIZE * numContexts ); require( msg.data.length >= nextTransactionPtr, "Not enough BatchContexts provided." ); // Cache the _nextQueueIndex storage variable to a temporary stack variable. // This is safe as long as nothing reads or writes to the storage variable // until it is updated by the temp variable. uint40 nextQueueIndex = _nextQueueIndex[_chainId]; // Counter for number of sequencer transactions appended so far. uint32 numSequencerTransactions = 0; BatchContext memory curContext; for (uint32 i = 0; i < numContexts; i++) { BatchContext memory nextContext = _getBatchContextByChainId(0,_chainId,i); // Now we can update our current context. curContext = nextContext; // Process sequencer transactions first. numSequencerTransactions += uint32(curContext.numSequencedTransactions); // Now process any subsequent queue transactions. nextQueueIndex += uint40(curContext.numSubsequentQueueTransactions); } require( nextQueueIndex <= queueElements[_chainId].length, "Attempted to append more elements than are available in the queue." ); // Generate the required metadata that we need to append this batch uint40 numQueuedTransactions = totalElementsToAppend - numSequencerTransactions; uint40 blockTimestamp; uint40 blockNumber; if (curContext.numSubsequentQueueTransactions == 0) { // The last element is a sequencer tx, therefore pull timestamp and block number from // the last context. blockTimestamp = uint40(curContext.timestamp); blockNumber = uint40(curContext.blockNumber); } else { // The last element is a queue tx, therefore pull timestamp and block number from the // queue element. // curContext.numSubsequentQueueTransactions > 0 which means that we've processed at // least one queue element. We increment nextQueueIndex after processing each queue // element, so the index of the last element we processed is nextQueueIndex - 1. Lib_OVMCodec.QueueElement memory lastElement = queueElements[_chainId][nextQueueIndex - 1]; blockTimestamp = lastElement.timestamp; blockNumber = lastElement.blockNumber; } // For efficiency reasons getMerkleRoot modifies the `leaves` argument in place // while calculating the root hash therefore any arguments passed to it must not // be used again afterwards _appendBatchByChainId( _chainId, blockhash(block.number - 1), totalElementsToAppend, numQueuedTransactions, blockTimestamp, blockNumber ); emit SequencerBatchAppended( _chainId, nextQueueIndex - numQueuedTransactions, numQueuedTransactions, getTotalElementsByChainId(_chainId) ); // Update the _nextQueueIndex storage variable. _nextQueueIndex[_chainId] = nextQueueIndex; } /********************** * Internal Functions * **********************/ /** * Returns the BatchContext located at a particular index. * @param _index The index of the BatchContext * @return The BatchContext at the specified index. */ function _getBatchContextByChainId( uint256 _ptrStart, uint256 _chainId, uint256 _index ) internal pure returns ( BatchContext memory ) { uint256 contextPtr = _ptrStart + 32 + 15 + _index * BATCH_CONTEXT_SIZE; uint256 numSequencedTransactions; uint256 numSubsequentQueueTransactions; uint256 ctxTimestamp; uint256 ctxBlockNumber; assembly { numSequencedTransactions := shr(232, calldataload(contextPtr)) numSubsequentQueueTransactions := shr(232, calldataload(add(contextPtr, 3))) ctxTimestamp := shr(216, calldataload(add(contextPtr, 6))) ctxBlockNumber := shr(216, calldataload(add(contextPtr, 11))) } return BatchContext({ numSequencedTransactions: numSequencedTransactions, numSubsequentQueueTransactions: numSubsequentQueueTransactions, timestamp: ctxTimestamp, blockNumber: ctxBlockNumber }); } /** * Parses the batch context from the extra data. * @return Total number of elements submitted. * @return Index of the next queue element. */ function _getBatchExtraDataByChainId( uint256 _chainId ) internal view returns ( uint40, uint40, uint40, uint40 ) { bytes27 extraData = batches().getGlobalMetadataByChainId(_chainId); uint40 totalElements; uint40 nextQueueIndex; uint40 lastTimestamp; uint40 lastBlockNumber; assembly { extraData := shr(40, extraData) totalElements := and(extraData, 0x000000000000000000000000000000000000000000000000000000FFFFFFFFFF) nextQueueIndex := shr(40, and(extraData, 0x00000000000000000000000000000000000000000000FFFFFFFFFF0000000000)) lastTimestamp := shr(80, and(extraData, 0x0000000000000000000000000000000000FFFFFFFFFF00000000000000000000)) lastBlockNumber := shr(120, and(extraData, 0x000000000000000000000000FFFFFFFFFF000000000000000000000000000000)) } return ( totalElements, nextQueueIndex, lastTimestamp, lastBlockNumber ); } /** * Encodes the batch context for the extra data. * @param _totalElements Total number of elements submitted. * @param _nextQueueIdx Index of the next queue element. * @param _timestamp Timestamp for the last batch. * @param _blockNumber Block number of the last batch. * @return Encoded batch context. */ function _makeBatchExtraDataByChainId( uint256 _chainId, uint40 _totalElements, uint40 _nextQueueIdx, uint40 _timestamp, uint40 _blockNumber ) internal pure returns ( bytes27 ) { bytes27 extraData; assembly { extraData := _totalElements extraData := or(extraData, shl(40, _nextQueueIdx)) extraData := or(extraData, shl(80, _timestamp)) extraData := or(extraData, shl(120, _blockNumber)) extraData := shl(40, extraData) } return extraData; } /** * Inserts a batch into the chain of batches. * @param _transactionRoot Root of the transaction tree for this batch. * @param _batchSize Number of elements in the batch. * @param _numQueuedTransactions Number of queue transactions in the batch. * @param _timestamp The latest batch timestamp. * @param _blockNumber The latest batch blockNumber. */ function _appendBatchByChainId( uint256 _chainId, bytes32 _transactionRoot, uint256 _batchSize, uint256 _numQueuedTransactions, uint40 _timestamp, uint40 _blockNumber ) internal { IChainStorageContainer batchesRef = batches(); (uint40 totalElements, uint40 nextQueueIndex, , ) = _getBatchExtraDataByChainId(_chainId); Lib_OVMCodec.ChainBatchHeader memory header = Lib_OVMCodec.ChainBatchHeader({ batchIndex: batchesRef.lengthByChainId(_chainId), batchRoot: _transactionRoot, batchSize: _batchSize, prevTotalElements: totalElements, extraData: hex"" }); emit TransactionBatchAppended( _chainId, header.batchIndex, header.batchRoot, header.batchSize, header.prevTotalElements, header.extraData ); bytes32 batchHeaderHash = Lib_OVMCodec.hashBatchHeader(header); bytes27 latestBatchContext = _makeBatchExtraDataByChainId( _chainId, totalElements + uint40(header.batchSize), nextQueueIndex + uint40(_numQueuedTransactions), _timestamp, _blockNumber ); batchesRef.pushByChainId(_chainId,batchHeaderHash, latestBatchContext); } modifier onlyManager() { require( msg.sender == resolve("MVM_SuperManager"), "ChainStorageContainer: Function can only be called by the owner." ); _; } function pushQueueByChainId( uint256 _chainId, Lib_OVMCodec.QueueElement calldata _object ) override public onlyManager { queueElements[_chainId].push(_object); emit QueuePushed(msg.sender,_chainId,_object); } function setQueueByChainId( uint256 _chainId, uint256 _index, Lib_OVMCodec.QueueElement calldata _object ) override public onlyManager { queueElements[_chainId][_index] = _object; emit QueueSetted(msg.sender,_chainId,_index,_object); } function setBatchGlobalMetadataByChainId( uint256 _chainId, bytes27 _globalMetadata ) override public onlyManager { batches().setGlobalMetadataByChainId(_chainId,_globalMetadata); emit BatchesGlobalMetadataSet(msg.sender,_chainId,_globalMetadata); } function getBatchGlobalMetadataByChainId(uint256 _chainId) override public view returns ( bytes27 ) { return batches().getGlobalMetadataByChainId(_chainId); } function lengthBatchByChainId(uint256 _chainId) override public view returns ( uint256 ) { return batches().lengthByChainId(_chainId); } function pushBatchByChainId( uint256 _chainId, bytes32 _object, bytes27 _globalMetadata ) override public onlyManager { batches().pushByChainId(_chainId,_object,_globalMetadata); emit BatchPushed(msg.sender,_chainId,_object,_globalMetadata); } function setBatchByChainId( uint256 _chainId, uint256 _index, bytes32 _object ) override public onlyManager { batches().setByChainId(_chainId,_index,_object); emit BatchSetted(msg.sender,_chainId,_index,_object); } function getBatchByChainId( uint256 _chainId, uint256 _index ) override public view returns ( bytes32 ) { return batches().getByChainId(_chainId,_index); } function deleteBatchElementsAfterInclusiveByChainId( uint256 _chainId, uint256 _index, bytes27 _globalMetadata ) override public onlyManager { batches().deleteElementsAfterInclusiveByChainId( _chainId, _index, _globalMetadata ); emit BatchElementDeleted(msg.sender,_chainId,_index,_globalMetadata); } }
// SPDX-License-Identifier: Apache-2.0 /* * Copyright 2019-2021, Offchain Labs, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ pragma solidity ^0.8.7; library AddressAliasHelper { uint160 constant offset = uint160(0x1111000000000000000000000000000000001111); /// @notice Utility function that converts the address in the L1 that submitted a tx to /// the inbox to the msg.sender viewed in the L2 /// @param l1Address the address in the L1 that triggered the tx to L2 /// @return l2Address L2 address as viewed in msg.sender function applyL1ToL2Alias(address l1Address) internal pure returns (address l2Address) { unchecked { l2Address = address(uint160(l1Address) + offset); } } /// @notice Utility function that converts the msg.sender viewed in the L2 to the /// address in the L1 that submitted a tx to the inbox /// @param l2Address L2 address as viewed in msg.sender /// @return l1Address the address in the L1 that triggered the tx to L2 function undoL1ToL2Alias(address l2Address) internal pure returns (address l1Address) { unchecked { l1Address = address(uint160(l2Address) - offset); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; /* Library Imports */ import { Lib_RLPReader } from "../rlp/Lib_RLPReader.sol"; import { Lib_RLPWriter } from "../rlp/Lib_RLPWriter.sol"; import { Lib_BytesUtils } from "../utils/Lib_BytesUtils.sol"; import { Lib_Bytes32Utils } from "../utils/Lib_Bytes32Utils.sol"; /** * @title Lib_OVMCodec */ library Lib_OVMCodec { /********* * Enums * *********/ enum QueueOrigin { SEQUENCER_QUEUE, L1TOL2_QUEUE } /*********** * Structs * ***********/ struct EVMAccount { uint256 nonce; uint256 balance; bytes32 storageRoot; bytes32 codeHash; } struct ChainBatchHeader { uint256 batchIndex; bytes32 batchRoot; uint256 batchSize; uint256 prevTotalElements; bytes extraData; } struct ChainInclusionProof { uint256 index; bytes32[] siblings; } struct Transaction { uint256 timestamp; uint256 blockNumber; QueueOrigin l1QueueOrigin; address l1TxOrigin; address entrypoint; uint256 gasLimit; bytes data; } struct TransactionChainElement { bool isSequenced; uint256 queueIndex; // QUEUED TX ONLY uint256 timestamp; // SEQUENCER TX ONLY uint256 blockNumber; // SEQUENCER TX ONLY bytes txData; // SEQUENCER TX ONLY } struct QueueElement { bytes32 transactionHash; uint40 timestamp; uint40 blockNumber; } /********************** * Internal Functions * **********************/ /** * Encodes a standard OVM transaction. * @param _transaction OVM transaction to encode. * @return Encoded transaction bytes. */ function encodeTransaction(Transaction memory _transaction) internal pure returns (bytes memory) { return abi.encodePacked( _transaction.timestamp, _transaction.blockNumber, _transaction.l1QueueOrigin, _transaction.l1TxOrigin, _transaction.entrypoint, _transaction.gasLimit, _transaction.data ); } /** * Hashes a standard OVM transaction. * @param _transaction OVM transaction to encode. * @return Hashed transaction */ function hashTransaction(Transaction memory _transaction) internal pure returns (bytes32) { return keccak256(encodeTransaction(_transaction)); } /** * @notice Decodes an RLP-encoded account state into a useful struct. * @param _encoded RLP-encoded account state. * @return Account state struct. */ function decodeEVMAccount(bytes memory _encoded) internal pure returns (EVMAccount memory) { Lib_RLPReader.RLPItem[] memory accountState = Lib_RLPReader.readList(_encoded); return EVMAccount({ nonce: Lib_RLPReader.readUint256(accountState[0]), balance: Lib_RLPReader.readUint256(accountState[1]), storageRoot: Lib_RLPReader.readBytes32(accountState[2]), codeHash: Lib_RLPReader.readBytes32(accountState[3]) }); } /** * Calculates a hash for a given batch header. * @param _batchHeader Header to hash. * @return Hash of the header. */ function hashBatchHeader(Lib_OVMCodec.ChainBatchHeader memory _batchHeader) internal pure returns (bytes32) { return keccak256( abi.encode( _batchHeader.batchRoot, _batchHeader.batchSize, _batchHeader.prevTotalElements, _batchHeader.extraData ) ); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; /* Library Imports */ import { Lib_AddressManager } from "./Lib_AddressManager.sol"; /** * @title Lib_AddressResolver */ abstract contract Lib_AddressResolver { /************* * Variables * *************/ Lib_AddressManager public libAddressManager; /*************** * Constructor * ***************/ /** * @param _libAddressManager Address of the Lib_AddressManager. */ constructor(address _libAddressManager) { libAddressManager = Lib_AddressManager(_libAddressManager); } /******************** * Public Functions * ********************/ /** * Resolves the address associated with a given name. * @param _name Name to resolve an address for. * @return Address associated with the given name. */ function resolve(string memory _name) public view returns (address) { return libAddressManager.getAddress(_name); } }
// SPDX-License-Identifier: MIT pragma solidity >0.5.0 <0.9.0; /* Library Imports */ import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol"; /* Interface Imports */ import { IChainStorageContainer } from "./IChainStorageContainer.sol"; /** * @title ICanonicalTransactionChain */ interface ICanonicalTransactionChain { /********** * Events * **********/ event QueueGlobalMetadataSet( address _sender, uint256 _chainId, bytes27 _globalMetadata ); event QueuePushed( address _sender, uint256 _chainId, Lib_OVMCodec.QueueElement _object ); event QueueSetted( address _sender, uint256 _chainId, uint256 _index, Lib_OVMCodec.QueueElement _object ); event QueueElementDeleted( address _sender, uint256 _chainId, uint256 _index, bytes27 _globalMetadata ); event BatchesGlobalMetadataSet( address _sender, uint256 _chainId, bytes27 _globalMetadata ); event BatchPushed( address _sender, uint256 _chainId, bytes32 _object, bytes27 _globalMetadata ); event BatchSetted( address _sender, uint256 _chainId, uint256 _index, bytes32 _object ); event BatchElementDeleted( address _sender, uint256 _chainId, uint256 _index, bytes27 _globalMetadata ); event L2GasParamsUpdated( uint256 l2GasDiscountDivisor, uint256 enqueueGasCost, uint256 enqueueL2GasPrepaid ); event TransactionEnqueued( uint256 _chainId, address indexed _l1TxOrigin, address indexed _target, uint256 _gasLimit, bytes _data, uint256 indexed _queueIndex, uint256 _timestamp ); event QueueBatchAppended( uint256 _chainId, uint256 _startingQueueIndex, uint256 _numQueueElements, uint256 _totalElements ); event SequencerBatchAppended( uint256 _chainId, uint256 _startingQueueIndex, uint256 _numQueueElements, uint256 _totalElements ); event TransactionBatchAppended( uint256 _chainId, uint256 indexed _batchIndex, bytes32 _batchRoot, uint256 _batchSize, uint256 _prevTotalElements, bytes _extraData ); /*********** * Structs * ***********/ struct BatchContext { uint256 numSequencedTransactions; uint256 numSubsequentQueueTransactions; uint256 timestamp; uint256 blockNumber; } /******************************* * Authorized Setter Functions * *******************************/ /** * Allows the Burn Admin to update the parameters which determine the amount of gas to burn. * The value of enqueueL2GasPrepaid is immediately updated as well. */ function setGasParams(uint256 _l2GasDiscountDivisor, uint256 _enqueueGasCost) external; /******************** * Public Functions * ********************/ /** * Accesses the batch storage container. * @return Reference to the batch storage container. */ function batches() external view returns (IChainStorageContainer); /** * Accesses the queue storage container. * @return Reference to the queue storage container. */ function queue() external view returns (IChainStorageContainer); /** * Retrieves the total number of elements submitted. * @return _totalElements Total submitted elements. */ function getTotalElements() external view returns (uint256 _totalElements); /** * Retrieves the total number of batches submitted. * @return _totalBatches Total submitted batches. */ function getTotalBatches() external view returns (uint256 _totalBatches); /** * Returns the index of the next element to be enqueued. * @return Index for the next queue element. */ function getNextQueueIndex() external view returns (uint40); /** * Gets the queue element at a particular index. * @param _index Index of the queue element to access. * @return _element Queue element at the given index. */ function getQueueElement(uint256 _index) external view returns (Lib_OVMCodec.QueueElement memory _element); /** * Returns the timestamp of the last transaction. * @return Timestamp for the last transaction. */ function getLastTimestamp() external view returns (uint40); /** * Returns the blocknumber of the last transaction. * @return Blocknumber for the last transaction. */ function getLastBlockNumber() external view returns (uint40); /** * Get the number of queue elements which have not yet been included. * @return Number of pending queue elements. */ function getNumPendingQueueElements() external view returns (uint40); /** * Retrieves the length of the queue, including * both pending and canonical transactions. * @return Length of the queue. */ function getQueueLength() external view returns (uint40); /** * Adds a transaction to the queue. * @param _target Target contract to send the transaction to. * @param _gasLimit Gas limit for the given transaction. * @param _data Transaction data. */ function enqueue( address _target, uint256 _gasLimit, bytes memory _data ) external; /** * Allows the sequencer to append a batch of transactions. * @dev This function uses a custom encoding scheme for efficiency reasons. * .param _shouldStartAtElement Specific batch we expect to start appending to. * .param _totalElementsToAppend Total number of batch elements we expect to append. * .param _contexts Array of batch contexts. * .param _transactionDataFields Array of raw transaction data. */ function appendSequencerBatch( // uint40 _shouldStartAtElement, // uint24 _totalElementsToAppend, // BatchContext[] _contexts, // bytes[] _transactionDataFields ) external; //added chain id function /** * Retrieves the total number of elements submitted. * @param _chainId identity for the l2 chain. * @return _totalElements Total submitted elements. */ function getTotalElementsByChainId( uint256 _chainId ) external view returns ( uint256 _totalElements ); /** * Retrieves the total number of batches submitted. * @param _chainId identity for the l2 chain. * @return _totalBatches Total submitted batches. */ function getTotalBatchesByChainId( uint256 _chainId ) external view returns ( uint256 _totalBatches ); /** * Returns the index of the next element to be enqueued. * @param _chainId identity for the l2 chain. * @return Index for the next queue element. */ function getNextQueueIndexByChainId( uint256 _chainId ) external view returns ( uint40 ); /** * Gets the queue element at a particular index. * @param _chainId identity for the l2 chain. * @param _index Index of the queue element to access. * @return _element Queue element at the given index. */ function getQueueElementByChainId( uint256 _chainId, uint256 _index ) external view returns ( Lib_OVMCodec.QueueElement memory _element ); /** * Returns the timestamp of the last transaction. * @param _chainId identity for the l2 chain. * @return Timestamp for the last transaction. */ function getLastTimestampByChainId( uint256 _chainId ) external view returns ( uint40 ); /** * Returns the blocknumber of the last transaction. * @param _chainId identity for the l2 chain. * @return Blocknumber for the last transaction. */ function getLastBlockNumberByChainId( uint256 _chainId ) external view returns ( uint40 ); /** * Get the number of queue elements which have not yet been included. * @param _chainId identity for the l2 chain. * @return Number of pending queue elements. */ function getNumPendingQueueElementsByChainId( uint256 _chainId ) external view returns ( uint40 ); /** * Retrieves the length of the queue, including * both pending and canonical transactions. * @param _chainId identity for the l2 chain. * @return Length of the queue. */ function getQueueLengthByChainId( uint256 _chainId ) external view returns ( uint40 ); /** * Adds a transaction to the queue. * @param _chainId identity for the l2 chain. * @param _target Target contract to send the transaction to. * @param _gasLimit Gas limit for the given transaction. * @param _data Transaction data. */ function enqueueByChainId( uint256 _chainId, address _target, uint256 _gasLimit, bytes memory _data ) external; /** * Allows the sequencer to append a batch of transactions. * @dev This function uses a custom encoding scheme for efficiency reasons. * .param _chainId identity for the l2 chain. * .param _shouldStartAtElement Specific batch we expect to start appending to. * .param _totalElementsToAppend Total number of batch elements we expect to append. * .param _contexts Array of batch contexts. * .param _transactionDataFields Array of raw transaction data. */ function appendSequencerBatchByChainId( // uint256 _chainId, // uint40 _shouldStartAtElement, // uint24 _totalElementsToAppend, // BatchContext[] _contexts, // bytes[] _transactionDataFields ) external; function pushQueueByChainId( uint256 _chainId, Lib_OVMCodec.QueueElement calldata _object ) external; function setQueueByChainId( uint256 _chainId, uint256 _index, Lib_OVMCodec.QueueElement calldata _object ) external; function setBatchGlobalMetadataByChainId( uint256 _chainId, bytes27 _globalMetadata ) external; function getBatchGlobalMetadataByChainId(uint256 _chainId) external view returns ( bytes27 ); function lengthBatchByChainId(uint256 _chainId) external view returns ( uint256 ); function pushBatchByChainId( uint256 _chainId, bytes32 _object, bytes27 _globalMetadata ) external; function setBatchByChainId( uint256 _chainId, uint256 _index, bytes32 _object ) external; function getBatchByChainId( uint256 _chainId, uint256 _index ) external view returns ( bytes32 ); function deleteBatchElementsAfterInclusiveByChainId( uint256 _chainId, uint256 _index, bytes27 _globalMetadata ) external; }
// SPDX-License-Identifier: MIT pragma solidity >0.5.0 <0.9.0; /** * @title IChainStorageContainer */ interface IChainStorageContainer { /******************** * Public Functions * ********************/ /** * Sets the container's global metadata field. We're using `bytes27` here because we use five * bytes to maintain the length of the underlying data structure, meaning we have an extra * 27 bytes to store arbitrary data. * @param _globalMetadata New global metadata to set. */ function setGlobalMetadata(bytes27 _globalMetadata) external; /** * Retrieves the container's global metadata field. * @return Container global metadata field. */ function getGlobalMetadata() external view returns (bytes27); /** * Retrieves the number of objects stored in the container. * @return Number of objects in the container. */ function length() external view returns (uint256); /** * Pushes an object into the container. * @param _object A 32 byte value to insert into the container. */ function push(bytes32 _object) external; /** * Pushes an object into the container. Function allows setting the global metadata since * we'll need to touch the "length" storage slot anyway, which also contains the global * metadata (it's an optimization). * @param _object A 32 byte value to insert into the container. * @param _globalMetadata New global metadata for the container. */ function push(bytes32 _object, bytes27 _globalMetadata) external; /** * Set an object into the container. Function allows setting the global metadata since * we'll need to touch the "length" storage slot anyway, which also contains the global * metadata (it's an optimization). * @param _index position. * @param _object A 32 byte value to insert into the container. */ function setByChainId( uint256 _chainId, uint256 _index, bytes32 _object ) external; /** * Retrieves an object from the container. * @param _index Index of the particular object to access. * @return 32 byte object value. */ function get(uint256 _index) external view returns (bytes32); /** * Removes all objects after and including a given index. * @param _index Object index to delete from. */ function deleteElementsAfterInclusive(uint256 _index) external; /** * Removes all objects after and including a given index. Also allows setting the global * metadata field. * @param _index Object index to delete from. * @param _globalMetadata New global metadata for the container. */ function deleteElementsAfterInclusive(uint256 _index, bytes27 _globalMetadata) external; /** * Sets the container's global metadata field. We're using `bytes27` here because we use five * bytes to maintain the length of the underlying data structure, meaning we have an extra * 27 bytes to store arbitrary data. * @param _chainId identity for the l2 chain. * @param _globalMetadata New global metadata to set. */ function setGlobalMetadataByChainId( uint256 _chainId, bytes27 _globalMetadata ) external; /** * Retrieves the container's global metadata field. * @param _chainId identity for the l2 chain. * @return Container global metadata field. */ function getGlobalMetadataByChainId( uint256 _chainId ) external view returns ( bytes27 ); /** * Retrieves the number of objects stored in the container. * @param _chainId identity for the l2 chain. * @return Number of objects in the container. */ function lengthByChainId( uint256 _chainId ) external view returns ( uint256 ); /** * Pushes an object into the container. * @param _chainId identity for the l2 chain. * @param _object A 32 byte value to insert into the container. */ function pushByChainId( uint256 _chainId, bytes32 _object ) external; /** * Pushes an object into the container. Function allows setting the global metadata since * we'll need to touch the "length" storage slot anyway, which also contains the global * metadata (it's an optimization). * @param _chainId identity for the l2 chain. * @param _object A 32 byte value to insert into the container. * @param _globalMetadata New global metadata for the container. */ function pushByChainId( uint256 _chainId, bytes32 _object, bytes27 _globalMetadata ) external; /** * Retrieves an object from the container. * @param _chainId identity for the l2 chain. * @param _index Index of the particular object to access. * @return 32 byte object value. */ function getByChainId( uint256 _chainId, uint256 _index ) external view returns ( bytes32 ); /** * Removes all objects after and including a given index. * @param _chainId identity for the l2 chain. * @param _index Object index to delete from. */ function deleteElementsAfterInclusiveByChainId( uint256 _chainId, uint256 _index ) external; /** * Removes all objects after and including a given index. Also allows setting the global * metadata field. * @param _chainId identity for the l2 chain. * @param _index Object index to delete from. * @param _globalMetadata New global metadata for the container. */ function deleteElementsAfterInclusiveByChainId( uint256 _chainId, uint256 _index, bytes27 _globalMetadata ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; /** * @title Lib_RLPReader * @dev Adapted from "RLPReader" by Hamdi Allam ([email protected]). */ library Lib_RLPReader { /************* * Constants * *************/ uint256 internal constant MAX_LIST_LENGTH = 32; /********* * Enums * *********/ enum RLPItemType { DATA_ITEM, LIST_ITEM } /*********** * Structs * ***********/ struct RLPItem { uint256 length; uint256 ptr; } /********************** * Internal Functions * **********************/ /** * Converts bytes to a reference to memory position and length. * @param _in Input bytes to convert. * @return Output memory reference. */ function toRLPItem(bytes memory _in) internal pure returns (RLPItem memory) { uint256 ptr; assembly { ptr := add(_in, 32) } return RLPItem({ length: _in.length, ptr: ptr }); } /** * Reads an RLP list value into a list of RLP items. * @param _in RLP list value. * @return Decoded RLP list items. */ function readList(RLPItem memory _in) internal pure returns (RLPItem[] memory) { (uint256 listOffset, , RLPItemType itemType) = _decodeLength(_in); require(itemType == RLPItemType.LIST_ITEM, "Invalid RLP list value."); // Solidity in-memory arrays can't be increased in size, but *can* be decreased in size by // writing to the length. Since we can't know the number of RLP items without looping over // the entire input, we'd have to loop twice to accurately size this array. It's easier to // simply set a reasonable maximum list length and decrease the size before we finish. RLPItem[] memory out = new RLPItem[](MAX_LIST_LENGTH); uint256 itemCount = 0; uint256 offset = listOffset; while (offset < _in.length) { require(itemCount < MAX_LIST_LENGTH, "Provided RLP list exceeds max list length."); (uint256 itemOffset, uint256 itemLength, ) = _decodeLength( RLPItem({ length: _in.length - offset, ptr: _in.ptr + offset }) ); out[itemCount] = RLPItem({ length: itemLength + itemOffset, ptr: _in.ptr + offset }); itemCount += 1; offset += itemOffset + itemLength; } // Decrease the array size to match the actual item count. assembly { mstore(out, itemCount) } return out; } /** * Reads an RLP list value into a list of RLP items. * @param _in RLP list value. * @return Decoded RLP list items. */ function readList(bytes memory _in) internal pure returns (RLPItem[] memory) { return readList(toRLPItem(_in)); } /** * Reads an RLP bytes value into bytes. * @param _in RLP bytes value. * @return Decoded bytes. */ function readBytes(RLPItem memory _in) internal pure returns (bytes memory) { (uint256 itemOffset, uint256 itemLength, RLPItemType itemType) = _decodeLength(_in); require(itemType == RLPItemType.DATA_ITEM, "Invalid RLP bytes value."); return _copy(_in.ptr, itemOffset, itemLength); } /** * Reads an RLP bytes value into bytes. * @param _in RLP bytes value. * @return Decoded bytes. */ function readBytes(bytes memory _in) internal pure returns (bytes memory) { return readBytes(toRLPItem(_in)); } /** * Reads an RLP string value into a string. * @param _in RLP string value. * @return Decoded string. */ function readString(RLPItem memory _in) internal pure returns (string memory) { return string(readBytes(_in)); } /** * Reads an RLP string value into a string. * @param _in RLP string value. * @return Decoded string. */ function readString(bytes memory _in) internal pure returns (string memory) { return readString(toRLPItem(_in)); } /** * Reads an RLP bytes32 value into a bytes32. * @param _in RLP bytes32 value. * @return Decoded bytes32. */ function readBytes32(RLPItem memory _in) internal pure returns (bytes32) { require(_in.length <= 33, "Invalid RLP bytes32 value."); (uint256 itemOffset, uint256 itemLength, RLPItemType itemType) = _decodeLength(_in); require(itemType == RLPItemType.DATA_ITEM, "Invalid RLP bytes32 value."); uint256 ptr = _in.ptr + itemOffset; bytes32 out; assembly { out := mload(ptr) // Shift the bytes over to match the item size. if lt(itemLength, 32) { out := div(out, exp(256, sub(32, itemLength))) } } return out; } /** * Reads an RLP bytes32 value into a bytes32. * @param _in RLP bytes32 value. * @return Decoded bytes32. */ function readBytes32(bytes memory _in) internal pure returns (bytes32) { return readBytes32(toRLPItem(_in)); } /** * Reads an RLP uint256 value into a uint256. * @param _in RLP uint256 value. * @return Decoded uint256. */ function readUint256(RLPItem memory _in) internal pure returns (uint256) { return uint256(readBytes32(_in)); } /** * Reads an RLP uint256 value into a uint256. * @param _in RLP uint256 value. * @return Decoded uint256. */ function readUint256(bytes memory _in) internal pure returns (uint256) { return readUint256(toRLPItem(_in)); } /** * Reads an RLP bool value into a bool. * @param _in RLP bool value. * @return Decoded bool. */ function readBool(RLPItem memory _in) internal pure returns (bool) { require(_in.length == 1, "Invalid RLP boolean value."); uint256 ptr = _in.ptr; uint256 out; assembly { out := byte(0, mload(ptr)) } require(out == 0 || out == 1, "Lib_RLPReader: Invalid RLP boolean value, must be 0 or 1"); return out != 0; } /** * Reads an RLP bool value into a bool. * @param _in RLP bool value. * @return Decoded bool. */ function readBool(bytes memory _in) internal pure returns (bool) { return readBool(toRLPItem(_in)); } /** * Reads an RLP address value into a address. * @param _in RLP address value. * @return Decoded address. */ function readAddress(RLPItem memory _in) internal pure returns (address) { if (_in.length == 1) { return address(0); } require(_in.length == 21, "Invalid RLP address value."); return address(uint160(readUint256(_in))); } /** * Reads an RLP address value into a address. * @param _in RLP address value. * @return Decoded address. */ function readAddress(bytes memory _in) internal pure returns (address) { return readAddress(toRLPItem(_in)); } /** * Reads the raw bytes of an RLP item. * @param _in RLP item to read. * @return Raw RLP bytes. */ function readRawBytes(RLPItem memory _in) internal pure returns (bytes memory) { return _copy(_in); } /********************* * Private Functions * *********************/ /** * Decodes the length of an RLP item. * @param _in RLP item to decode. * @return Offset of the encoded data. * @return Length of the encoded data. * @return RLP item type (LIST_ITEM or DATA_ITEM). */ function _decodeLength(RLPItem memory _in) private pure returns ( uint256, uint256, RLPItemType ) { require(_in.length > 0, "RLP item cannot be null."); uint256 ptr = _in.ptr; uint256 prefix; assembly { prefix := byte(0, mload(ptr)) } if (prefix <= 0x7f) { // Single byte. return (0, 1, RLPItemType.DATA_ITEM); } else if (prefix <= 0xb7) { // Short string. uint256 strLen = prefix - 0x80; require(_in.length > strLen, "Invalid RLP short string."); return (1, strLen, RLPItemType.DATA_ITEM); } else if (prefix <= 0xbf) { // Long string. uint256 lenOfStrLen = prefix - 0xb7; require(_in.length > lenOfStrLen, "Invalid RLP long string length."); uint256 strLen; assembly { // Pick out the string length. strLen := div(mload(add(ptr, 1)), exp(256, sub(32, lenOfStrLen))) } require(_in.length > lenOfStrLen + strLen, "Invalid RLP long string."); return (1 + lenOfStrLen, strLen, RLPItemType.DATA_ITEM); } else if (prefix <= 0xf7) { // Short list. uint256 listLen = prefix - 0xc0; require(_in.length > listLen, "Invalid RLP short list."); return (1, listLen, RLPItemType.LIST_ITEM); } else { // Long list. uint256 lenOfListLen = prefix - 0xf7; require(_in.length > lenOfListLen, "Invalid RLP long list length."); uint256 listLen; assembly { // Pick out the list length. listLen := div(mload(add(ptr, 1)), exp(256, sub(32, lenOfListLen))) } require(_in.length > lenOfListLen + listLen, "Invalid RLP long list."); return (1 + lenOfListLen, listLen, RLPItemType.LIST_ITEM); } } /** * Copies the bytes from a memory location. * @param _src Pointer to the location to read from. * @param _offset Offset to start reading from. * @param _length Number of bytes to read. * @return Copied bytes. */ function _copy( uint256 _src, uint256 _offset, uint256 _length ) private pure returns (bytes memory) { bytes memory out = new bytes(_length); if (out.length == 0) { return out; } uint256 src = _src + _offset; uint256 dest; assembly { dest := add(out, 32) } // Copy over as many complete words as we can. for (uint256 i = 0; i < _length / 32; i++) { assembly { mstore(dest, mload(src)) } src += 32; dest += 32; } // Pick out the remaining bytes. uint256 mask; unchecked { mask = 256**(32 - (_length % 32)) - 1; } assembly { mstore(dest, or(and(mload(src), not(mask)), and(mload(dest), mask))) } return out; } /** * Copies an RLP item into bytes. * @param _in RLP item to copy. * @return Copied bytes. */ function _copy(RLPItem memory _in) private pure returns (bytes memory) { return _copy(_in.ptr, 0, _in.length); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; /** * @title Lib_RLPWriter * @author Bakaoh (with modifications) */ library Lib_RLPWriter { /********************** * Internal Functions * **********************/ /** * RLP encodes a byte string. * @param _in The byte string to encode. * @return The RLP encoded string in bytes. */ function writeBytes(bytes memory _in) internal pure returns (bytes memory) { bytes memory encoded; if (_in.length == 1 && uint8(_in[0]) < 128) { encoded = _in; } else { encoded = abi.encodePacked(_writeLength(_in.length, 128), _in); } return encoded; } /** * RLP encodes a list of RLP encoded byte byte strings. * @param _in The list of RLP encoded byte strings. * @return The RLP encoded list of items in bytes. */ function writeList(bytes[] memory _in) internal pure returns (bytes memory) { bytes memory list = _flatten(_in); return abi.encodePacked(_writeLength(list.length, 192), list); } /** * RLP encodes a string. * @param _in The string to encode. * @return The RLP encoded string in bytes. */ function writeString(string memory _in) internal pure returns (bytes memory) { return writeBytes(bytes(_in)); } /** * RLP encodes an address. * @param _in The address to encode. * @return The RLP encoded address in bytes. */ function writeAddress(address _in) internal pure returns (bytes memory) { return writeBytes(abi.encodePacked(_in)); } /** * RLP encodes a uint. * @param _in The uint256 to encode. * @return The RLP encoded uint256 in bytes. */ function writeUint(uint256 _in) internal pure returns (bytes memory) { return writeBytes(_toBinary(_in)); } /** * RLP encodes a bool. * @param _in The bool to encode. * @return The RLP encoded bool in bytes. */ function writeBool(bool _in) internal pure returns (bytes memory) { bytes memory encoded = new bytes(1); encoded[0] = (_in ? bytes1(0x01) : bytes1(0x80)); return encoded; } /********************* * Private Functions * *********************/ /** * Encode the first byte, followed by the `len` in binary form if `length` is more than 55. * @param _len The length of the string or the payload. * @param _offset 128 if item is string, 192 if item is list. * @return RLP encoded bytes. */ function _writeLength(uint256 _len, uint256 _offset) private pure returns (bytes memory) { bytes memory encoded; if (_len < 56) { encoded = new bytes(1); encoded[0] = bytes1(uint8(_len) + uint8(_offset)); } else { uint256 lenLen; uint256 i = 1; while (_len / i != 0) { lenLen++; i *= 256; } encoded = new bytes(lenLen + 1); encoded[0] = bytes1(uint8(lenLen) + uint8(_offset) + 55); for (i = 1; i <= lenLen; i++) { encoded[i] = bytes1(uint8((_len / (256**(lenLen - i))) % 256)); } } return encoded; } /** * Encode integer in big endian binary form with no leading zeroes. * @notice TODO: This should be optimized with assembly to save gas costs. * @param _x The integer to encode. * @return RLP encoded bytes. */ function _toBinary(uint256 _x) private pure returns (bytes memory) { bytes memory b = abi.encodePacked(_x); uint256 i = 0; for (; i < 32; i++) { if (b[i] != 0) { break; } } bytes memory res = new bytes(32 - i); for (uint256 j = 0; j < res.length; j++) { res[j] = b[i++]; } return res; } /** * Copies a piece of memory to another location. * @notice From: https://github.com/Arachnid/solidity-stringutils/blob/master/src/strings.sol. * @param _dest Destination location. * @param _src Source location. * @param _len Length of memory to copy. */ function _memcpy( uint256 _dest, uint256 _src, uint256 _len ) private pure { uint256 dest = _dest; uint256 src = _src; uint256 len = _len; for (; len >= 32; len -= 32) { assembly { mstore(dest, mload(src)) } dest += 32; src += 32; } uint256 mask; unchecked { mask = 256**(32 - len) - 1; } assembly { let srcpart := and(mload(src), not(mask)) let destpart := and(mload(dest), mask) mstore(dest, or(destpart, srcpart)) } } /** * Flattens a list of byte strings into one byte string. * @notice From: https://github.com/sammayo/solidity-rlp-encoder/blob/master/RLPEncode.sol. * @param _list List of byte strings to flatten. * @return The flattened byte string. */ function _flatten(bytes[] memory _list) private pure returns (bytes memory) { if (_list.length == 0) { return new bytes(0); } uint256 len; uint256 i = 0; for (; i < _list.length; i++) { len += _list[i].length; } bytes memory flattened = new bytes(len); uint256 flattenedPtr; assembly { flattenedPtr := add(flattened, 0x20) } for (i = 0; i < _list.length; i++) { bytes memory item = _list[i]; uint256 listPtr; assembly { listPtr := add(item, 0x20) } _memcpy(flattenedPtr, listPtr, item.length); flattenedPtr += _list[i].length; } return flattened; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; /** * @title Lib_BytesUtils */ library Lib_BytesUtils { /********************** * Internal Functions * **********************/ function slice( bytes memory _bytes, uint256 _start, uint256 _length ) internal pure returns (bytes memory) { require(_length + 31 >= _length, "slice_overflow"); require(_start + _length >= _start, "slice_overflow"); require(_bytes.length >= _start + _length, "slice_outOfBounds"); bytes memory tempBytes; assembly { switch iszero(_length) case 0 { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // The first word of the slice result is potentially a partial // word read from the original array. To read it, we calculate // the length of that partial word and start copying that many // bytes into the array. The first word we copy will start with // data we don't care about, but the last `lengthmod` bytes will // land at the beginning of the contents of the new array. When // we're done copying, we overwrite the full first word with // the actual length of the slice. let lengthmod := and(_length, 31) // The multiplication in the next line is necessary // because when slicing multiples of 32 bytes (lengthmod == 0) // the following copy loop was copying the origin's length // and then ending prematurely not copying everything it should. let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) let end := add(mc, _length) for { // The multiplication in the next line has the same exact purpose // as the one above. let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } mstore(tempBytes, _length) //update free-memory pointer //allocating the array padded to 32 bytes like the compiler does now mstore(0x40, and(add(mc, 31), not(31))) } //if we want a zero-length slice let's just return a zero-length array default { tempBytes := mload(0x40) //zero out the 32 bytes slice we are about to return //we need to do it because Solidity does not garbage collect mstore(tempBytes, 0) mstore(0x40, add(tempBytes, 0x20)) } } return tempBytes; } function slice(bytes memory _bytes, uint256 _start) internal pure returns (bytes memory) { if (_start >= _bytes.length) { return bytes(""); } return slice(_bytes, _start, _bytes.length - _start); } function toBytes32(bytes memory _bytes) internal pure returns (bytes32) { if (_bytes.length < 32) { bytes32 ret; assembly { ret := mload(add(_bytes, 32)) } return ret; } return abi.decode(_bytes, (bytes32)); // will truncate if input length > 32 bytes } function toUint256(bytes memory _bytes) internal pure returns (uint256) { return uint256(toBytes32(_bytes)); } function toNibbles(bytes memory _bytes) internal pure returns (bytes memory) { bytes memory nibbles = new bytes(_bytes.length * 2); for (uint256 i = 0; i < _bytes.length; i++) { nibbles[i * 2] = _bytes[i] >> 4; nibbles[i * 2 + 1] = bytes1(uint8(_bytes[i]) % 16); } return nibbles; } function fromNibbles(bytes memory _bytes) internal pure returns (bytes memory) { bytes memory ret = new bytes(_bytes.length / 2); for (uint256 i = 0; i < ret.length; i++) { ret[i] = (_bytes[i * 2] << 4) | (_bytes[i * 2 + 1]); } return ret; } function equal(bytes memory _bytes, bytes memory _other) internal pure returns (bool) { return keccak256(_bytes) == keccak256(_other); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; /** * @title Lib_Byte32Utils */ library Lib_Bytes32Utils { /********************** * Internal Functions * **********************/ /** * Converts a bytes32 value to a boolean. Anything non-zero will be converted to "true." * @param _in Input bytes32 value. * @return Bytes32 as a boolean. */ function toBool(bytes32 _in) internal pure returns (bool) { return _in != 0; } /** * Converts a boolean to a bytes32 value. * @param _in Input boolean value. * @return Boolean as a bytes32. */ function fromBool(bool _in) internal pure returns (bytes32) { return bytes32(uint256(_in ? 1 : 0)); } /** * Converts a bytes32 value to an address. Takes the *last* 20 bytes. * @param _in Input bytes32 value. * @return Bytes32 as an address. */ function toAddress(bytes32 _in) internal pure returns (address) { return address(uint160(uint256(_in))); } /** * Converts an address to a bytes32. * @param _in Input address value. * @return Address as a bytes32. */ function fromAddress(address _in) internal pure returns (bytes32) { return bytes32(uint256(uint160(_in))); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; /* External Imports */ import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; /** * @title Lib_AddressManager */ contract Lib_AddressManager is Ownable { /********** * Events * **********/ event AddressSet(string indexed _name, address _newAddress, address _oldAddress); /************* * Variables * *************/ mapping(bytes32 => address) private addresses; /******************** * Public Functions * ********************/ /** * Changes the address associated with a particular name. * @param _name String name to associate an address with. * @param _address Address to associate with the name. */ function setAddress(string memory _name, address _address) external onlyOwner { bytes32 nameHash = _getNameHash(_name); address oldAddress = addresses[nameHash]; addresses[nameHash] = _address; emit AddressSet(_name, _address, oldAddress); } /** * Retrieves the address associated with a given name. * @param _name Name to retrieve an address for. * @return Address associated with the given name. */ function getAddress(string memory _name) external view returns (address) { return addresses[_getNameHash(_name)]; } /********************** * Internal Functions * **********************/ /** * Computes the hash of a name. * @param _name Name to compute a hash for. * @return Hash of the given name. */ function _getNameHash(string memory _name) internal pure returns (bytes32) { return keccak256(abi.encodePacked(_name)); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _setOwner(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _setOwner(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _setOwner(newOwner); } function _setOwner(address newOwner) private { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
{ "optimizer": { "enabled": true, "runs": 10000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_libAddressManager","type":"address"},{"internalType":"uint256","name":"_maxTransactionGasLimit","type":"uint256"},{"internalType":"uint256","name":"_l2GasDiscountDivisor","type":"uint256"},{"internalType":"uint256","name":"_enqueueGasCost","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_chainId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_index","type":"uint256"},{"indexed":false,"internalType":"bytes27","name":"_globalMetadata","type":"bytes27"}],"name":"BatchElementDeleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_chainId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"_object","type":"bytes32"},{"indexed":false,"internalType":"bytes27","name":"_globalMetadata","type":"bytes27"}],"name":"BatchPushed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_chainId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_index","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"_object","type":"bytes32"}],"name":"BatchSetted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_chainId","type":"uint256"},{"indexed":false,"internalType":"bytes27","name":"_globalMetadata","type":"bytes27"}],"name":"BatchesGlobalMetadataSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"l2GasDiscountDivisor","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"enqueueGasCost","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"enqueueL2GasPrepaid","type":"uint256"}],"name":"L2GasParamsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_chainId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_startingQueueIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_numQueueElements","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_totalElements","type":"uint256"}],"name":"QueueBatchAppended","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_chainId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_index","type":"uint256"},{"indexed":false,"internalType":"bytes27","name":"_globalMetadata","type":"bytes27"}],"name":"QueueElementDeleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_chainId","type":"uint256"},{"indexed":false,"internalType":"bytes27","name":"_globalMetadata","type":"bytes27"}],"name":"QueueGlobalMetadataSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_chainId","type":"uint256"},{"components":[{"internalType":"bytes32","name":"transactionHash","type":"bytes32"},{"internalType":"uint40","name":"timestamp","type":"uint40"},{"internalType":"uint40","name":"blockNumber","type":"uint40"}],"indexed":false,"internalType":"struct Lib_OVMCodec.QueueElement","name":"_object","type":"tuple"}],"name":"QueuePushed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_chainId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_index","type":"uint256"},{"components":[{"internalType":"bytes32","name":"transactionHash","type":"bytes32"},{"internalType":"uint40","name":"timestamp","type":"uint40"},{"internalType":"uint40","name":"blockNumber","type":"uint40"}],"indexed":false,"internalType":"struct Lib_OVMCodec.QueueElement","name":"_object","type":"tuple"}],"name":"QueueSetted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_chainId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_startingQueueIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_numQueueElements","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_totalElements","type":"uint256"}],"name":"SequencerBatchAppended","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_chainId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"_batchIndex","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"_batchRoot","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"_batchSize","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_prevTotalElements","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"_extraData","type":"bytes"}],"name":"TransactionBatchAppended","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_chainId","type":"uint256"},{"indexed":true,"internalType":"address","name":"_l1TxOrigin","type":"address"},{"indexed":true,"internalType":"address","name":"_target","type":"address"},{"indexed":false,"internalType":"uint256","name":"_gasLimit","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"_data","type":"bytes"},{"indexed":true,"internalType":"uint256","name":"_queueIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"TransactionEnqueued","type":"event"},{"inputs":[],"name":"DEFAULT_CHAINID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_ROLLUP_TX_SIZE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_ROLLUP_TX_GAS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"appendSequencerBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"appendSequencerBatchByChainId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"batches","outputs":[{"internalType":"contract IChainStorageContainer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_chainId","type":"uint256"},{"internalType":"uint256","name":"_index","type":"uint256"},{"internalType":"bytes27","name":"_globalMetadata","type":"bytes27"}],"name":"deleteBatchElementsAfterInclusiveByChainId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_target","type":"address"},{"internalType":"uint256","name":"_gasLimit","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"enqueue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_chainId","type":"uint256"},{"internalType":"address","name":"_target","type":"address"},{"internalType":"uint256","name":"_gasLimit","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"enqueueByChainId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enqueueGasCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enqueueL2GasPrepaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_chainId","type":"uint256"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getBatchByChainId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_chainId","type":"uint256"}],"name":"getBatchGlobalMetadataByChainId","outputs":[{"internalType":"bytes27","name":"","type":"bytes27"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastBlockNumber","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_chainId","type":"uint256"}],"name":"getLastBlockNumberByChainId","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastTimestamp","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_chainId","type":"uint256"}],"name":"getLastTimestampByChainId","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNextQueueIndex","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_chainId","type":"uint256"}],"name":"getNextQueueIndexByChainId","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNumPendingQueueElements","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_chainId","type":"uint256"}],"name":"getNumPendingQueueElementsByChainId","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getQueueElement","outputs":[{"components":[{"internalType":"bytes32","name":"transactionHash","type":"bytes32"},{"internalType":"uint40","name":"timestamp","type":"uint40"},{"internalType":"uint40","name":"blockNumber","type":"uint40"}],"internalType":"struct Lib_OVMCodec.QueueElement","name":"_element","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_chainId","type":"uint256"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getQueueElementByChainId","outputs":[{"components":[{"internalType":"bytes32","name":"transactionHash","type":"bytes32"},{"internalType":"uint40","name":"timestamp","type":"uint40"},{"internalType":"uint40","name":"blockNumber","type":"uint40"}],"internalType":"struct Lib_OVMCodec.QueueElement","name":"_element","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getQueueLength","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_chainId","type":"uint256"}],"name":"getQueueLengthByChainId","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalBatches","outputs":[{"internalType":"uint256","name":"_totalBatches","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_chainId","type":"uint256"}],"name":"getTotalBatchesByChainId","outputs":[{"internalType":"uint256","name":"_totalBatches","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalElements","outputs":[{"internalType":"uint256","name":"_totalElements","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_chainId","type":"uint256"}],"name":"getTotalElementsByChainId","outputs":[{"internalType":"uint256","name":"_totalElements","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l2GasDiscountDivisor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_chainId","type":"uint256"}],"name":"lengthBatchByChainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"libAddressManager","outputs":[{"internalType":"contract Lib_AddressManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTransactionGasLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_chainId","type":"uint256"},{"internalType":"bytes32","name":"_object","type":"bytes32"},{"internalType":"bytes27","name":"_globalMetadata","type":"bytes27"}],"name":"pushBatchByChainId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_chainId","type":"uint256"},{"components":[{"internalType":"bytes32","name":"transactionHash","type":"bytes32"},{"internalType":"uint40","name":"timestamp","type":"uint40"},{"internalType":"uint40","name":"blockNumber","type":"uint40"}],"internalType":"struct Lib_OVMCodec.QueueElement","name":"_object","type":"tuple"}],"name":"pushQueueByChainId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"queue","outputs":[{"internalType":"contract IChainStorageContainer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"}],"name":"resolve","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_chainId","type":"uint256"},{"internalType":"uint256","name":"_index","type":"uint256"},{"internalType":"bytes32","name":"_object","type":"bytes32"}],"name":"setBatchByChainId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_chainId","type":"uint256"},{"internalType":"bytes27","name":"_globalMetadata","type":"bytes27"}],"name":"setBatchGlobalMetadataByChainId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_l2GasDiscountDivisor","type":"uint256"},{"internalType":"uint256","name":"_enqueueGasCost","type":"uint256"}],"name":"setGasParams","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_chainId","type":"uint256"},{"internalType":"uint256","name":"_index","type":"uint256"},{"components":[{"internalType":"bytes32","name":"transactionHash","type":"bytes32"},{"internalType":"uint40","name":"timestamp","type":"uint40"},{"internalType":"uint40","name":"blockNumber","type":"uint40"}],"internalType":"struct Lib_OVMCodec.QueueElement","name":"_object","type":"tuple"}],"name":"setQueueByChainId","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b50604051620038d9380380620038d9833981016040819052620000349162000078565b600080546001600160a01b0319166001600160a01b0386161790556004839055600282905560018190556200006a8183620000c5565b60035550620000f392505050565b600080600080608085870312156200008f57600080fd5b84516001600160a01b0381168114620000a757600080fd5b60208601516040870151606090970151919890975090945092505050565b6000816000190483118215151615620000ee57634e487b7160e01b600052601160045260246000fd5b500290565b6137d680620001036000396000f3fe608060405234801561001057600080fd5b50600436106102d35760003560e01c80637a209b9311610186578063b4be51ae116100e3578063db29772211610097578063e654b1fb11610071578063e654b1fb146105fb578063edcc4a4514610604578063f722b41a1461061757600080fd5b8063db297722146105d8578063e10d29ee146105eb578063e561dddc146105f357600080fd5b8063ccf987c8116100c8578063ccf987c8146105bf578063cfdf677e146105c8578063d0f89344146105d057600080fd5b8063b4be51ae1461057a578063b8f770051461058d57600080fd5b80638d38c6c11161013a578063a14420ee1161011f578063a14420ee1461054c578063a16d359a1461055f578063a8cda37b1461057257600080fd5b80638d38c6c1146105305780639156f18a1461053957600080fd5b8063876ed5cb1161016b578063876ed5cb146105145780638a52e6221461051d5780638c7de742146103ee57600080fd5b80637a209b93146104e25780637aa63a861461050c57600080fd5b8063461a4478116102345780635bbbb7ed116101e85780636fee07e0116101cd5780636fee07e01461048c57806378f4b2f21461049f5780637a167a8a146104a957600080fd5b80635bbbb7ed1461047057806363d5dbd11461047957600080fd5b80634f5da7c6116102195780634f5da7c614610442578063511da531146104555780635ae6256d1461046857600080fd5b8063461a44781461041c5780634a0eddab1461042f57600080fd5b8063299ca4781161028b5780632de6a708116102705780632de6a708146103ee578063378997701461040157806343be0a841461040957600080fd5b8063299ca478146103655780632a7f18be146103aa57600080fd5b806319625535116102bc57806319625535146103095780632538f3a81461031c57806325412c841461035257600080fd5b80630545ba77146102d85780630b3dfa97146102ed575b600080fd5b6102eb6102e6366004612ed6565b61061f565b005b6102f660035481565b6040519081526020015b60405180910390f35b6102eb610317366004612ed6565b6107f9565b61033c61032a366004612f0f565b60009081526006602052604090205490565b60405164ffffffffff9091168152602001610300565b6102f6610360366004612f28565b6109c5565b6000546103859073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610300565b6103bd6103b8366004612f0f565b610a7d565b604080518251815260208084015164ffffffffff908116918301919091529282015190921690820152606001610300565b6102f66103fc366004612f0f565b610b26565b61033c610bc0565b61033c610417366004612f0f565b610bd4565b61038561042a36600461300d565b610bff565b61033c61043d366004612f0f565b610ca6565b6102eb61045036600461306e565b610cbc565b6102eb6104633660046130e6565b610e11565b61033c6111ce565b6102f661044081565b6102eb610487366004613149565b6111e2565b6102eb61049a366004613175565b6113a0565b6102f6620186a081565b61044060005260056020527f0dc7af05b69860904321737f972990978ada95ccab9945c9e4152a2706ab58865464ffffffffff1661033c565b6104f56104f0366004612f0f565b6113b3565b60405164ffffffffff199091168152602001610300565b6102f6611447565b6102f661c35081565b6102f661052b366004612f0f565b611462565b6102f660045481565b61033c610547366004612f0f565b61147f565b6102eb61055a3660046131ce565b611495565b6103bd61056d366004612f28565b61165e565b6102eb6116eb565b6102eb6105883660046131fe565b611cb1565b61044060005260066020527ff2fadc8f281df3b2e312450efbc7e5145e4214fc70e639a3a1b10148ef5697af5461033c565b6102f660025481565b610385611df3565b6102eb611e1b565b61033c6105e6366004612f0f565b612362565b610385612379565b6102f66123b9565b6102f660015481565b6102eb610612366004612f28565b612440565b61033c6125b6565b61065d6040518060400160405280601081526020017f4d564d5f53757065724d616e6167657200000000000000000000000000000000815250610bff565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610704576040805162461bcd60e51b81526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e60648201526084015b60405180910390fd5b61070c611df3565b6040517fbc052576000000000000000000000000000000000000000000000000000000008152600481018590526024810184905264ffffffffff198316604482015273ffffffffffffffffffffffffffffffffffffffff919091169063bc05257690606401600060405180830381600087803b15801561078b57600080fd5b505af115801561079f573d6000803e3d6000fd5b5050604080513381526020810187905290810185905264ffffffffff19841660608201527fe3b4c53eef322c0bb4aba4dae151a0cd9c381d45db311cbe6ffe8a47806bca9a925060800190505b60405180910390a1505050565b6108376040518060400160405280601081526020017f4d564d5f53757065724d616e6167657200000000000000000000000000000000815250610bff565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146108d9576040805162461bcd60e51b81526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e60648201526084016106fb565b6108e1611df3565b6040517fe6e436c0000000000000000000000000000000000000000000000000000000008152600481018590526024810184905264ffffffffff198316604482015273ffffffffffffffffffffffffffffffffffffffff919091169063e6e436c090606401600060405180830381600087803b15801561096057600080fd5b505af1158015610974573d6000803e3d6000fd5b5050604080513381526020810187905290810185905264ffffffffff19841660608201527fdaa76f618a31042f0705fdcf560ac258420fd56e1202be8a1d3faa236d530e89925060800190506107ec565b60006109cf611df3565b6040517f67d18b9b000000000000000000000000000000000000000000000000000000008152600481018590526024810184905273ffffffffffffffffffffffffffffffffffffffff91909116906367d18b9b9060440160206040518083038186803b158015610a3e57600080fd5b505afa158015610a52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a76919061322b565b9392505050565b604080516060810182526000808252602082018190529181019190915261044060005260066020527ff2fadc8f281df3b2e312450efbc7e5145e4214fc70e639a3a1b10148ef5697af805483908110610ad857610ad8613244565b6000918252602091829020604080516060810182526002909302909101805483526001015464ffffffffff808216948401949094526501000000000090049092169181019190915292915050565b6000610b30611df3565b73ffffffffffffffffffffffffffffffffffffffff1663576f2588836040518263ffffffff1660e01b8152600401610b6a91815260200190565b60206040518083038186803b158015610b8257600080fd5b505afa158015610b96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bba919061322b565b92915050565b600080610bcb612618565b50949350505050565b6000818152600560209081526040808320546006909252822054610bba9164ffffffffff16906132a2565b600080546040517fbf40fac100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063bf40fac190610c56908590600401613342565b60206040518083038186803b158015610c6e57600080fd5b505afa158015610c82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bba9190613355565b600080610cb2836126d3565b9695505050505050565b610cfa6040518060400160405280601081526020017f4d564d5f53757065724d616e6167657200000000000000000000000000000000815250610bff565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d9c576040805162461bcd60e51b81526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e60648201526084016106fb565b6000838152600660205260409020805482919084908110610dbf57610dbf613244565b90600052602060002090600202018181610dd99190613385565b9050507f5a3965b29b524ca11ad9115cbeff6477733f21383a7d5220aa3bd535ea116eb6338484846040516107ec949392919061343f565b610e3260405180606001604052806021815260200161375f60219139610bff565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610ed25760405162461bcd60e51b815260206004820152602b60248201527f6f6e6c79207468652063726f737320646f6d61696e206d657373656e6765722060448201527f63616e20656e717565756500000000000000000000000000000000000000000060648201526084016106fb565b61c35081511115610f4b5760405162461bcd60e51b815260206004820152603d60248201527f5472616e73616374696f6e20646174612073697a652065786365656473206d6160448201527f78696d756d20666f7220726f6c6c7570207472616e73616374696f6e2e00000060648201526084016106fb565b600454821115610fc35760405162461bcd60e51b815260206004820152603d60248201527f5472616e73616374696f6e20676173206c696d69742065786365656473206d6160448201527f78696d756d20666f7220726f6c6c7570207472616e73616374696f6e2e00000060648201526084016106fb565b620186a082101561103c5760405162461bcd60e51b815260206004820152602960248201527f5472616e73616374696f6e20676173206c696d697420746f6f206c6f7720746f60448201527f20656e71756575652e000000000000000000000000000000000000000000000060648201526084016106fb565b60003332141561104d575033611066565b5033731111000000000000000000000000000000001111015b60008185858560405160200161107f9493929190613477565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012060008a8152600680845284822060608701865283875264ffffffffff4281168887019081524382169789019788528254600181810185558487528887209a516002909202909a01908155905190890180549851831665010000000000027fffffffffffffffffffffffffffffffffffffffffffff000000000000000000009099169190921617969096179095558b8252909252915491935091611157916134b6565b9050808673ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f6afbb2eaf0241302d1ab6244dff35383c745f31ee1f878e9052d510baeb425068a8989426040516111bd94939291906134cd565b60405180910390a450505050505050565b6000806111d9612618565b95945050505050565b6112206040518060400160405280601081526020017f4d564d5f53757065724d616e6167657200000000000000000000000000000000815250610bff565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146112c2576040805162461bcd60e51b81526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e60648201526084016106fb565b6112ca611df3565b6040517f4cd4d76900000000000000000000000000000000000000000000000000000000815260048101859052602481018490526044810183905273ffffffffffffffffffffffffffffffffffffffff9190911690634cd4d76990606401600060405180830381600087803b15801561134257600080fd5b505af1158015611356573d6000803e3d6000fd5b50506040805133815260208101879052908101859052606081018490527fd7503502091a493b0a762f4ddf6bb0854a3b7b9e3955f186226d2fabc94bf7a1925060800190506107ec565b6113ae610440848484610e11565b505050565b60006113bd611df3565b73ffffffffffffffffffffffffffffffffffffffff166324a49415836040518263ffffffff1660e01b81526004016113f791815260200190565b60206040518083038186803b15801561140f57600080fd5b505afa158015611423573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bba91906134fd565b600080611452612618565b50505064ffffffffff1692915050565b60008061146e836126d3565b50505064ffffffffff169392505050565b60008061148b836126d3565b5095945050505050565b6114d36040518060400160405280601081526020017f4d564d5f53757065724d616e6167657200000000000000000000000000000000815250610bff565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611575576040805162461bcd60e51b81526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e60648201526084016106fb565b61157d611df3565b6040517f24d722440000000000000000000000000000000000000000000000000000000081526004810184905264ffffffffff198316602482015273ffffffffffffffffffffffffffffffffffffffff91909116906324d7224490604401600060405180830381600087803b1580156115f557600080fd5b505af1158015611609573d6000803e3d6000fd5b5050604080513381526020810186905264ffffffffff198516918101919091527fdbc6a2a2ec9c0d9fd8fe896da2050bcea6b51cbc50d6108ec57ba994144cc21a925060600190505b60405180910390a15050565b6040805160608101825260008082526020820181905291810191909152600083815260066020526040902080548390811061169b5761169b613244565b6000918252602091829020604080516060810182526002909302909101805483526001015464ffffffffff8082169484019490945265010000000000900490921691810191909152905092915050565b60043560243560d81c60293560e890811c90602c35901c61170b84611462565b8364ffffffffff16146117865760405162461bcd60e51b815260206004820152603d60248201527f41637475616c20626174636820737461727420696e64657820646f6573206e6f60448201527f74206d6174636820657870656374656420737461727420696e6465782e00000060648201526084016106fb565b6117b66117928561279c565b6040516020016117a2919061351a565b604051602081830303815290604052610bff565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146118565760405162461bcd60e51b815260206004820152602d60248201527f46756e6374696f6e2063616e206f6e6c792062652063616c6c6564206279207460448201527f68652053657175656e6365722e0000000000000000000000000000000000000060648201526084016106fb565b60008162ffffff16116118d15760405162461bcd60e51b815260206004820152602860248201527f4d7573742070726f76696465206174206c65617374206f6e652062617463682060448201527f636f6e746578742e00000000000000000000000000000000000000000000000060648201526084016106fb565b60008262ffffff161161194c5760405162461bcd60e51b815260206004820152602160248201527f4d75737420617070656e64206174206c65617374206f6e6520656c656d656e7460448201527f2e0000000000000000000000000000000000000000000000000000000000000060648201526084016106fb565b600061195e62ffffff8316601061355b565b61196990600f613598565b905064ffffffffff81163610156119e85760405162461bcd60e51b815260206004820152602260248201527f4e6f7420656e6f756768204261746368436f6e74657874732070726f7669646560448201527f642e00000000000000000000000000000000000000000000000000000000000060648201526084016106fb565b60008581526005602090815260408083205481516080810183528481529283018490529082018390526060820183905264ffffffffff16919060005b8562ffffff168163ffffffff161015611a85576000611a4b60008b8463ffffffff166128f0565b8051909350839150611a5d90856135b0565b9350826020015185611a6f91906135d8565b9450508080611a7d906135f8565b915050611a24565b5060008881526006602052604090205464ffffffffff84161115611b375760405162461bcd60e51b815260206004820152604260248201527f417474656d7074656420746f20617070656e64206d6f726520656c656d656e7460448201527f73207468616e2061726520617661696c61626c6520696e20746865207175657560648201527f652e000000000000000000000000000000000000000000000000000000000000608482015260a4016106fb565b6000611b488362ffffff891661361c565b63ffffffff169050600080836020015160001415611b7157505060408201516060830151611bec565b60008b8152600660205260408120611b8a6001896132a2565b64ffffffffff1681548110611ba157611ba1613244565b6000918252602091829020604080516060810182526002909302909101805483526001015464ffffffffff808216948401859052650100000000009091041691018190529093509150505b611c118b611bfb6001436134b6565b408b62ffffff168664ffffffffff16868661298e565b7f178ecbc4b986ebf7ea68a0a7ae593212f963053458fda23484ad60e95dde758d8b611c3d85896132a2565b85611c478f611462565b604051611c75949392919093845264ffffffffff928316602085015291166040830152606082015260800190565b60405180910390a15050506000978852505060056020526040909520805464ffffffffff191664ffffffffff9096169590951790945550505050565b611cef6040518060400160405280601081526020017f4d564d5f53757065724d616e6167657200000000000000000000000000000000815250610bff565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611d91576040805162461bcd60e51b81526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e60648201526084016106fb565b6000828152600660209081526040822080546001810182559083529120829160020201611dbe8282613385565b50507f56afa4f6505f4a309504be105b887cb40789cdeea8e108f671d00e2ae07f3dcd33838360405161165293929190613639565b6000611e1660405180606001604052806021815260200161378060219139610bff565b905090565b60043560d81c60093560e890811c90600c35901c611e37611447565b8364ffffffffff1614611eb25760405162461bcd60e51b815260206004820152603d60248201527f41637475616c20626174636820737461727420696e64657820646f6573206e6f60448201527f74206d6174636820657870656374656420737461727420696e6465782e00000060648201526084016106fb565b611ef06040518060400160405280600d81526020017f4f564d5f53657175656e63657200000000000000000000000000000000000000815250610bff565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611f905760405162461bcd60e51b815260206004820152602d60248201527f46756e6374696f6e2063616e206f6e6c792062652063616c6c6564206279207460448201527f68652053657175656e6365722e0000000000000000000000000000000000000060648201526084016106fb565b6000611fa262ffffff8316601061355b565b611fad90600f613598565b905064ffffffffff811636101561202c5760405162461bcd60e51b815260206004820152602260248201527f4e6f7420656e6f756768204261746368436f6e74657874732070726f7669646560448201527f642e00000000000000000000000000000000000000000000000000000000000060648201526084016106fb565b6104406000908152600560209081527f0dc7af05b69860904321737f972990978ada95ccab9945c9e4152a2706ab5886546040805160808101825284815292830184905282018390526060820183905264ffffffffff169060005b8562ffffff168163ffffffff1610156120e55760006120ab8263ffffffff16612bd2565b80519093508391506120bd90866135b0565b94508260200151846120cf91906135d8565b93505080806120dd906135f8565b915050612087565b5061044060005260066020527ff2fadc8f281df3b2e312450efbc7e5145e4214fc70e639a3a1b10148ef5697af5464ffffffffff831611156121b55760405162461bcd60e51b815260206004820152604260248201527f417474656d7074656420746f20617070656e64206d6f726520656c656d656e7460448201527f73207468616e2061726520617661696c61626c6520696e20746865207175657560648201527f652e000000000000000000000000000000000000000000000000000000000000608482015260a4016106fb565b60006121c68462ffffff891661361c565b63ffffffff1690506000808360200151600014156121ef5750506040820151606083015161228a565b610440600090815260066020527ff2fadc8f281df3b2e312450efbc7e5145e4214fc70e639a3a1b10148ef5697af6122286001886132a2565b64ffffffffff168154811061223f5761223f613244565b6000918252602091829020604080516060810182526002909302909101805483526001015464ffffffffff808216948401859052650100000000009091041691018190529093509150505b6122ae6122986001436134b6565b408a62ffffff168564ffffffffff168585612c59565b7f178ecbc4b986ebf7ea68a0a7ae593212f963053458fda23484ad60e95dde758d6122d984876132a2565b846122e2611447565b6040805164ffffffffff948516815293909216602084015290820152610440606082015260800160405180910390a15050610440600052505060056020527f0dc7af05b69860904321737f972990978ada95ccab9945c9e4152a2706ab5886805464ffffffffff191664ffffffffff929092169190911790555050505050565b60008061236e836126d3565b509095945050505050565b6000611e166040518060400160405280601f81526020017f436861696e53746f72616765436f6e7461696e65722d4354432d717565756500815250610bff565b60006123c3611df3565b73ffffffffffffffffffffffffffffffffffffffff16631f7b6d326040518163ffffffff1660e01b815260040160206040518083038186803b15801561240857600080fd5b505afa15801561241c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e16919061322b565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156124a657600080fd5b505afa1580156124ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124de9190613355565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146125585760405162461bcd60e51b815260206004820181905260248201527f4f6e6c792063616c6c61626c6520627920746865204275726e2041646d696e2e60448201526064016106fb565b6001819055600282905561256c818361355b565b60038190556002546001546040805192835260208301919091528101919091527fc6ed75e96b8b18b71edc1a6e82a9d677f8268c774a262c624eeb2cf0a8b3e07e90606001611652565b61044060009081527f0dc7af05b69860904321737f972990978ada95ccab9945c9e4152a2706ab58865460066020527ff2fadc8f281df3b2e312450efbc7e5145e4214fc70e639a3a1b10148ef5697af54611e169164ffffffffff16906132a2565b6000806000806000612628611df3565b73ffffffffffffffffffffffffffffffffffffffff1663ccf8f9696040518163ffffffff1660e01b815260040160206040518083038186803b15801561266d57600080fd5b505afa158015612681573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126a591906134fd565b64ffffffffff602882901c811697605083901c82169750607883901c8216965060a09290921c169350915050565b60008060008060006126e3611df3565b73ffffffffffffffffffffffffffffffffffffffff166324a49415876040518263ffffffff1660e01b815260040161271d91815260200190565b60206040518083038186803b15801561273557600080fd5b505afa158015612749573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061276d91906134fd565b64ffffffffff602882901c811698605083901c82169850607883901c8216975060a09290921c16945092505050565b6060816127dc57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561280657806127f08161366a565b91506127ff9050600a836136a3565b91506127e0565b60008167ffffffffffffffff81111561282157612821612f4a565b6040519080825280601f01601f19166020018201604052801561284b576020820181803683370190505b509050815b8515610bcb576128616001826134b6565b90506000612870600a886136a3565b61287b90600a61355b565b61288590886134b6565b6128909060306136de565b905060008160f81b9050808484815181106128ad576128ad613244565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506128e7600a896136a3565b97505050612850565b61291b6040518060800160405280600081526020016000815260200160008152602001600081525090565b600061292860108461355b565b612933866020613598565b61293e90600f613598565b6129489190613598565b60408051608081018252823560e890811c82526003840135901c6020820152600683013560d890811c92820192909252600b90920135901c606082015295945050505050565b6000612998611df3565b90506000806129a6896126d3565b50506040805160a08101918290527f576f25880000000000000000000000000000000000000000000000000000000090915260a481018c905291935091506000908073ffffffffffffffffffffffffffffffffffffffff861663576f258860c4830160206040518083038186803b158015612a2057600080fd5b505afa158015612a34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a58919061322b565b81526020018a81526020018981526020018464ffffffffff16815260200160405180602001604052806000815250815250905080600001517fc4c3b7c157dc7d495c3ed62df83a8b8d6bdf6724d0cc0150228eba4976c4e3318b8360200151846040015185606001518660800151604051612ad7959493929190613703565b60405180910390a26000612aea82612e5b565b90506000612b2c8c846040015187612b0291906135d8565b612b0c8c886135d8565b8b8b602883811b8517605084901b17607883901b17901b95945050505050565b6040517fe6e436c0000000000000000000000000000000000000000000000000000000008152600481018e90526024810184905264ffffffffff198216604482015290915073ffffffffffffffffffffffffffffffffffffffff87169063e6e436c090606401600060405180830381600087803b158015612bac57600080fd5b505af1158015612bc0573d6000803e3d6000fd5b50505050505050505050505050505050565b612bfd6040518060800160405280600081526020016000815260200160008152602001600081525090565b6000612c0a60108461355b565b612c1590600f613598565b60408051608081018252823560e890811c82526003840135901c6020820152600683013560d890811c92820192909252600b90920135901c60608201529392505050565b6000612c63611df3565b9050600080612c70612618565b50509150915060006040518060a001604052808573ffffffffffffffffffffffffffffffffffffffff16631f7b6d326040518163ffffffff1660e01b815260040160206040518083038186803b158015612cc957600080fd5b505afa158015612cdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d01919061322b565b81526020018a81526020018981526020018464ffffffffff16815260200160405180602001604052806000815250815250905080600001517fc4c3b7c157dc7d495c3ed62df83a8b8d6bdf6724d0cc0150228eba4976c4e3316104408360200151846040015185606001518660800151604051612d82959493929190613703565b60405180910390a26000612d9582612e5b565b90506000612dbd836040015186612dac91906135d8565b612db68b876135d8565b8a8a612ea1565b6040517f2015276c0000000000000000000000000000000000000000000000000000000081526004810184905264ffffffffff198216602482015290915073ffffffffffffffffffffffffffffffffffffffff871690632015276c90604401600060405180830381600087803b158015612e3657600080fd5b505af1158015612e4a573d6000803e3d6000fd5b505050505050505050505050505050565b60008160200151826040015183606001518460800151604051602001612e849493929190613739565b604051602081830303815290604052805190602001209050919050565b602883811b8517605084901b17607883901b17901b5b949350505050565b64ffffffffff1981168114612ed357600080fd5b50565b600080600060608486031215612eeb57600080fd5b83359250602084013591506040840135612f0481612ebf565b809150509250925092565b600060208284031215612f2157600080fd5b5035919050565b60008060408385031215612f3b57600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600067ffffffffffffffff80841115612f9457612f94612f4a565b604051601f85017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715612fda57612fda612f4a565b81604052809350858152868686011115612ff357600080fd5b858560208301376000602087830101525050509392505050565b60006020828403121561301f57600080fd5b813567ffffffffffffffff81111561303657600080fd5b8201601f8101841361304757600080fd5b612eb784823560208401612f79565b60006060828403121561306857600080fd5b50919050565b600080600060a0848603121561308357600080fd5b833592506020840135915061309b8560408601613056565b90509250925092565b73ffffffffffffffffffffffffffffffffffffffff81168114612ed357600080fd5b600082601f8301126130d757600080fd5b610a7683833560208501612f79565b600080600080608085870312156130fc57600080fd5b84359350602085013561310e816130a4565b925060408501359150606085013567ffffffffffffffff81111561313157600080fd5b61313d878288016130c6565b91505092959194509250565b60008060006060848603121561315e57600080fd5b505081359360208301359350604090920135919050565b60008060006060848603121561318a57600080fd5b8335613195816130a4565b925060208401359150604084013567ffffffffffffffff8111156131b857600080fd5b6131c4868287016130c6565b9150509250925092565b600080604083850312156131e157600080fd5b8235915060208301356131f381612ebf565b809150509250929050565b6000806080838503121561321157600080fd5b823591506132228460208501613056565b90509250929050565b60006020828403121561323d57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600064ffffffffff838116908316818110156132c0576132c0613273565b039392505050565b60005b838110156132e35781810151838201526020016132cb565b838111156132f2576000848401525b50505050565b600081518084526133108160208601602086016132c8565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610a7660208301846132f8565b60006020828403121561336757600080fd5b8151610a76816130a4565b64ffffffffff81168114612ed357600080fd5b8135815560018101602083013561339b81613372565b64ffffffffff8116905081548164ffffffffff19821617835560408501356133c281613372565b69ffffffffff00000000008160281b16837fffffffffffffffffffffffffffffffffffffffffffff00000000000000000000841617178455505050505050565b80358252602081013561341481613372565b64ffffffffff908116602084015260408201359061343182613372565b808216604085015250505050565b73ffffffffffffffffffffffffffffffffffffffff85168152602081018490526040810183905260c081016111d96060830184613402565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525083604083015260806060830152610cb260808301846132f8565b6000828210156134c8576134c8613273565b500390565b8481528360208201526080604082015260006134ec60808301856132f8565b905082606083015295945050505050565b60006020828403121561350f57600080fd5b8151610a7681612ebf565b6000825161352c8184602087016132c8565b7f5f4d564d5f53657175656e636572000000000000000000000000000000000000920191825250600e01919050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561359357613593613273565b500290565b600082198211156135ab576135ab613273565b500190565b600063ffffffff8083168185168083038211156135cf576135cf613273565b01949350505050565b600064ffffffffff8083168185168083038211156135cf576135cf613273565b600063ffffffff8083168181141561361257613612613273565b6001019392505050565b600063ffffffff838116908316818110156132c0576132c0613273565b73ffffffffffffffffffffffffffffffffffffffff841681526020810183905260a08101612eb76040830184613402565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561369c5761369c613273565b5060010190565b6000826136d9577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600060ff821660ff84168060ff038211156136fb576136fb613273565b019392505050565b85815284602082015283604082015282606082015260a06080820152600061372e60a08301846132f8565b979650505050505050565b848152836020820152826040820152608060608201526000610cb260808301846132f856fe50726f78795f5f4f564d5f4c3143726f7373446f6d61696e4d657373656e676572436861696e53746f72616765436f6e7461696e65722d4354432d62617463686573a2646970667358221220df9778683a9e46dcef3453d175eb075bd3a4c460e10a0a8e5f77102875b70f1364736f6c63430008090033000000000000000000000000918778e825747a892b17c66fe7d24c618262867d000000000000000000000000000000000000000000000000000000004190ab000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000ea60
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102d35760003560e01c80637a209b9311610186578063b4be51ae116100e3578063db29772211610097578063e654b1fb11610071578063e654b1fb146105fb578063edcc4a4514610604578063f722b41a1461061757600080fd5b8063db297722146105d8578063e10d29ee146105eb578063e561dddc146105f357600080fd5b8063ccf987c8116100c8578063ccf987c8146105bf578063cfdf677e146105c8578063d0f89344146105d057600080fd5b8063b4be51ae1461057a578063b8f770051461058d57600080fd5b80638d38c6c11161013a578063a14420ee1161011f578063a14420ee1461054c578063a16d359a1461055f578063a8cda37b1461057257600080fd5b80638d38c6c1146105305780639156f18a1461053957600080fd5b8063876ed5cb1161016b578063876ed5cb146105145780638a52e6221461051d5780638c7de742146103ee57600080fd5b80637a209b93146104e25780637aa63a861461050c57600080fd5b8063461a4478116102345780635bbbb7ed116101e85780636fee07e0116101cd5780636fee07e01461048c57806378f4b2f21461049f5780637a167a8a146104a957600080fd5b80635bbbb7ed1461047057806363d5dbd11461047957600080fd5b80634f5da7c6116102195780634f5da7c614610442578063511da531146104555780635ae6256d1461046857600080fd5b8063461a44781461041c5780634a0eddab1461042f57600080fd5b8063299ca4781161028b5780632de6a708116102705780632de6a708146103ee578063378997701461040157806343be0a841461040957600080fd5b8063299ca478146103655780632a7f18be146103aa57600080fd5b806319625535116102bc57806319625535146103095780632538f3a81461031c57806325412c841461035257600080fd5b80630545ba77146102d85780630b3dfa97146102ed575b600080fd5b6102eb6102e6366004612ed6565b61061f565b005b6102f660035481565b6040519081526020015b60405180910390f35b6102eb610317366004612ed6565b6107f9565b61033c61032a366004612f0f565b60009081526006602052604090205490565b60405164ffffffffff9091168152602001610300565b6102f6610360366004612f28565b6109c5565b6000546103859073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610300565b6103bd6103b8366004612f0f565b610a7d565b604080518251815260208084015164ffffffffff908116918301919091529282015190921690820152606001610300565b6102f66103fc366004612f0f565b610b26565b61033c610bc0565b61033c610417366004612f0f565b610bd4565b61038561042a36600461300d565b610bff565b61033c61043d366004612f0f565b610ca6565b6102eb61045036600461306e565b610cbc565b6102eb6104633660046130e6565b610e11565b61033c6111ce565b6102f661044081565b6102eb610487366004613149565b6111e2565b6102eb61049a366004613175565b6113a0565b6102f6620186a081565b61044060005260056020527f0dc7af05b69860904321737f972990978ada95ccab9945c9e4152a2706ab58865464ffffffffff1661033c565b6104f56104f0366004612f0f565b6113b3565b60405164ffffffffff199091168152602001610300565b6102f6611447565b6102f661c35081565b6102f661052b366004612f0f565b611462565b6102f660045481565b61033c610547366004612f0f565b61147f565b6102eb61055a3660046131ce565b611495565b6103bd61056d366004612f28565b61165e565b6102eb6116eb565b6102eb6105883660046131fe565b611cb1565b61044060005260066020527ff2fadc8f281df3b2e312450efbc7e5145e4214fc70e639a3a1b10148ef5697af5461033c565b6102f660025481565b610385611df3565b6102eb611e1b565b61033c6105e6366004612f0f565b612362565b610385612379565b6102f66123b9565b6102f660015481565b6102eb610612366004612f28565b612440565b61033c6125b6565b61065d6040518060400160405280601081526020017f4d564d5f53757065724d616e6167657200000000000000000000000000000000815250610bff565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610704576040805162461bcd60e51b81526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e60648201526084015b60405180910390fd5b61070c611df3565b6040517fbc052576000000000000000000000000000000000000000000000000000000008152600481018590526024810184905264ffffffffff198316604482015273ffffffffffffffffffffffffffffffffffffffff919091169063bc05257690606401600060405180830381600087803b15801561078b57600080fd5b505af115801561079f573d6000803e3d6000fd5b5050604080513381526020810187905290810185905264ffffffffff19841660608201527fe3b4c53eef322c0bb4aba4dae151a0cd9c381d45db311cbe6ffe8a47806bca9a925060800190505b60405180910390a1505050565b6108376040518060400160405280601081526020017f4d564d5f53757065724d616e6167657200000000000000000000000000000000815250610bff565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146108d9576040805162461bcd60e51b81526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e60648201526084016106fb565b6108e1611df3565b6040517fe6e436c0000000000000000000000000000000000000000000000000000000008152600481018590526024810184905264ffffffffff198316604482015273ffffffffffffffffffffffffffffffffffffffff919091169063e6e436c090606401600060405180830381600087803b15801561096057600080fd5b505af1158015610974573d6000803e3d6000fd5b5050604080513381526020810187905290810185905264ffffffffff19841660608201527fdaa76f618a31042f0705fdcf560ac258420fd56e1202be8a1d3faa236d530e89925060800190506107ec565b60006109cf611df3565b6040517f67d18b9b000000000000000000000000000000000000000000000000000000008152600481018590526024810184905273ffffffffffffffffffffffffffffffffffffffff91909116906367d18b9b9060440160206040518083038186803b158015610a3e57600080fd5b505afa158015610a52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a76919061322b565b9392505050565b604080516060810182526000808252602082018190529181019190915261044060005260066020527ff2fadc8f281df3b2e312450efbc7e5145e4214fc70e639a3a1b10148ef5697af805483908110610ad857610ad8613244565b6000918252602091829020604080516060810182526002909302909101805483526001015464ffffffffff808216948401949094526501000000000090049092169181019190915292915050565b6000610b30611df3565b73ffffffffffffffffffffffffffffffffffffffff1663576f2588836040518263ffffffff1660e01b8152600401610b6a91815260200190565b60206040518083038186803b158015610b8257600080fd5b505afa158015610b96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bba919061322b565b92915050565b600080610bcb612618565b50949350505050565b6000818152600560209081526040808320546006909252822054610bba9164ffffffffff16906132a2565b600080546040517fbf40fac100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063bf40fac190610c56908590600401613342565b60206040518083038186803b158015610c6e57600080fd5b505afa158015610c82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bba9190613355565b600080610cb2836126d3565b9695505050505050565b610cfa6040518060400160405280601081526020017f4d564d5f53757065724d616e6167657200000000000000000000000000000000815250610bff565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d9c576040805162461bcd60e51b81526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e60648201526084016106fb565b6000838152600660205260409020805482919084908110610dbf57610dbf613244565b90600052602060002090600202018181610dd99190613385565b9050507f5a3965b29b524ca11ad9115cbeff6477733f21383a7d5220aa3bd535ea116eb6338484846040516107ec949392919061343f565b610e3260405180606001604052806021815260200161375f60219139610bff565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610ed25760405162461bcd60e51b815260206004820152602b60248201527f6f6e6c79207468652063726f737320646f6d61696e206d657373656e6765722060448201527f63616e20656e717565756500000000000000000000000000000000000000000060648201526084016106fb565b61c35081511115610f4b5760405162461bcd60e51b815260206004820152603d60248201527f5472616e73616374696f6e20646174612073697a652065786365656473206d6160448201527f78696d756d20666f7220726f6c6c7570207472616e73616374696f6e2e00000060648201526084016106fb565b600454821115610fc35760405162461bcd60e51b815260206004820152603d60248201527f5472616e73616374696f6e20676173206c696d69742065786365656473206d6160448201527f78696d756d20666f7220726f6c6c7570207472616e73616374696f6e2e00000060648201526084016106fb565b620186a082101561103c5760405162461bcd60e51b815260206004820152602960248201527f5472616e73616374696f6e20676173206c696d697420746f6f206c6f7720746f60448201527f20656e71756575652e000000000000000000000000000000000000000000000060648201526084016106fb565b60003332141561104d575033611066565b5033731111000000000000000000000000000000001111015b60008185858560405160200161107f9493929190613477565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012060008a8152600680845284822060608701865283875264ffffffffff4281168887019081524382169789019788528254600181810185558487528887209a516002909202909a01908155905190890180549851831665010000000000027fffffffffffffffffffffffffffffffffffffffffffff000000000000000000009099169190921617969096179095558b8252909252915491935091611157916134b6565b9050808673ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f6afbb2eaf0241302d1ab6244dff35383c745f31ee1f878e9052d510baeb425068a8989426040516111bd94939291906134cd565b60405180910390a450505050505050565b6000806111d9612618565b95945050505050565b6112206040518060400160405280601081526020017f4d564d5f53757065724d616e6167657200000000000000000000000000000000815250610bff565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146112c2576040805162461bcd60e51b81526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e60648201526084016106fb565b6112ca611df3565b6040517f4cd4d76900000000000000000000000000000000000000000000000000000000815260048101859052602481018490526044810183905273ffffffffffffffffffffffffffffffffffffffff9190911690634cd4d76990606401600060405180830381600087803b15801561134257600080fd5b505af1158015611356573d6000803e3d6000fd5b50506040805133815260208101879052908101859052606081018490527fd7503502091a493b0a762f4ddf6bb0854a3b7b9e3955f186226d2fabc94bf7a1925060800190506107ec565b6113ae610440848484610e11565b505050565b60006113bd611df3565b73ffffffffffffffffffffffffffffffffffffffff166324a49415836040518263ffffffff1660e01b81526004016113f791815260200190565b60206040518083038186803b15801561140f57600080fd5b505afa158015611423573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bba91906134fd565b600080611452612618565b50505064ffffffffff1692915050565b60008061146e836126d3565b50505064ffffffffff169392505050565b60008061148b836126d3565b5095945050505050565b6114d36040518060400160405280601081526020017f4d564d5f53757065724d616e6167657200000000000000000000000000000000815250610bff565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611575576040805162461bcd60e51b81526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e60648201526084016106fb565b61157d611df3565b6040517f24d722440000000000000000000000000000000000000000000000000000000081526004810184905264ffffffffff198316602482015273ffffffffffffffffffffffffffffffffffffffff91909116906324d7224490604401600060405180830381600087803b1580156115f557600080fd5b505af1158015611609573d6000803e3d6000fd5b5050604080513381526020810186905264ffffffffff198516918101919091527fdbc6a2a2ec9c0d9fd8fe896da2050bcea6b51cbc50d6108ec57ba994144cc21a925060600190505b60405180910390a15050565b6040805160608101825260008082526020820181905291810191909152600083815260066020526040902080548390811061169b5761169b613244565b6000918252602091829020604080516060810182526002909302909101805483526001015464ffffffffff8082169484019490945265010000000000900490921691810191909152905092915050565b60043560243560d81c60293560e890811c90602c35901c61170b84611462565b8364ffffffffff16146117865760405162461bcd60e51b815260206004820152603d60248201527f41637475616c20626174636820737461727420696e64657820646f6573206e6f60448201527f74206d6174636820657870656374656420737461727420696e6465782e00000060648201526084016106fb565b6117b66117928561279c565b6040516020016117a2919061351a565b604051602081830303815290604052610bff565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146118565760405162461bcd60e51b815260206004820152602d60248201527f46756e6374696f6e2063616e206f6e6c792062652063616c6c6564206279207460448201527f68652053657175656e6365722e0000000000000000000000000000000000000060648201526084016106fb565b60008162ffffff16116118d15760405162461bcd60e51b815260206004820152602860248201527f4d7573742070726f76696465206174206c65617374206f6e652062617463682060448201527f636f6e746578742e00000000000000000000000000000000000000000000000060648201526084016106fb565b60008262ffffff161161194c5760405162461bcd60e51b815260206004820152602160248201527f4d75737420617070656e64206174206c65617374206f6e6520656c656d656e7460448201527f2e0000000000000000000000000000000000000000000000000000000000000060648201526084016106fb565b600061195e62ffffff8316601061355b565b61196990600f613598565b905064ffffffffff81163610156119e85760405162461bcd60e51b815260206004820152602260248201527f4e6f7420656e6f756768204261746368436f6e74657874732070726f7669646560448201527f642e00000000000000000000000000000000000000000000000000000000000060648201526084016106fb565b60008581526005602090815260408083205481516080810183528481529283018490529082018390526060820183905264ffffffffff16919060005b8562ffffff168163ffffffff161015611a85576000611a4b60008b8463ffffffff166128f0565b8051909350839150611a5d90856135b0565b9350826020015185611a6f91906135d8565b9450508080611a7d906135f8565b915050611a24565b5060008881526006602052604090205464ffffffffff84161115611b375760405162461bcd60e51b815260206004820152604260248201527f417474656d7074656420746f20617070656e64206d6f726520656c656d656e7460448201527f73207468616e2061726520617661696c61626c6520696e20746865207175657560648201527f652e000000000000000000000000000000000000000000000000000000000000608482015260a4016106fb565b6000611b488362ffffff891661361c565b63ffffffff169050600080836020015160001415611b7157505060408201516060830151611bec565b60008b8152600660205260408120611b8a6001896132a2565b64ffffffffff1681548110611ba157611ba1613244565b6000918252602091829020604080516060810182526002909302909101805483526001015464ffffffffff808216948401859052650100000000009091041691018190529093509150505b611c118b611bfb6001436134b6565b408b62ffffff168664ffffffffff16868661298e565b7f178ecbc4b986ebf7ea68a0a7ae593212f963053458fda23484ad60e95dde758d8b611c3d85896132a2565b85611c478f611462565b604051611c75949392919093845264ffffffffff928316602085015291166040830152606082015260800190565b60405180910390a15050506000978852505060056020526040909520805464ffffffffff191664ffffffffff9096169590951790945550505050565b611cef6040518060400160405280601081526020017f4d564d5f53757065724d616e6167657200000000000000000000000000000000815250610bff565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611d91576040805162461bcd60e51b81526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e60648201526084016106fb565b6000828152600660209081526040822080546001810182559083529120829160020201611dbe8282613385565b50507f56afa4f6505f4a309504be105b887cb40789cdeea8e108f671d00e2ae07f3dcd33838360405161165293929190613639565b6000611e1660405180606001604052806021815260200161378060219139610bff565b905090565b60043560d81c60093560e890811c90600c35901c611e37611447565b8364ffffffffff1614611eb25760405162461bcd60e51b815260206004820152603d60248201527f41637475616c20626174636820737461727420696e64657820646f6573206e6f60448201527f74206d6174636820657870656374656420737461727420696e6465782e00000060648201526084016106fb565b611ef06040518060400160405280600d81526020017f4f564d5f53657175656e63657200000000000000000000000000000000000000815250610bff565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611f905760405162461bcd60e51b815260206004820152602d60248201527f46756e6374696f6e2063616e206f6e6c792062652063616c6c6564206279207460448201527f68652053657175656e6365722e0000000000000000000000000000000000000060648201526084016106fb565b6000611fa262ffffff8316601061355b565b611fad90600f613598565b905064ffffffffff811636101561202c5760405162461bcd60e51b815260206004820152602260248201527f4e6f7420656e6f756768204261746368436f6e74657874732070726f7669646560448201527f642e00000000000000000000000000000000000000000000000000000000000060648201526084016106fb565b6104406000908152600560209081527f0dc7af05b69860904321737f972990978ada95ccab9945c9e4152a2706ab5886546040805160808101825284815292830184905282018390526060820183905264ffffffffff169060005b8562ffffff168163ffffffff1610156120e55760006120ab8263ffffffff16612bd2565b80519093508391506120bd90866135b0565b94508260200151846120cf91906135d8565b93505080806120dd906135f8565b915050612087565b5061044060005260066020527ff2fadc8f281df3b2e312450efbc7e5145e4214fc70e639a3a1b10148ef5697af5464ffffffffff831611156121b55760405162461bcd60e51b815260206004820152604260248201527f417474656d7074656420746f20617070656e64206d6f726520656c656d656e7460448201527f73207468616e2061726520617661696c61626c6520696e20746865207175657560648201527f652e000000000000000000000000000000000000000000000000000000000000608482015260a4016106fb565b60006121c68462ffffff891661361c565b63ffffffff1690506000808360200151600014156121ef5750506040820151606083015161228a565b610440600090815260066020527ff2fadc8f281df3b2e312450efbc7e5145e4214fc70e639a3a1b10148ef5697af6122286001886132a2565b64ffffffffff168154811061223f5761223f613244565b6000918252602091829020604080516060810182526002909302909101805483526001015464ffffffffff808216948401859052650100000000009091041691018190529093509150505b6122ae6122986001436134b6565b408a62ffffff168564ffffffffff168585612c59565b7f178ecbc4b986ebf7ea68a0a7ae593212f963053458fda23484ad60e95dde758d6122d984876132a2565b846122e2611447565b6040805164ffffffffff948516815293909216602084015290820152610440606082015260800160405180910390a15050610440600052505060056020527f0dc7af05b69860904321737f972990978ada95ccab9945c9e4152a2706ab5886805464ffffffffff191664ffffffffff929092169190911790555050505050565b60008061236e836126d3565b509095945050505050565b6000611e166040518060400160405280601f81526020017f436861696e53746f72616765436f6e7461696e65722d4354432d717565756500815250610bff565b60006123c3611df3565b73ffffffffffffffffffffffffffffffffffffffff16631f7b6d326040518163ffffffff1660e01b815260040160206040518083038186803b15801561240857600080fd5b505afa15801561241c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e16919061322b565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156124a657600080fd5b505afa1580156124ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124de9190613355565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146125585760405162461bcd60e51b815260206004820181905260248201527f4f6e6c792063616c6c61626c6520627920746865204275726e2041646d696e2e60448201526064016106fb565b6001819055600282905561256c818361355b565b60038190556002546001546040805192835260208301919091528101919091527fc6ed75e96b8b18b71edc1a6e82a9d677f8268c774a262c624eeb2cf0a8b3e07e90606001611652565b61044060009081527f0dc7af05b69860904321737f972990978ada95ccab9945c9e4152a2706ab58865460066020527ff2fadc8f281df3b2e312450efbc7e5145e4214fc70e639a3a1b10148ef5697af54611e169164ffffffffff16906132a2565b6000806000806000612628611df3565b73ffffffffffffffffffffffffffffffffffffffff1663ccf8f9696040518163ffffffff1660e01b815260040160206040518083038186803b15801561266d57600080fd5b505afa158015612681573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126a591906134fd565b64ffffffffff602882901c811697605083901c82169750607883901c8216965060a09290921c169350915050565b60008060008060006126e3611df3565b73ffffffffffffffffffffffffffffffffffffffff166324a49415876040518263ffffffff1660e01b815260040161271d91815260200190565b60206040518083038186803b15801561273557600080fd5b505afa158015612749573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061276d91906134fd565b64ffffffffff602882901c811698605083901c82169850607883901c8216975060a09290921c16945092505050565b6060816127dc57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561280657806127f08161366a565b91506127ff9050600a836136a3565b91506127e0565b60008167ffffffffffffffff81111561282157612821612f4a565b6040519080825280601f01601f19166020018201604052801561284b576020820181803683370190505b509050815b8515610bcb576128616001826134b6565b90506000612870600a886136a3565b61287b90600a61355b565b61288590886134b6565b6128909060306136de565b905060008160f81b9050808484815181106128ad576128ad613244565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506128e7600a896136a3565b97505050612850565b61291b6040518060800160405280600081526020016000815260200160008152602001600081525090565b600061292860108461355b565b612933866020613598565b61293e90600f613598565b6129489190613598565b60408051608081018252823560e890811c82526003840135901c6020820152600683013560d890811c92820192909252600b90920135901c606082015295945050505050565b6000612998611df3565b90506000806129a6896126d3565b50506040805160a08101918290527f576f25880000000000000000000000000000000000000000000000000000000090915260a481018c905291935091506000908073ffffffffffffffffffffffffffffffffffffffff861663576f258860c4830160206040518083038186803b158015612a2057600080fd5b505afa158015612a34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a58919061322b565b81526020018a81526020018981526020018464ffffffffff16815260200160405180602001604052806000815250815250905080600001517fc4c3b7c157dc7d495c3ed62df83a8b8d6bdf6724d0cc0150228eba4976c4e3318b8360200151846040015185606001518660800151604051612ad7959493929190613703565b60405180910390a26000612aea82612e5b565b90506000612b2c8c846040015187612b0291906135d8565b612b0c8c886135d8565b8b8b602883811b8517605084901b17607883901b17901b95945050505050565b6040517fe6e436c0000000000000000000000000000000000000000000000000000000008152600481018e90526024810184905264ffffffffff198216604482015290915073ffffffffffffffffffffffffffffffffffffffff87169063e6e436c090606401600060405180830381600087803b158015612bac57600080fd5b505af1158015612bc0573d6000803e3d6000fd5b50505050505050505050505050505050565b612bfd6040518060800160405280600081526020016000815260200160008152602001600081525090565b6000612c0a60108461355b565b612c1590600f613598565b60408051608081018252823560e890811c82526003840135901c6020820152600683013560d890811c92820192909252600b90920135901c60608201529392505050565b6000612c63611df3565b9050600080612c70612618565b50509150915060006040518060a001604052808573ffffffffffffffffffffffffffffffffffffffff16631f7b6d326040518163ffffffff1660e01b815260040160206040518083038186803b158015612cc957600080fd5b505afa158015612cdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d01919061322b565b81526020018a81526020018981526020018464ffffffffff16815260200160405180602001604052806000815250815250905080600001517fc4c3b7c157dc7d495c3ed62df83a8b8d6bdf6724d0cc0150228eba4976c4e3316104408360200151846040015185606001518660800151604051612d82959493929190613703565b60405180910390a26000612d9582612e5b565b90506000612dbd836040015186612dac91906135d8565b612db68b876135d8565b8a8a612ea1565b6040517f2015276c0000000000000000000000000000000000000000000000000000000081526004810184905264ffffffffff198216602482015290915073ffffffffffffffffffffffffffffffffffffffff871690632015276c90604401600060405180830381600087803b158015612e3657600080fd5b505af1158015612e4a573d6000803e3d6000fd5b505050505050505050505050505050565b60008160200151826040015183606001518460800151604051602001612e849493929190613739565b604051602081830303815290604052805190602001209050919050565b602883811b8517605084901b17607883901b17901b5b949350505050565b64ffffffffff1981168114612ed357600080fd5b50565b600080600060608486031215612eeb57600080fd5b83359250602084013591506040840135612f0481612ebf565b809150509250925092565b600060208284031215612f2157600080fd5b5035919050565b60008060408385031215612f3b57600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600067ffffffffffffffff80841115612f9457612f94612f4a565b604051601f85017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715612fda57612fda612f4a565b81604052809350858152868686011115612ff357600080fd5b858560208301376000602087830101525050509392505050565b60006020828403121561301f57600080fd5b813567ffffffffffffffff81111561303657600080fd5b8201601f8101841361304757600080fd5b612eb784823560208401612f79565b60006060828403121561306857600080fd5b50919050565b600080600060a0848603121561308357600080fd5b833592506020840135915061309b8560408601613056565b90509250925092565b73ffffffffffffffffffffffffffffffffffffffff81168114612ed357600080fd5b600082601f8301126130d757600080fd5b610a7683833560208501612f79565b600080600080608085870312156130fc57600080fd5b84359350602085013561310e816130a4565b925060408501359150606085013567ffffffffffffffff81111561313157600080fd5b61313d878288016130c6565b91505092959194509250565b60008060006060848603121561315e57600080fd5b505081359360208301359350604090920135919050565b60008060006060848603121561318a57600080fd5b8335613195816130a4565b925060208401359150604084013567ffffffffffffffff8111156131b857600080fd5b6131c4868287016130c6565b9150509250925092565b600080604083850312156131e157600080fd5b8235915060208301356131f381612ebf565b809150509250929050565b6000806080838503121561321157600080fd5b823591506132228460208501613056565b90509250929050565b60006020828403121561323d57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600064ffffffffff838116908316818110156132c0576132c0613273565b039392505050565b60005b838110156132e35781810151838201526020016132cb565b838111156132f2576000848401525b50505050565b600081518084526133108160208601602086016132c8565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610a7660208301846132f8565b60006020828403121561336757600080fd5b8151610a76816130a4565b64ffffffffff81168114612ed357600080fd5b8135815560018101602083013561339b81613372565b64ffffffffff8116905081548164ffffffffff19821617835560408501356133c281613372565b69ffffffffff00000000008160281b16837fffffffffffffffffffffffffffffffffffffffffffff00000000000000000000841617178455505050505050565b80358252602081013561341481613372565b64ffffffffff908116602084015260408201359061343182613372565b808216604085015250505050565b73ffffffffffffffffffffffffffffffffffffffff85168152602081018490526040810183905260c081016111d96060830184613402565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525083604083015260806060830152610cb260808301846132f8565b6000828210156134c8576134c8613273565b500390565b8481528360208201526080604082015260006134ec60808301856132f8565b905082606083015295945050505050565b60006020828403121561350f57600080fd5b8151610a7681612ebf565b6000825161352c8184602087016132c8565b7f5f4d564d5f53657175656e636572000000000000000000000000000000000000920191825250600e01919050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561359357613593613273565b500290565b600082198211156135ab576135ab613273565b500190565b600063ffffffff8083168185168083038211156135cf576135cf613273565b01949350505050565b600064ffffffffff8083168185168083038211156135cf576135cf613273565b600063ffffffff8083168181141561361257613612613273565b6001019392505050565b600063ffffffff838116908316818110156132c0576132c0613273565b73ffffffffffffffffffffffffffffffffffffffff841681526020810183905260a08101612eb76040830184613402565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561369c5761369c613273565b5060010190565b6000826136d9577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600060ff821660ff84168060ff038211156136fb576136fb613273565b019392505050565b85815284602082015283604082015282606082015260a06080820152600061372e60a08301846132f8565b979650505050505050565b848152836020820152826040820152608060608201526000610cb260808301846132f856fe50726f78795f5f4f564d5f4c3143726f7373446f6d61696e4d657373656e676572436861696e53746f72616765436f6e7461696e65722d4354432d62617463686573a2646970667358221220df9778683a9e46dcef3453d175eb075bd3a4c460e10a0a8e5f77102875b70f1364736f6c63430008090033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000918778e825747a892b17c66fe7d24c618262867d000000000000000000000000000000000000000000000000000000004190ab000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000ea60
-----Decoded View---------------
Arg [0] : _libAddressManager (address): 0x918778e825747a892b17C66fe7D24C618262867d
Arg [1] : _maxTransactionGasLimit (uint256): 1100000000
Arg [2] : _l2GasDiscountDivisor (uint256): 32
Arg [3] : _enqueueGasCost (uint256): 60000
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000918778e825747a892b17c66fe7d24c618262867d
Arg [1] : 000000000000000000000000000000000000000000000000000000004190ab00
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000020
Arg [3] : 000000000000000000000000000000000000000000000000000000000000ea60
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.