Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 321 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Append State Bat... | 12411256 | 1374 days ago | IN | 0 ETH | 0.02546897 | ||||
Append State Bat... | 12410697 | 1374 days ago | IN | 0 ETH | 0.05002667 | ||||
Append State Bat... | 12410189 | 1374 days ago | IN | 0 ETH | 0.03655828 | ||||
Append State Bat... | 12409673 | 1374 days ago | IN | 0 ETH | 0.04118212 | ||||
Append State Bat... | 12409192 | 1374 days ago | IN | 0 ETH | 0.04372934 | ||||
Append State Bat... | 12408577 | 1374 days ago | IN | 0 ETH | 0.08125458 | ||||
Append State Bat... | 12405320 | 1375 days ago | IN | 0 ETH | 0.01332008 | ||||
Append State Bat... | 12404740 | 1375 days ago | IN | 0 ETH | 0.0186851 | ||||
Append State Bat... | 12404216 | 1375 days ago | IN | 0 ETH | 0.01705819 | ||||
Append State Bat... | 12403650 | 1375 days ago | IN | 0 ETH | 0.0158346 | ||||
Append State Bat... | 12403110 | 1375 days ago | IN | 0 ETH | 0.01568908 | ||||
Append State Bat... | 12402576 | 1375 days ago | IN | 0 ETH | 0.01484864 | ||||
Append State Bat... | 12402015 | 1375 days ago | IN | 0 ETH | 0.0161443 | ||||
Append State Bat... | 12401488 | 1375 days ago | IN | 0 ETH | 0.01595244 | ||||
Append State Bat... | 12400972 | 1375 days ago | IN | 0 ETH | 0.01576085 | ||||
Append State Bat... | 12400415 | 1375 days ago | IN | 0 ETH | 0.01671924 | ||||
Append State Bat... | 12399905 | 1375 days ago | IN | 0 ETH | 0.01115904 | ||||
Append State Bat... | 12399333 | 1376 days ago | IN | 0 ETH | 0.01462347 | ||||
Append State Bat... | 12398820 | 1376 days ago | IN | 0 ETH | 0.01567666 | ||||
Append State Bat... | 12398251 | 1376 days ago | IN | 0 ETH | 0.019529 | ||||
Append State Bat... | 12397710 | 1376 days ago | IN | 0 ETH | 0.03291734 | ||||
Append State Bat... | 12397152 | 1376 days ago | IN | 0 ETH | 0.01994403 | ||||
Append State Bat... | 12396613 | 1376 days ago | IN | 0 ETH | 0.02367362 | ||||
Append State Bat... | 12396215 | 1376 days ago | IN | 0 ETH | 0.02063381 | ||||
Append State Bat... | 12395533 | 1376 days ago | IN | 0 ETH | 0.04663986 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
OVM_StateCommitmentChain
Compiler Version
v0.7.6+commit.7338295f
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity >0.5.0 <0.8.0; pragma experimental ABIEncoderV2; /* Library Imports */ import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol"; import { Lib_AddressResolver } from "../../libraries/resolver/Lib_AddressResolver.sol"; import { Lib_MerkleTree } from "../../libraries/utils/Lib_MerkleTree.sol"; /* Interface Imports */ import { iOVM_FraudVerifier } from "../../iOVM/verification/iOVM_FraudVerifier.sol"; import { iOVM_StateCommitmentChain } from "../../iOVM/chain/iOVM_StateCommitmentChain.sol"; import { iOVM_CanonicalTransactionChain } from "../../iOVM/chain/iOVM_CanonicalTransactionChain.sol"; import { iOVM_BondManager } from "../../iOVM/verification/iOVM_BondManager.sol"; import { iOVM_ChainStorageContainer } from "../../iOVM/chain/iOVM_ChainStorageContainer.sol"; /* External Imports */ import '@openzeppelin/contracts/math/SafeMath.sol'; /** * @title OVM_StateCommitmentChain * @dev The State Commitment Chain (SCC) contract contains a list of proposed state roots which * Proposers assert to be a result of each transaction in the Canonical Transaction Chain (CTC). * Elements here have a 1:1 correspondence with transactions in the CTC, and should be the unique * state root calculated off-chain by applying the canonical transactions one by one. * * Compiler used: solc * Runtime target: EVM */ contract OVM_StateCommitmentChain is iOVM_StateCommitmentChain, Lib_AddressResolver { /************* * Constants * *************/ uint256 public FRAUD_PROOF_WINDOW; uint256 public SEQUENCER_PUBLISH_WINDOW; /*************** * Constructor * ***************/ /** * @param _libAddressManager Address of the Address Manager. */ constructor( address _libAddressManager, uint256 _fraudProofWindow, uint256 _sequencerPublishWindow ) Lib_AddressResolver(_libAddressManager) { FRAUD_PROOF_WINDOW = _fraudProofWindow; SEQUENCER_PUBLISH_WINDOW = _sequencerPublishWindow; } /******************** * Public Functions * ********************/ /** * Accesses the batch storage container. * @return Reference to the batch storage container. */ function batches() public view returns ( iOVM_ChainStorageContainer ) { return iOVM_ChainStorageContainer( resolve("OVM_ChainStorageContainer:SCC:batches") ); } /** * @inheritdoc iOVM_StateCommitmentChain */ function getTotalElements() override public view returns ( uint256 _totalElements ) { (uint40 totalElements, ) = _getBatchExtraData(); return uint256(totalElements); } /** * @inheritdoc iOVM_StateCommitmentChain */ function getTotalBatches() override public view returns ( uint256 _totalBatches ) { return batches().length(); } /** * @inheritdoc iOVM_StateCommitmentChain */ function getLastSequencerTimestamp() override public view returns ( uint256 _lastSequencerTimestamp ) { (, uint40 lastSequencerTimestamp) = _getBatchExtraData(); return uint256(lastSequencerTimestamp); } /** * @inheritdoc iOVM_StateCommitmentChain */ function appendStateBatch( bytes32[] memory _batch, uint256 _shouldStartAtElement ) override public { // Fail fast in to make sure our batch roots aren't accidentally made fraudulent by the // publication of batches by some other user. require( _shouldStartAtElement == getTotalElements(), "Actual batch start index does not match expected start index." ); // Proposers must have previously staked at the BondManager require( iOVM_BondManager(resolve("OVM_BondManager")).isCollateralized(msg.sender), "Proposer does not have enough collateral posted" ); require( _batch.length > 0, "Cannot submit an empty state batch." ); require( getTotalElements() + _batch.length <= iOVM_CanonicalTransactionChain(resolve("OVM_CanonicalTransactionChain")).getTotalElements(), "Number of state roots cannot exceed the number of canonical transactions." ); // Pass the block's timestamp and the publisher of the data // to be used in the fraud proofs _appendBatch( _batch, abi.encode(block.timestamp, msg.sender) ); } /** * @inheritdoc iOVM_StateCommitmentChain */ function deleteStateBatch( Lib_OVMCodec.ChainBatchHeader memory _batchHeader ) override public { require( msg.sender == resolve("OVM_FraudVerifier"), "State batches can only be deleted by the OVM_FraudVerifier." ); require( _isValidBatchHeader(_batchHeader), "Invalid batch header." ); require( insideFraudProofWindow(_batchHeader), "State batches can only be deleted within the fraud proof window." ); _deleteBatch(_batchHeader); } /** * @inheritdoc iOVM_StateCommitmentChain */ function verifyStateCommitment( bytes32 _element, Lib_OVMCodec.ChainBatchHeader memory _batchHeader, Lib_OVMCodec.ChainInclusionProof memory _proof ) override public view returns ( bool ) { require( _isValidBatchHeader(_batchHeader), "Invalid batch header." ); require( Lib_MerkleTree.verify( _batchHeader.batchRoot, _element, _proof.index, _proof.siblings, _batchHeader.batchSize ), "Invalid inclusion proof." ); return true; } /** * @inheritdoc iOVM_StateCommitmentChain */ function insideFraudProofWindow( Lib_OVMCodec.ChainBatchHeader memory _batchHeader ) override public view returns ( bool _inside ) { (uint256 timestamp,) = abi.decode( _batchHeader.extraData, (uint256, address) ); require( timestamp != 0, "Batch header timestamp cannot be zero" ); return SafeMath.add(timestamp, FRAUD_PROOF_WINDOW) > block.timestamp; } /********************** * Internal Functions * **********************/ /** * Parses the batch context from the extra data. * @return Total number of elements submitted. * @return Timestamp of the last batch submitted by the sequencer. */ function _getBatchExtraData() internal view returns ( uint40, uint40 ) { bytes27 extraData = batches().getGlobalMetadata(); uint40 totalElements; uint40 lastSequencerTimestamp; assembly { extraData := shr(40, extraData) totalElements := and(extraData, 0x000000000000000000000000000000000000000000000000000000FFFFFFFFFF) lastSequencerTimestamp := shr(40, and(extraData, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000)) } return ( totalElements, lastSequencerTimestamp ); } /** * Encodes the batch context for the extra data. * @param _totalElements Total number of elements submitted. * @param _lastSequencerTimestamp Timestamp of the last batch submitted by the sequencer. * @return Encoded batch context. */ function _makeBatchExtraData( uint40 _totalElements, uint40 _lastSequencerTimestamp ) internal pure returns ( bytes27 ) { bytes27 extraData; assembly { extraData := _totalElements extraData := or(extraData, shl(40, _lastSequencerTimestamp)) extraData := shl(40, extraData) } return extraData; } /** * Appends a batch to the chain. * @param _batch Elements within the batch. * @param _extraData Any extra data to append to the batch. */ function _appendBatch( bytes32[] memory _batch, bytes memory _extraData ) internal { address sequencer = resolve("OVM_Proposer"); (uint40 totalElements, uint40 lastSequencerTimestamp) = _getBatchExtraData(); if (msg.sender == sequencer) { lastSequencerTimestamp = uint40(block.timestamp); } else { // We keep track of the last batch submitted by the sequencer so there's a window in // which only the sequencer can publish state roots. A window like this just reduces // the chance of "system breaking" state roots being published while we're still in // testing mode. This window should be removed or significantly reduced in the future. require( lastSequencerTimestamp + SEQUENCER_PUBLISH_WINDOW < block.timestamp, "Cannot publish state roots within the sequencer publication window." ); } // For efficiency reasons getMerkleRoot modifies the `_batch` argument in place // while calculating the root hash therefore any arguments passed to it must not // be used again afterwards Lib_OVMCodec.ChainBatchHeader memory batchHeader = Lib_OVMCodec.ChainBatchHeader({ batchIndex: getTotalBatches(), batchRoot: Lib_MerkleTree.getMerkleRoot(_batch), batchSize: _batch.length, prevTotalElements: totalElements, extraData: _extraData }); emit StateBatchAppended( batchHeader.batchIndex, batchHeader.batchRoot, batchHeader.batchSize, batchHeader.prevTotalElements, batchHeader.extraData ); batches().push( Lib_OVMCodec.hashBatchHeader(batchHeader), _makeBatchExtraData( uint40(batchHeader.prevTotalElements + batchHeader.batchSize), lastSequencerTimestamp ) ); } /** * Removes a batch and all subsequent batches from the chain. * @param _batchHeader Header of the batch to remove. */ function _deleteBatch( Lib_OVMCodec.ChainBatchHeader memory _batchHeader ) internal { require( _batchHeader.batchIndex < batches().length(), "Invalid batch index." ); require( _isValidBatchHeader(_batchHeader), "Invalid batch header." ); batches().deleteElementsAfterInclusive( _batchHeader.batchIndex, _makeBatchExtraData( uint40(_batchHeader.prevTotalElements), 0 ) ); emit StateBatchDeleted( _batchHeader.batchIndex, _batchHeader.batchRoot ); } /** * Checks that a batch header matches the stored hash for the given index. * @param _batchHeader Batch header to validate. * @return Whether or not the header matches the stored one. */ function _isValidBatchHeader( Lib_OVMCodec.ChainBatchHeader memory _batchHeader ) internal view returns ( bool ) { return Lib_OVMCodec.hashBatchHeader(_batchHeader) == batches().get(_batchHeader.batchIndex); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) return 0; uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a % b; } }
// SPDX-License-Identifier: MIT pragma solidity >0.5.0 <0.8.0; pragma experimental ABIEncoderV2; /* Library Imports */ import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol"; /* Interface Imports */ import { iOVM_ChainStorageContainer } from "./iOVM_ChainStorageContainer.sol"; /** * @title iOVM_CanonicalTransactionChain */ interface iOVM_CanonicalTransactionChain { /********** * Events * **********/ event TransactionEnqueued( address _l1TxOrigin, address _target, uint256 _gasLimit, bytes _data, uint256 _queueIndex, uint256 _timestamp ); event QueueBatchAppended( uint256 _startingQueueIndex, uint256 _numQueueElements, uint256 _totalElements ); event SequencerBatchAppended( uint256 _startingQueueIndex, uint256 _numQueueElements, uint256 _totalElements ); event TransactionBatchAppended( uint256 indexed _batchIndex, bytes32 _batchRoot, uint256 _batchSize, uint256 _prevTotalElements, bytes _extraData ); /*********** * Structs * ***********/ struct BatchContext { uint256 numSequencedTransactions; uint256 numSubsequentQueueTransactions; uint256 timestamp; uint256 blockNumber; } /******************** * Public Functions * ********************/ /** * Accesses the batch storage container. * @return Reference to the batch storage container. */ function batches() external view returns ( iOVM_ChainStorageContainer ); /** * Accesses the queue storage container. * @return Reference to the queue storage container. */ function queue() external view returns ( iOVM_ChainStorageContainer ); /** * 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; /** * Appends a given number of queued transactions as a single batch. * @param _numQueuedTransactions Number of transactions to append. */ function appendQueueBatch( uint256 _numQueuedTransactions ) 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; /** * Verifies whether a transaction is included in the chain. * @param _transaction Transaction to verify. * @param _txChainElement Transaction chain element corresponding to the transaction. * @param _batchHeader Header of the batch the transaction was included in. * @param _inclusionProof Inclusion proof for the provided transaction chain element. * @return True if the transaction exists in the CTC, false if not. */ function verifyTransaction( Lib_OVMCodec.Transaction memory _transaction, Lib_OVMCodec.TransactionChainElement memory _txChainElement, Lib_OVMCodec.ChainBatchHeader memory _batchHeader, Lib_OVMCodec.ChainInclusionProof memory _inclusionProof ) external view returns ( bool ); }
// SPDX-License-Identifier: MIT pragma solidity >0.5.0 <0.8.0; /** * @title iOVM_ChainStorageContainer */ interface iOVM_ChainStorageContainer { /******************** * 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; /** * 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; /** * Marks an index as overwritable, meaing the underlying buffer can start to write values over * any objects before and including the given index. */ function setNextOverwritableIndex( uint256 _index ) external; }
// SPDX-License-Identifier: MIT pragma solidity >0.5.0 <0.8.0; pragma experimental ABIEncoderV2; /* Library Imports */ import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol"; /** * @title iOVM_StateCommitmentChain */ interface iOVM_StateCommitmentChain { /********** * Events * **********/ event StateBatchAppended( uint256 indexed _batchIndex, bytes32 _batchRoot, uint256 _batchSize, uint256 _prevTotalElements, bytes _extraData ); event StateBatchDeleted( uint256 indexed _batchIndex, bytes32 _batchRoot ); /******************** * Public Functions * ********************/ /** * 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 ); /** * Retrieves the timestamp of the last batch submitted by the sequencer. * @return _lastSequencerTimestamp Last sequencer batch timestamp. */ function getLastSequencerTimestamp() external view returns ( uint256 _lastSequencerTimestamp ); /** * Appends a batch of state roots to the chain. * @param _batch Batch of state roots. * @param _shouldStartAtElement Index of the element at which this batch should start. */ function appendStateBatch( bytes32[] calldata _batch, uint256 _shouldStartAtElement ) external; /** * Deletes all state roots after (and including) a given batch. * @param _batchHeader Header of the batch to start deleting from. */ function deleteStateBatch( Lib_OVMCodec.ChainBatchHeader memory _batchHeader ) external; /** * Verifies a batch inclusion proof. * @param _element Hash of the element to verify a proof for. * @param _batchHeader Header of the batch in which the element was included. * @param _proof Merkle inclusion proof for the element. */ function verifyStateCommitment( bytes32 _element, Lib_OVMCodec.ChainBatchHeader memory _batchHeader, Lib_OVMCodec.ChainInclusionProof memory _proof ) external view returns ( bool _verified ); /** * Checks whether a given batch is still inside its fraud proof window. * @param _batchHeader Header of the batch to check. * @return _inside Whether or not the batch is inside the fraud proof window. */ function insideFraudProofWindow( Lib_OVMCodec.ChainBatchHeader memory _batchHeader ) external view returns ( bool _inside ); }
// SPDX-License-Identifier: MIT pragma solidity >0.5.0 <0.8.0; interface ERC20 { function transfer(address, uint256) external returns (bool); function transferFrom(address, address, uint256) external returns (bool); } /// All the errors which may be encountered on the bond manager library Errors { string constant ERC20_ERR = "BondManager: Could not post bond"; string constant ALREADY_FINALIZED = "BondManager: Fraud proof for this pre-state root has already been finalized"; string constant SLASHED = "BondManager: Cannot finalize withdrawal, you probably got slashed"; string constant WRONG_STATE = "BondManager: Wrong bond state for proposer"; string constant CANNOT_CLAIM = "BondManager: Cannot claim yet. Dispute must be finalized first"; string constant WITHDRAWAL_PENDING = "BondManager: Withdrawal already pending"; string constant TOO_EARLY = "BondManager: Too early to finalize your withdrawal"; string constant ONLY_TRANSITIONER = "BondManager: Only the transitioner for this pre-state root may call this function"; string constant ONLY_FRAUD_VERIFIER = "BondManager: Only the fraud verifier may call this function"; string constant ONLY_STATE_COMMITMENT_CHAIN = "BondManager: Only the state commitment chain may call this function"; string constant WAIT_FOR_DISPUTES = "BondManager: Wait for other potential disputes"; } /** * @title iOVM_BondManager */ interface iOVM_BondManager { /******************* * Data Structures * *******************/ /// The lifecycle of a proposer's bond enum State { // Before depositing or after getting slashed, a user is uncollateralized NOT_COLLATERALIZED, // After depositing, a user is collateralized COLLATERALIZED, // After a user has initiated a withdrawal WITHDRAWING } /// A bond posted by a proposer struct Bond { // The user's state State state; // The timestamp at which a proposer issued their withdrawal request uint32 withdrawalTimestamp; // The time when the first disputed was initiated for this bond uint256 firstDisputeAt; // The earliest observed state root for this bond which has had fraud bytes32 earliestDisputedStateRoot; // The state root's timestamp uint256 earliestTimestamp; } // Per pre-state root, store the number of state provisions that were made // and how many of these calls were made by each user. Payouts will then be // claimed by users proportionally for that dispute. struct Rewards { // Flag to check if rewards for a fraud proof are claimable bool canClaim; // Total number of `recordGasSpent` calls made uint256 total; // The gas spent by each user to provide witness data. The sum of all // values inside this map MUST be equal to the value of `total` mapping(address => uint256) gasSpent; } /******************** * Public Functions * ********************/ function recordGasSpent( bytes32 _preStateRoot, bytes32 _txHash, address _who, uint256 _gasSpent ) external; function finalize( bytes32 _preStateRoot, address _publisher, uint256 _timestamp ) external; function deposit() external; function startWithdrawal() external; function finalizeWithdrawal() external; function claim( address _who ) external; function isCollateralized( address _who ) external view returns (bool); function getGasSpent( bytes32 _preStateRoot, address _who ) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity >0.5.0 <0.8.0; pragma experimental ABIEncoderV2; /* Library Imports */ import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol"; /* Interface Imports */ import { iOVM_StateTransitioner } from "./iOVM_StateTransitioner.sol"; /** * @title iOVM_FraudVerifier */ interface iOVM_FraudVerifier { /********** * Events * **********/ event FraudProofInitialized( bytes32 _preStateRoot, uint256 _preStateRootIndex, bytes32 _transactionHash, address _who ); event FraudProofFinalized( bytes32 _preStateRoot, uint256 _preStateRootIndex, bytes32 _transactionHash, address _who ); /*************************************** * Public Functions: Transition Status * ***************************************/ function getStateTransitioner(bytes32 _preStateRoot, bytes32 _txHash) external view returns (iOVM_StateTransitioner _transitioner); /**************************************** * Public Functions: Fraud Verification * ****************************************/ function initializeFraudVerification( bytes32 _preStateRoot, Lib_OVMCodec.ChainBatchHeader calldata _preStateRootBatchHeader, Lib_OVMCodec.ChainInclusionProof calldata _preStateRootProof, Lib_OVMCodec.Transaction calldata _transaction, Lib_OVMCodec.TransactionChainElement calldata _txChainElement, Lib_OVMCodec.ChainBatchHeader calldata _transactionBatchHeader, Lib_OVMCodec.ChainInclusionProof calldata _transactionProof ) external; function finalizeFraudVerification( bytes32 _preStateRoot, Lib_OVMCodec.ChainBatchHeader calldata _preStateRootBatchHeader, Lib_OVMCodec.ChainInclusionProof calldata _preStateRootProof, bytes32 _txHash, bytes32 _postStateRoot, Lib_OVMCodec.ChainBatchHeader calldata _postStateRootBatchHeader, Lib_OVMCodec.ChainInclusionProof calldata _postStateRootProof ) external; }
// SPDX-License-Identifier: MIT pragma solidity >0.5.0 <0.8.0; pragma experimental ABIEncoderV2; /* Library Imports */ import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol"; /** * @title iOVM_StateTransitioner */ interface iOVM_StateTransitioner { /********** * Events * **********/ event AccountCommitted( address _address ); event ContractStorageCommitted( address _address, bytes32 _key ); /********************************** * Public Functions: State Access * **********************************/ function getPreStateRoot() external view returns (bytes32 _preStateRoot); function getPostStateRoot() external view returns (bytes32 _postStateRoot); function isComplete() external view returns (bool _complete); /*********************************** * Public Functions: Pre-Execution * ***********************************/ function proveContractState( address _ovmContractAddress, address _ethContractAddress, bytes calldata _stateTrieWitness ) external; function proveStorageSlot( address _ovmContractAddress, bytes32 _key, bytes calldata _storageTrieWitness ) external; /******************************* * Public Functions: Execution * *******************************/ function applyTransaction( Lib_OVMCodec.Transaction calldata _transaction ) external; /************************************ * Public Functions: Post-Execution * ************************************/ function commitContractState( address _ovmContractAddress, bytes calldata _stateTrieWitness ) external; function commitStorageSlot( address _ovmContractAddress, bytes32 _key, bytes calldata _storageTrieWitness ) external; /********************************** * Public Functions: Finalization * **********************************/ function completeTransition() external; }
// SPDX-License-Identifier: MIT pragma solidity >0.5.0 <0.8.0; pragma experimental ABIEncoderV2; /* 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"; import { Lib_SafeExecutionManagerWrapper } from "../../libraries/wrappers/Lib_SafeExecutionManagerWrapper.sol"; /** * @title Lib_OVMCodec */ library Lib_OVMCodec { /********* * Enums * *********/ enum EOASignatureType { EIP155_TRANSACTION, ETH_SIGNED_MESSAGE } enum QueueOrigin { SEQUENCER_QUEUE, L1TOL2_QUEUE } /*********** * Structs * ***********/ struct Account { uint256 nonce; uint256 balance; bytes32 storageRoot; bytes32 codeHash; address ethAddress; bool isFresh; } 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; } struct EIP155Transaction { uint256 nonce; uint256 gasPrice; uint256 gasLimit; address to; uint256 value; bytes data; uint256 chainId; } /********************** * Internal Functions * **********************/ /** * Decodes an EOA transaction (i.e., native Ethereum RLP encoding). * @param _transaction Encoded EOA transaction. * @return Transaction decoded into a struct. */ function decodeEIP155Transaction( bytes memory _transaction, bool _isEthSignedMessage ) internal pure returns ( EIP155Transaction memory ) { if (_isEthSignedMessage) { ( uint256 _nonce, uint256 _gasLimit, uint256 _gasPrice, uint256 _chainId, address _to, bytes memory _data ) = abi.decode( _transaction, (uint256, uint256, uint256, uint256, address ,bytes) ); return EIP155Transaction({ nonce: _nonce, gasPrice: _gasPrice, gasLimit: _gasLimit, to: _to, value: 0, data: _data, chainId: _chainId }); } else { Lib_RLPReader.RLPItem[] memory decoded = Lib_RLPReader.readList(_transaction); return EIP155Transaction({ nonce: Lib_RLPReader.readUint256(decoded[0]), gasPrice: Lib_RLPReader.readUint256(decoded[1]), gasLimit: Lib_RLPReader.readUint256(decoded[2]), to: Lib_RLPReader.readAddress(decoded[3]), value: Lib_RLPReader.readUint256(decoded[4]), data: Lib_RLPReader.readBytes(decoded[5]), chainId: Lib_RLPReader.readUint256(decoded[6]) }); } } /** * Decompresses a compressed EIP155 transaction. * @param _transaction Compressed EIP155 transaction bytes. * @return Transaction parsed into a struct. */ function decompressEIP155Transaction( bytes memory _transaction ) internal returns ( EIP155Transaction memory ) { return EIP155Transaction({ gasLimit: Lib_BytesUtils.toUint24(_transaction, 0), gasPrice: uint256(Lib_BytesUtils.toUint24(_transaction, 3)) * 1000000, nonce: Lib_BytesUtils.toUint24(_transaction, 6), to: Lib_BytesUtils.toAddress(_transaction, 9), data: Lib_BytesUtils.slice(_transaction, 29), chainId: Lib_SafeExecutionManagerWrapper.safeCHAINID(), value: 0 }); } /** * Encodes an EOA transaction back into the original transaction. * @param _transaction EIP155transaction to encode. * @param _isEthSignedMessage Whether or not this was an eth signed message. * @return Encoded transaction. */ function encodeEIP155Transaction( EIP155Transaction memory _transaction, bool _isEthSignedMessage ) internal pure returns ( bytes memory ) { if (_isEthSignedMessage) { return abi.encode( _transaction.nonce, _transaction.gasLimit, _transaction.gasPrice, _transaction.chainId, _transaction.to, _transaction.data ); } else { bytes[] memory raw = new bytes[](9); raw[0] = Lib_RLPWriter.writeUint(_transaction.nonce); raw[1] = Lib_RLPWriter.writeUint(_transaction.gasPrice); raw[2] = Lib_RLPWriter.writeUint(_transaction.gasLimit); if (_transaction.to == address(0)) { raw[3] = Lib_RLPWriter.writeBytes(''); } else { raw[3] = Lib_RLPWriter.writeAddress(_transaction.to); } raw[4] = Lib_RLPWriter.writeUint(0); raw[5] = Lib_RLPWriter.writeBytes(_transaction.data); raw[6] = Lib_RLPWriter.writeUint(_transaction.chainId); raw[7] = Lib_RLPWriter.writeBytes(bytes('')); raw[8] = Lib_RLPWriter.writeBytes(bytes('')); return Lib_RLPWriter.writeList(raw); } } /** * 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)); } /** * Converts an OVM account to an EVM account. * @param _in OVM account to convert. * @return Converted EVM account. */ function toEVMAccount( Account memory _in ) internal pure returns ( EVMAccount memory ) { return EVMAccount({ nonce: _in.nonce, balance: _in.balance, storageRoot: _in.storageRoot, codeHash: _in.codeHash }); } /** * @notice RLP-encodes an account state struct. * @param _account Account state struct. * @return RLP-encoded account state. */ function encodeEVMAccount( EVMAccount memory _account ) internal pure returns ( bytes memory ) { bytes[] memory raw = new bytes[](4); // Unfortunately we can't create this array outright because // Lib_RLPWriter.writeList will reject fixed-size arrays. Assigning // index-by-index circumvents this issue. raw[0] = Lib_RLPWriter.writeBytes( Lib_Bytes32Utils.removeLeadingZeros( bytes32(_account.nonce) ) ); raw[1] = Lib_RLPWriter.writeBytes( Lib_Bytes32Utils.removeLeadingZeros( bytes32(_account.balance) ) ); raw[2] = Lib_RLPWriter.writeBytes(abi.encodePacked(_account.storageRoot)); raw[3] = Lib_RLPWriter.writeBytes(abi.encodePacked(_account.codeHash)); return Lib_RLPWriter.writeList(raw); } /** * @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.5.0 <0.8.0; /* Contract Imports */ import { Ownable } from "./Lib_Ownable.sol"; /** * @title Lib_AddressManager */ contract Lib_AddressManager is Ownable { /********** * Events * **********/ event AddressSet( string _name, address _newAddress ); /******************************************* * Contract Variables: Internal Accounting * *******************************************/ mapping (bytes32 => address) private addresses; /******************** * Public Functions * ********************/ function setAddress( string memory _name, address _address ) public onlyOwner { emit AddressSet(_name, _address); addresses[_getNameHash(_name)] = _address; } function getAddress( string memory _name ) public view returns (address) { return addresses[_getNameHash(_name)]; } /********************** * Internal Functions * **********************/ function _getNameHash( string memory _name ) internal pure returns ( bytes32 _hash ) { return keccak256(abi.encodePacked(_name)); } }
// SPDX-License-Identifier: MIT pragma solidity >0.5.0 <0.8.0; /* Library Imports */ import { Lib_AddressManager } from "./Lib_AddressManager.sol"; /** * @title Lib_AddressResolver */ abstract contract Lib_AddressResolver { /******************************************* * Contract Variables: Contract References * *******************************************/ Lib_AddressManager public libAddressManager; /*************** * Constructor * ***************/ /** * @param _libAddressManager Address of the Lib_AddressManager. */ constructor( address _libAddressManager ) { libAddressManager = Lib_AddressManager(_libAddressManager); } /******************** * Public Functions * ********************/ function resolve( string memory _name ) public view returns ( address _contract ) { return libAddressManager.getAddress(_name); } }
// SPDX-License-Identifier: MIT pragma solidity >0.5.0 <0.8.0; /** * @title Ownable * @dev Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol */ abstract contract Ownable { /************* * Variables * *************/ address public owner; /********** * Events * **********/ event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); /*************** * Constructor * ***************/ constructor() { owner = msg.sender; emit OwnershipTransferred(address(0), owner); } /********************** * Function Modifiers * **********************/ modifier onlyOwner() { require( owner == msg.sender, "Ownable: caller is not the owner" ); _; } /******************** * Public Functions * ********************/ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(owner, address(0)); owner = address(0); } function transferOwnership(address _newOwner) public virtual onlyOwner { require( _newOwner != address(0), "Ownable: new owner cannot be the zero address" ); emit OwnershipTransferred(owner, _newOwner); owner = _newOwner; } }
// SPDX-License-Identifier: MIT pragma solidity >0.5.0 <0.8.0; /** * @title Lib_RLPReader * @dev Adapted from "RLPReader" by Hamdi Allam ([email protected]). */ library Lib_RLPReader { /************* * Constants * *************/ uint256 constant internal 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(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 = 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.5.0 <0.8.0; pragma experimental ABIEncoderV2; /* Library Imports */ import { Lib_BytesUtils } from "../utils/Lib_BytesUtils.sol"; /** * @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 _out The RLP encoded string in bytes. */ function writeBytes( bytes memory _in ) internal pure returns ( bytes memory _out ) { 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 _out The RLP encoded list of items in bytes. */ function writeList( bytes[] memory _in ) internal pure returns ( bytes memory _out ) { bytes memory list = _flatten(_in); return abi.encodePacked(_writeLength(list.length, 192), list); } /** * RLP encodes a string. * @param _in The string to encode. * @return _out The RLP encoded string in bytes. */ function writeString( string memory _in ) internal pure returns ( bytes memory _out ) { return writeBytes(bytes(_in)); } /** * RLP encodes an address. * @param _in The address to encode. * @return _out The RLP encoded address in bytes. */ function writeAddress( address _in ) internal pure returns ( bytes memory _out ) { return writeBytes(abi.encodePacked(_in)); } /** * RLP encodes a uint. * @param _in The uint256 to encode. * @return _out The RLP encoded uint256 in bytes. */ function writeUint( uint256 _in ) internal pure returns ( bytes memory _out ) { return writeBytes(_toBinary(_in)); } /** * RLP encodes a bool. * @param _in The bool to encode. * @return _out The RLP encoded bool in bytes. */ function writeBool( bool _in ) internal pure returns ( bytes memory _out ) { 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 _encoded RLP encoded bytes. */ function _writeLength( uint256 _len, uint256 _offset ) private pure returns ( bytes memory _encoded ) { bytes memory encoded; if (_len < 56) { encoded = new bytes(1); encoded[0] = byte(uint8(_len) + uint8(_offset)); } else { uint256 lenLen; uint256 i = 1; while (_len / i != 0) { lenLen++; i *= 256; } encoded = new bytes(lenLen + 1); encoded[0] = byte(uint8(lenLen) + uint8(_offset) + 55); for(i = 1; i <= lenLen; i++) { encoded[i] = byte(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 _binary RLP encoded bytes. */ function _toBinary( uint256 _x ) private pure returns ( bytes memory _binary ) { 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 = 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 _flattened The flattened byte string. */ function _flatten( bytes[] memory _list ) private pure returns ( bytes memory _flattened ) { 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.5.0 <0.8.0; /** * @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(_in)); } /** * Removes the leading zeros from a bytes32 value and returns a new (smaller) bytes value. * @param _in Input bytes32 value. * @return Bytes32 without any leading zeros. */ function removeLeadingZeros( bytes32 _in ) internal pure returns ( bytes memory ) { bytes memory out; assembly { // Figure out how many leading zero bytes to remove. let shift := 0 for { let i := 0 } and(lt(i, 32), eq(byte(i, _in), 0)) { i := add(i, 1) } { shift := add(shift, 1) } // Reserve some space for our output and fix the free memory pointer. out := mload(0x40) mstore(0x40, add(out, 0x40)) // Shift the value and store it into the output bytes. mstore(add(out, 0x20), shl(mul(shift, 8), _in)) // Store the new size (with leading zero bytes removed) in the output byte size. mstore(out, sub(32, shift)) } return out; } }
// SPDX-License-Identifier: MIT pragma solidity >0.5.0 <0.8.0; /** * @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 (_bytes.length - _start == 0) { return bytes(''); } return slice(_bytes, _start, _bytes.length - _start); } function toBytes32PadLeft( bytes memory _bytes ) internal pure returns (bytes32) { bytes32 ret; uint256 len = _bytes.length <= 32 ? _bytes.length : 32; assembly { ret := shr(mul(sub(32, len), 8), mload(add(_bytes, 32))) } return ret; } 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 toUint24(bytes memory _bytes, uint256 _start) internal pure returns (uint24) { require(_start + 3 >= _start, "toUint24_overflow"); require(_bytes.length >= _start + 3 , "toUint24_outOfBounds"); uint24 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x3), _start)) } return tempUint; } function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) { require(_start + 1 >= _start, "toUint8_overflow"); require(_bytes.length >= _start + 1 , "toUint8_outOfBounds"); uint8 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x1), _start)) } return tempUint; } function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) { require(_start + 20 >= _start, "toAddress_overflow"); require(_bytes.length >= _start + 20, "toAddress_outOfBounds"); address tempAddress; assembly { tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000) } return tempAddress; } 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.5.0 <0.8.0; pragma experimental ABIEncoderV2; /** * @title Lib_ErrorUtils */ library Lib_ErrorUtils { /********************** * Internal Functions * **********************/ /** * Encodes an error string into raw solidity-style revert data. * (i.e. ascii bytes, prefixed with bytes4(keccak("Error(string))")) * Ref: https://docs.soliditylang.org/en/v0.8.2/control-structures.html?highlight=Error(string)#panic-via-assert-and-error-via-require * @param _reason Reason for the reversion. * @return Standard solidity revert data for the given reason. */ function encodeRevertString( string memory _reason ) internal pure returns ( bytes memory ) { return abi.encodeWithSignature( "Error(string)", _reason ); } }
// SPDX-License-Identifier: MIT pragma solidity >0.5.0 <0.8.0; /** * @title Lib_MerkleTree * @author River Keefer */ library Lib_MerkleTree { /********************** * Internal Functions * **********************/ /** * Calculates a merkle root for a list of 32-byte leaf hashes. WARNING: If the number * of leaves passed in is not a power of two, it pads out the tree with zero hashes. * If you do not know the original length of elements for the tree you are verifying, * then this may allow empty leaves past _elements.length to pass a verification check down the line. * Note that the _elements argument is modified, therefore it must not be used again afterwards * @param _elements Array of hashes from which to generate a merkle root. * @return Merkle root of the leaves, with zero hashes for non-powers-of-two (see above). */ function getMerkleRoot( bytes32[] memory _elements ) internal pure returns ( bytes32 ) { require( _elements.length > 0, "Lib_MerkleTree: Must provide at least one leaf hash." ); if (_elements.length == 1) { return _elements[0]; } uint256[16] memory defaults = [ 0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563, 0x633dc4d7da7256660a892f8f1604a44b5432649cc8ec5cb3ced4c4e6ac94dd1d, 0x890740a8eb06ce9be422cb8da5cdafc2b58c0a5e24036c578de2a433c828ff7d, 0x3b8ec09e026fdc305365dfc94e189a81b38c7597b3d941c279f042e8206e0bd8, 0xecd50eee38e386bd62be9bedb990706951b65fe053bd9d8a521af753d139e2da, 0xdefff6d330bb5403f63b14f33b578274160de3a50df4efecf0e0db73bcdd3da5, 0x617bdd11f7c0a11f49db22f629387a12da7596f9d1704d7465177c63d88ec7d7, 0x292c23a9aa1d8bea7e2435e555a4a60e379a5a35f3f452bae60121073fb6eead, 0xe1cea92ed99acdcb045a6726b2f87107e8a61620a232cf4d7d5b5766b3952e10, 0x7ad66c0a68c72cb89e4fb4303841966e4062a76ab97451e3b9fb526a5ceb7f82, 0xe026cc5a4aed3c22a58cbd3d2ac754c9352c5436f638042dca99034e83636516, 0x3d04cffd8b46a874edf5cfae63077de85f849a660426697b06a829c70dd1409c, 0xad676aa337a485e4728a0b240d92b3ef7b3c372d06d189322bfd5f61f1e7203e, 0xa2fca4a49658f9fab7aa63289c91b7c7b6c832a6d0e69334ff5b0a3483d09dab, 0x4ebfd9cd7bca2505f7bef59cc1c12ecc708fff26ae4af19abe852afe9e20c862, 0x2def10d13dd169f550f578bda343d9717a138562e0093b380a1120789d53cf10 ]; // Reserve memory space for our hashes. bytes memory buf = new bytes(64); // We'll need to keep track of left and right siblings. bytes32 leftSibling; bytes32 rightSibling; // Number of non-empty nodes at the current depth. uint256 rowSize = _elements.length; // Current depth, counting from 0 at the leaves uint256 depth = 0; // Common sub-expressions uint256 halfRowSize; // rowSize / 2 bool rowSizeIsOdd; // rowSize % 2 == 1 while (rowSize > 1) { halfRowSize = rowSize / 2; rowSizeIsOdd = rowSize % 2 == 1; for (uint256 i = 0; i < halfRowSize; i++) { leftSibling = _elements[(2 * i) ]; rightSibling = _elements[(2 * i) + 1]; assembly { mstore(add(buf, 32), leftSibling ) mstore(add(buf, 64), rightSibling) } _elements[i] = keccak256(buf); } if (rowSizeIsOdd) { leftSibling = _elements[rowSize - 1]; rightSibling = bytes32(defaults[depth]); assembly { mstore(add(buf, 32), leftSibling) mstore(add(buf, 64), rightSibling) } _elements[halfRowSize] = keccak256(buf); } rowSize = halfRowSize + (rowSizeIsOdd ? 1 : 0); depth++; } return _elements[0]; } /** * Verifies a merkle branch for the given leaf hash. Assumes the original length * of leaves generated is a known, correct input, and does not return true for indices * extending past that index (even if _siblings would be otherwise valid.) * @param _root The Merkle root to verify against. * @param _leaf The leaf hash to verify inclusion of. * @param _index The index in the tree of this leaf. * @param _siblings Array of sibline nodes in the inclusion proof, starting from depth 0 (bottom of the tree). * @param _totalLeaves The total number of leaves originally passed into. * @return Whether or not the merkle branch and leaf passes verification. */ function verify( bytes32 _root, bytes32 _leaf, uint256 _index, bytes32[] memory _siblings, uint256 _totalLeaves ) internal pure returns ( bool ) { require( _totalLeaves > 0, "Lib_MerkleTree: Total leaves must be greater than zero." ); require( _index < _totalLeaves, "Lib_MerkleTree: Index out of bounds." ); require( _siblings.length == _ceilLog2(_totalLeaves), "Lib_MerkleTree: Total siblings does not correctly correspond to total leaves." ); bytes32 computedRoot = _leaf; for (uint256 i = 0; i < _siblings.length; i++) { if ((_index & 1) == 1) { computedRoot = keccak256( abi.encodePacked( _siblings[i], computedRoot ) ); } else { computedRoot = keccak256( abi.encodePacked( computedRoot, _siblings[i] ) ); } _index >>= 1; } return _root == computedRoot; } /********************* * Private Functions * *********************/ /** * Calculates the integer ceiling of the log base 2 of an input. * @param _in Unsigned input to calculate the log. * @return ceil(log_base_2(_in)) */ function _ceilLog2( uint256 _in ) private pure returns ( uint256 ) { require( _in > 0, "Lib_MerkleTree: Cannot compute ceil(log_2) of 0." ); if (_in == 1) { return 0; } // Find the highest set bit (will be floor(log_2)). // Borrowed with <3 from https://github.com/ethereum/solidity-examples uint256 val = _in; uint256 highest = 0; for (uint256 i = 128; i >= 1; i >>= 1) { if (val & (uint(1) << i) - 1 << i != 0) { highest += i; val >>= i; } } // Increment by one if this is not a perfect logarithm. if ((uint(1) << highest) != _in) { highest += 1; } return highest; } }
// SPDX-License-Identifier: MIT pragma solidity >0.5.0 <0.8.0; /* Library Imports */ import { Lib_ErrorUtils } from "../utils/Lib_ErrorUtils.sol"; /** * @title Lib_SafeExecutionManagerWrapper * @dev The Safe Execution Manager Wrapper provides functions which facilitate writing OVM safe * code using the standard solidity compiler, by routing all its operations through the Execution * Manager. * * Compiler used: solc * Runtime target: OVM */ library Lib_SafeExecutionManagerWrapper { /********************** * Internal Functions * **********************/ /** * Performs a safe ovmCALL. * @param _gasLimit Gas limit for the call. * @param _target Address to call. * @param _calldata Data to send to the call. * @return _success Whether or not the call reverted. * @return _returndata Data returned by the call. */ function safeCALL( uint256 _gasLimit, address _target, bytes memory _calldata ) internal returns ( bool _success, bytes memory _returndata ) { bytes memory returndata = _safeExecutionManagerInteraction( abi.encodeWithSignature( "ovmCALL(uint256,address,bytes)", _gasLimit, _target, _calldata ) ); return abi.decode(returndata, (bool, bytes)); } /** * Performs a safe ovmDELEGATECALL. * @param _gasLimit Gas limit for the call. * @param _target Address to call. * @param _calldata Data to send to the call. * @return _success Whether or not the call reverted. * @return _returndata Data returned by the call. */ function safeDELEGATECALL( uint256 _gasLimit, address _target, bytes memory _calldata ) internal returns ( bool _success, bytes memory _returndata ) { bytes memory returndata = _safeExecutionManagerInteraction( abi.encodeWithSignature( "ovmDELEGATECALL(uint256,address,bytes)", _gasLimit, _target, _calldata ) ); return abi.decode(returndata, (bool, bytes)); } /** * Performs a safe ovmCREATE call. * @param _gasLimit Gas limit for the creation. * @param _bytecode Code for the new contract. * @return _contract Address of the created contract. */ function safeCREATE( uint256 _gasLimit, bytes memory _bytecode ) internal returns ( address, bytes memory ) { bytes memory returndata = _safeExecutionManagerInteraction( _gasLimit, abi.encodeWithSignature( "ovmCREATE(bytes)", _bytecode ) ); return abi.decode(returndata, (address, bytes)); } /** * Performs a safe ovmEXTCODESIZE call. * @param _contract Address of the contract to query the size of. * @return _EXTCODESIZE Size of the requested contract in bytes. */ function safeEXTCODESIZE( address _contract ) internal returns ( uint256 _EXTCODESIZE ) { bytes memory returndata = _safeExecutionManagerInteraction( abi.encodeWithSignature( "ovmEXTCODESIZE(address)", _contract ) ); return abi.decode(returndata, (uint256)); } /** * Performs a safe ovmCHAINID call. * @return _CHAINID Result of calling ovmCHAINID. */ function safeCHAINID() internal returns ( uint256 _CHAINID ) { bytes memory returndata = _safeExecutionManagerInteraction( abi.encodeWithSignature( "ovmCHAINID()" ) ); return abi.decode(returndata, (uint256)); } /** * Performs a safe ovmCALLER call. * @return _CALLER Result of calling ovmCALLER. */ function safeCALLER() internal returns ( address _CALLER ) { bytes memory returndata = _safeExecutionManagerInteraction( abi.encodeWithSignature( "ovmCALLER()" ) ); return abi.decode(returndata, (address)); } /** * Performs a safe ovmADDRESS call. * @return _ADDRESS Result of calling ovmADDRESS. */ function safeADDRESS() internal returns ( address _ADDRESS ) { bytes memory returndata = _safeExecutionManagerInteraction( abi.encodeWithSignature( "ovmADDRESS()" ) ); return abi.decode(returndata, (address)); } /** * Performs a safe ovmGETNONCE call. * @return _nonce Result of calling ovmGETNONCE. */ function safeGETNONCE() internal returns ( uint256 _nonce ) { bytes memory returndata = _safeExecutionManagerInteraction( abi.encodeWithSignature( "ovmGETNONCE()" ) ); return abi.decode(returndata, (uint256)); } /** * Performs a safe ovmINCREMENTNONCE call. */ function safeINCREMENTNONCE() internal { _safeExecutionManagerInteraction( abi.encodeWithSignature( "ovmINCREMENTNONCE()" ) ); } /** * Performs a safe ovmCREATEEOA call. * @param _messageHash Message hash which was signed by EOA * @param _v v value of signature (0 or 1) * @param _r r value of signature * @param _s s value of signature */ function safeCREATEEOA( bytes32 _messageHash, uint8 _v, bytes32 _r, bytes32 _s ) internal { _safeExecutionManagerInteraction( abi.encodeWithSignature( "ovmCREATEEOA(bytes32,uint8,bytes32,bytes32)", _messageHash, _v, _r, _s ) ); } /** * Performs a safe REVERT. * @param _reason String revert reason to pass along with the REVERT. */ function safeREVERT( string memory _reason ) internal { _safeExecutionManagerInteraction( abi.encodeWithSignature( "ovmREVERT(bytes)", Lib_ErrorUtils.encodeRevertString( _reason ) ) ); } /** * Performs a safe "require". * @param _condition Boolean condition that must be true or will revert. * @param _reason String revert reason to pass along with the REVERT. */ function safeREQUIRE( bool _condition, string memory _reason ) internal { if (!_condition) { safeREVERT( _reason ); } } /** * Performs a safe ovmSLOAD call. */ function safeSLOAD( bytes32 _key ) internal returns ( bytes32 ) { bytes memory returndata = _safeExecutionManagerInteraction( abi.encodeWithSignature( "ovmSLOAD(bytes32)", _key ) ); return abi.decode(returndata, (bytes32)); } /** * Performs a safe ovmSSTORE call. */ function safeSSTORE( bytes32 _key, bytes32 _value ) internal { _safeExecutionManagerInteraction( abi.encodeWithSignature( "ovmSSTORE(bytes32,bytes32)", _key, _value ) ); } /********************* * Private Functions * *********************/ /** * Performs an ovm interaction and the necessary safety checks. * @param _gasLimit Gas limit for the interaction. * @param _calldata Data to send to the OVM_ExecutionManager (encoded with sighash). * @return _returndata Data sent back by the OVM_ExecutionManager. */ function _safeExecutionManagerInteraction( uint256 _gasLimit, bytes memory _calldata ) private returns ( bytes memory _returndata ) { address ovmExecutionManager = msg.sender; ( bool success, bytes memory returndata ) = ovmExecutionManager.call{gas: _gasLimit}(_calldata); if (success == false) { assembly { revert(add(returndata, 0x20), mload(returndata)) } } else if (returndata.length == 1) { assembly { return(0, 1) } } else { return returndata; } } function _safeExecutionManagerInteraction( bytes memory _calldata ) private returns ( bytes memory _returndata ) { return _safeExecutionManagerInteraction( gasleft(), _calldata ); } }
{ "evmVersion": "istanbul", "libraries": {}, "metadata": { "bytecodeHash": "none", "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 200 }, "remappings": [], "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_libAddressManager","type":"address"},{"internalType":"uint256","name":"_fraudProofWindow","type":"uint256"},{"internalType":"uint256","name":"_sequencerPublishWindow","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"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":"StateBatchAppended","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_batchIndex","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"_batchRoot","type":"bytes32"}],"name":"StateBatchDeleted","type":"event"},{"inputs":[],"name":"FRAUD_PROOF_WINDOW","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SEQUENCER_PUBLISH_WINDOW","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_batch","type":"bytes32[]"},{"internalType":"uint256","name":"_shouldStartAtElement","type":"uint256"}],"name":"appendStateBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"batches","outputs":[{"internalType":"contract iOVM_ChainStorageContainer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"batchIndex","type":"uint256"},{"internalType":"bytes32","name":"batchRoot","type":"bytes32"},{"internalType":"uint256","name":"batchSize","type":"uint256"},{"internalType":"uint256","name":"prevTotalElements","type":"uint256"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"internalType":"struct Lib_OVMCodec.ChainBatchHeader","name":"_batchHeader","type":"tuple"}],"name":"deleteStateBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getLastSequencerTimestamp","outputs":[{"internalType":"uint256","name":"_lastSequencerTimestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalBatches","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":[{"components":[{"internalType":"uint256","name":"batchIndex","type":"uint256"},{"internalType":"bytes32","name":"batchRoot","type":"bytes32"},{"internalType":"uint256","name":"batchSize","type":"uint256"},{"internalType":"uint256","name":"prevTotalElements","type":"uint256"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"internalType":"struct Lib_OVMCodec.ChainBatchHeader","name":"_batchHeader","type":"tuple"}],"name":"insideFraudProofWindow","outputs":[{"internalType":"bool","name":"_inside","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"libAddressManager","outputs":[{"internalType":"contract Lib_AddressManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"}],"name":"resolve","outputs":[{"internalType":"address","name":"_contract","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_element","type":"bytes32"},{"components":[{"internalType":"uint256","name":"batchIndex","type":"uint256"},{"internalType":"bytes32","name":"batchRoot","type":"bytes32"},{"internalType":"uint256","name":"batchSize","type":"uint256"},{"internalType":"uint256","name":"prevTotalElements","type":"uint256"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"internalType":"struct Lib_OVMCodec.ChainBatchHeader","name":"_batchHeader","type":"tuple"},{"components":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"bytes32[]","name":"siblings","type":"bytes32[]"}],"internalType":"struct Lib_OVMCodec.ChainInclusionProof","name":"_proof","type":"tuple"}],"name":"verifyStateCommitment","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50604051611bc5380380611bc583398101604081905261002f9161005b565b600080546001600160a01b0319166001600160a01b03949094169390931790925560015560025561009c565b60008060006060848603121561006f578283fd5b83516001600160a01b0381168114610085578384fd5b602085015160409095015190969495509392505050565b611b1a806100ab6000396000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c80638ca5cbb9116100715780638ca5cbb91461012f5780639418bddd14610144578063b8e189ac14610157578063c17b291b1461016a578063cfdf677e14610172578063e561dddc1461017a576100b4565b8063299ca478146100b9578063461a4478146100d75780634d69ee57146100ea5780637aa63a861461010a5780637ad168a01461011f57806381eb62ef14610127575b600080fd5b6100c1610182565b6040516100ce919061159f565b60405180910390f35b6100c16100e53660046114e3565b610191565b6100fd6100f8366004611431565b61026f565b6040516100ce91906115b3565b6101126102e2565b6040516100ce91906115be565b6101126102fb565b610112610314565b61014261013d366004611390565b61031a565b005b6100fd610152366004611531565b61052e565b610142610165366004611531565b61057e565b610112610636565b6100c161063c565b610112610664565b6000546001600160a01b031681565b6000805460405163bf40fac160e01b81526020600482018181528551602484015285516001600160a01b039094169363bf40fac19387938392604490920191908501908083838b5b838110156101f15781810151838201526020016101d9565b50505050905090810190601f16801561021e5780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b15801561023b57600080fd5b505afa15801561024f573d6000803e3d6000fd5b505050506040513d602081101561026557600080fd5b505190505b919050565b600061027a836106de565b61029f5760405162461bcd60e51b815260040161029690611749565b60405180910390fd5b6102bc836020015185846000015185602001518760400151610776565b6102d85760405162461bcd60e51b8152600401610296906116b5565b5060019392505050565b6000806102ed6108fb565b5064ffffffffff1691505090565b6000806103066108fb565b64ffffffffff169250505090565b60025481565b6103226102e2565b81146103405760405162461bcd60e51b8152600401610296906116ec565b6103706040518060400160405280600f81526020016e27ab26afa137b73226b0b730b3b2b960891b815250610191565b6001600160a01b03166302ad4d2a336040518263ffffffff1660e01b815260040161039b919061159f565b60206040518083038186803b1580156103b357600080fd5b505afa1580156103c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103eb91906113d3565b6104075760405162461bcd60e51b8152600401610296906118bb565b60008251116104285760405162461bcd60e51b815260040161029690611878565b6104666040518060400160405280601d81526020017f4f564d5f43616e6f6e6963616c5472616e73616374696f6e436861696e000000815250610191565b6001600160a01b0316637aa63a866040518163ffffffff1660e01b815260040160206040518083038186803b15801561049e57600080fd5b505afa1580156104b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104d69190611419565b82516104e06102e2565b0111156104ff5760405162461bcd60e51b815260040161029690611646565b61052a8242336040516020016105169291906119a1565b604051602081830303815290604052610990565b5050565b60008082608001518060200190518101906105499190611564565b509050806105695760405162461bcd60e51b815260040161029690611833565b4261057682600154610b31565b119392505050565b6105b06040518060400160405280601181526020017027ab26afa33930bab22b32b934b334b2b960791b815250610191565b6001600160a01b0316336001600160a01b0316146105e05760405162461bcd60e51b8152600401610296906117d6565b6105e9816106de565b6106055760405162461bcd60e51b815260040161029690611749565b61060e8161052e565b61062a5760405162461bcd60e51b815260040161029690611778565b61063381610b92565b50565b60015481565b600061065f604051806060016040528060258152602001611ab560259139610191565b905090565b600061066e61063c565b6001600160a01b0316631f7b6d326040518163ffffffff1660e01b815260040160206040518083038186803b1580156106a657600080fd5b505afa1580156106ba573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065f9190611419565b60006106e861063c565b8251604051634a83e9cd60e11b81526001600160a01b039290921691639507d39a91610716916004016115be565b60206040518083038186803b15801561072e57600080fd5b505afa158015610742573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107669190611419565b61076f83610d0a565b1492915050565b60008082116107b65760405162461bcd60e51b8152600401808060200182810382526037815260200180611a316037913960400191505060405180910390fd5b8184106107f45760405162461bcd60e51b81526004018080602001828103825260248152602001806119dd6024913960400191505060405180910390fd5b6107fd82610d50565b83511461083b5760405162461bcd60e51b815260040180806020018281038252604d815260200180611a68604d913960600191505060405180910390fd5b8460005b84518110156108ee57856001166001141561089d5784818151811061086057fe5b60200260200101518260405160200180838152602001828152602001925050506040516020818303038152906040528051906020012091506108e2565b818582815181106108aa57fe5b602002602001015160405160200180838152602001828152602001925050506040516020818303038152906040528051906020012091505b600195861c950161083f565b5090951495945050505050565b600080600061090861063c565b6001600160a01b031663ccf8f9696040518163ffffffff1660e01b815260040160206040518083038186803b15801561094057600080fd5b505afa158015610954573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097891906113f3565b64ffffffffff602882901c16935060501c9150509091565b60006109bf6040518060400160405280600c81526020016b27ab26afa83937b837b9b2b960a11b815250610191565b90506000806109cc6108fb565b9092509050336001600160a01b03841614156109e9575042610a13565b426002548264ffffffffff160110610a135760405162461bcd60e51b81526004016102969061190a565b60006040518060a00160405280610a28610664565b8152602001610a3688610de6565b8152602001875181526020018464ffffffffff16815260200186815250905080600001517f16be4c5129a4e03cf3350262e181dc02ddfb4a6008d925368c0899fcd97ca9c58260200151836040015184606001518560800151604051610a9f94939291906115dd565b60405180910390a2610aaf61063c565b6001600160a01b0316632015276c610ac683610d0a565b610ada84604001518560600151018661121a565b6040518363ffffffff1660e01b8152600401610af79291906115c7565b600060405180830381600087803b158015610b1157600080fd5b505af1158015610b25573d6000803e3d6000fd5b50505050505050505050565b600082820183811015610b8b576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b610b9a61063c565b6001600160a01b0316631f7b6d326040518163ffffffff1660e01b815260040160206040518083038186803b158015610bd257600080fd5b505afa158015610be6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0a9190611419565b815110610c295760405162461bcd60e51b815260040161029690611973565b610c32816106de565b610c4e5760405162461bcd60e51b815260040161029690611749565b610c5661063c565b6001600160a01b031663167fd6818260000151610c788460600151600061121a565b6040518363ffffffff1660e01b8152600401610c959291906115c7565b600060405180830381600087803b158015610caf57600080fd5b505af1158015610cc3573d6000803e3d6000fd5b5050505080600001517f8747b69ce8fdb31c3b9b0a67bd8049ad8c1a69ea417b69b12174068abd9cbd648260200151604051610cff91906115be565b60405180910390a250565b60008160200151826040015183606001518460800151604051602001610d3394939291906115dd565b604051602081830303815290604052805190602001209050919050565b6000808211610d905760405162461bcd60e51b8152600401808060200182810382526030815260200180611a016030913960400191505060405180910390fd5b8160011415610da15750600061026a565b81600060805b60018110610dd1576000196001821b01811b831615610dc95791821c91908101905b60011c610da7565b506001811b8414610b8b576001019392505050565b600080825111610e275760405162461bcd60e51b8152600401808060200182810382526034815260200180611ada6034913960400191505060405180910390fd5b815160011415610e4d5781600081518110610e3e57fe5b6020026020010151905061026a565b60408051610200810182527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56381527f633dc4d7da7256660a892f8f1604a44b5432649cc8ec5cb3ced4c4e6ac94dd1d60208201527f890740a8eb06ce9be422cb8da5cdafc2b58c0a5e24036c578de2a433c828ff7d818301527f3b8ec09e026fdc305365dfc94e189a81b38c7597b3d941c279f042e8206e0bd86060808301919091527fecd50eee38e386bd62be9bedb990706951b65fe053bd9d8a521af753d139e2da60808301527fdefff6d330bb5403f63b14f33b578274160de3a50df4efecf0e0db73bcdd3da560a08301527f617bdd11f7c0a11f49db22f629387a12da7596f9d1704d7465177c63d88ec7d760c08301527f292c23a9aa1d8bea7e2435e555a4a60e379a5a35f3f452bae60121073fb6eead60e08301527fe1cea92ed99acdcb045a6726b2f87107e8a61620a232cf4d7d5b5766b3952e106101008301527f7ad66c0a68c72cb89e4fb4303841966e4062a76ab97451e3b9fb526a5ceb7f826101208301527fe026cc5a4aed3c22a58cbd3d2ac754c9352c5436f638042dca99034e836365166101408301527f3d04cffd8b46a874edf5cfae63077de85f849a660426697b06a829c70dd1409c6101608301527fad676aa337a485e4728a0b240d92b3ef7b3c372d06d189322bfd5f61f1e7203e6101808301527fa2fca4a49658f9fab7aa63289c91b7c7b6c832a6d0e69334ff5b0a3483d09dab6101a08301527f4ebfd9cd7bca2505f7bef59cc1c12ecc708fff26ae4af19abe852afe9e20c8626101c08301527f2def10d13dd169f550f578bda343d9717a138562e0093b380a1120789d53cf106101e083015282518381529081018352909160009190602082018180368337505085519192506000918291508180805b60018411156111f65750506002820460018084161460005b82811015611172578a816002028151811061111957fe5b602002602001015196508a816002026001018151811061113557fe5b6020026020010151955086602089015285604089015287805190602001208b828151811061115f57fe5b6020908102919091010152600101611102565b5080156111d55789600185038151811061118857fe5b6020026020010151955087836010811061119e57fe5b602002015160001b945085602088015284604088015286805190602001208a83815181106111c857fe5b6020026020010181815250505b806111e15760006111e4565b60015b60ff16820193506001909201916110ea565b8960008151811061120357fe5b602002602001015198505050505050505050919050565b602890811b91909117901b90565b600067ffffffffffffffff83111561123c57fe5b61124f601f8401601f19166020016119b8565b905082815283838301111561126357600080fd5b828260208301376000602084830101529392505050565b600082601f83011261128a578081fd5b8135602067ffffffffffffffff8211156112a057fe5b8082026112ae8282016119b8565b8381528281019086840183880185018910156112c8578687fd5b8693505b858410156112ea5780358352600193909301929184019184016112cc565b50979650505050505050565b600060a08284031215611307578081fd5b60405160a0810167ffffffffffffffff828210818311171561132557fe5b8160405282935084358352602085013560208401526040850135604084015260608501356060840152608085013591508082111561136257600080fd5b508301601f8101851361137457600080fd5b61138385823560208401611228565b6080830152505092915050565b600080604083850312156113a2578182fd5b823567ffffffffffffffff8111156113b8578283fd5b6113c48582860161127a565b95602094909401359450505050565b6000602082840312156113e4578081fd5b81518015158114610b8b578182fd5b600060208284031215611404578081fd5b815164ffffffffff1981168114610b8b578182fd5b60006020828403121561142a578081fd5b5051919050565b600080600060608486031215611445578081fd5b83359250602084013567ffffffffffffffff80821115611463578283fd5b61146f878388016112f6565b93506040860135915080821115611484578283fd5b9085019060408288031215611497578283fd5b6040516040810181811083821117156114ac57fe5b604052823581526020830135828111156114c4578485fd5b6114d08982860161127a565b6020830152508093505050509250925092565b6000602082840312156114f4578081fd5b813567ffffffffffffffff81111561150a578182fd5b8201601f8101841361151a578182fd5b61152984823560208401611228565b949350505050565b600060208284031215611542578081fd5b813567ffffffffffffffff811115611558578182fd5b611529848285016112f6565b60008060408385031215611576578182fd5b825160208401519092506001600160a01b0381168114611594578182fd5b809150509250929050565b6001600160a01b0391909116815260200190565b901515815260200190565b90815260200190565b91825264ffffffffff1916602082015260400190565b600085825260208581840152846040840152608060608401528351806080850152825b8181101561161c5785810183015185820160a001528201611600565b8181111561162d578360a083870101525b50601f01601f19169290920160a0019695505050505050565b60208082526049908201527f4e756d626572206f6620737461746520726f6f74732063616e6e6f742065786360408201527f65656420746865206e756d626572206f662063616e6f6e6963616c207472616e60608201526839b0b1ba34b7b7399760b91b608082015260a00190565b60208082526018908201527f496e76616c696420696e636c7573696f6e2070726f6f662e0000000000000000604082015260600190565b6020808252603d908201527f41637475616c20626174636820737461727420696e64657820646f6573206e6f60408201527f74206d6174636820657870656374656420737461727420696e6465782e000000606082015260800190565b60208082526015908201527424b73b30b634b2103130ba31b4103432b0b232b91760591b604082015260600190565b602080825260409082018190527f537461746520626174636865732063616e206f6e6c792062652064656c657465908201527f642077697468696e207468652066726175642070726f6f662077696e646f772e606082015260800190565b6020808252603b908201527f537461746520626174636865732063616e206f6e6c792062652064656c65746560408201527f6420627920746865204f564d5f467261756456657269666965722e0000000000606082015260800190565b60208082526025908201527f4261746368206865616465722074696d657374616d702063616e6e6f74206265604082015264207a65726f60d81b606082015260800190565b60208082526023908201527f43616e6e6f74207375626d697420616e20656d7074792073746174652062617460408201526231b41760e91b606082015260800190565b6020808252602f908201527f50726f706f73657220646f6573206e6f74206861766520656e6f75676820636f60408201526e1b1b185d195c985b081c1bdcdd1959608a1b606082015260800190565b60208082526043908201527f43616e6e6f74207075626c69736820737461746520726f6f747320776974686960408201527f6e207468652073657175656e636572207075626c69636174696f6e2077696e6460608201526237bb9760e91b608082015260a00190565b60208082526014908201527324b73b30b634b2103130ba31b41034b73232bc1760611b604082015260600190565b9182526001600160a01b0316602082015260400190565b60405181810167ffffffffffffffff811182821017156119d457fe5b60405291905056fe4c69625f4d65726b6c65547265653a20496e646578206f7574206f6620626f756e64732e4c69625f4d65726b6c65547265653a2043616e6e6f7420636f6d70757465206365696c286c6f675f3229206f6620302e4c69625f4d65726b6c65547265653a20546f74616c206c6561766573206d7573742062652067726561746572207468616e207a65726f2e4c69625f4d65726b6c65547265653a20546f74616c207369626c696e677320646f6573206e6f7420636f72726563746c7920636f72726573706f6e6420746f20746f74616c206c65617665732e4f564d5f436861696e53746f72616765436f6e7461696e65723a5343433a626174636865734c69625f4d65726b6c65547265653a204d7573742070726f76696465206174206c65617374206f6e65206c65616620686173682ea164736f6c6343000706000a000000000000000000000000d3eed86464ff13b4bfd81a3bb1e753b7ceba3a390000000000000000000000000000000000000000000000000000000000000258000000000000000000000000000000000000000000000000000000000112a880
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100b45760003560e01c80638ca5cbb9116100715780638ca5cbb91461012f5780639418bddd14610144578063b8e189ac14610157578063c17b291b1461016a578063cfdf677e14610172578063e561dddc1461017a576100b4565b8063299ca478146100b9578063461a4478146100d75780634d69ee57146100ea5780637aa63a861461010a5780637ad168a01461011f57806381eb62ef14610127575b600080fd5b6100c1610182565b6040516100ce919061159f565b60405180910390f35b6100c16100e53660046114e3565b610191565b6100fd6100f8366004611431565b61026f565b6040516100ce91906115b3565b6101126102e2565b6040516100ce91906115be565b6101126102fb565b610112610314565b61014261013d366004611390565b61031a565b005b6100fd610152366004611531565b61052e565b610142610165366004611531565b61057e565b610112610636565b6100c161063c565b610112610664565b6000546001600160a01b031681565b6000805460405163bf40fac160e01b81526020600482018181528551602484015285516001600160a01b039094169363bf40fac19387938392604490920191908501908083838b5b838110156101f15781810151838201526020016101d9565b50505050905090810190601f16801561021e5780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b15801561023b57600080fd5b505afa15801561024f573d6000803e3d6000fd5b505050506040513d602081101561026557600080fd5b505190505b919050565b600061027a836106de565b61029f5760405162461bcd60e51b815260040161029690611749565b60405180910390fd5b6102bc836020015185846000015185602001518760400151610776565b6102d85760405162461bcd60e51b8152600401610296906116b5565b5060019392505050565b6000806102ed6108fb565b5064ffffffffff1691505090565b6000806103066108fb565b64ffffffffff169250505090565b60025481565b6103226102e2565b81146103405760405162461bcd60e51b8152600401610296906116ec565b6103706040518060400160405280600f81526020016e27ab26afa137b73226b0b730b3b2b960891b815250610191565b6001600160a01b03166302ad4d2a336040518263ffffffff1660e01b815260040161039b919061159f565b60206040518083038186803b1580156103b357600080fd5b505afa1580156103c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103eb91906113d3565b6104075760405162461bcd60e51b8152600401610296906118bb565b60008251116104285760405162461bcd60e51b815260040161029690611878565b6104666040518060400160405280601d81526020017f4f564d5f43616e6f6e6963616c5472616e73616374696f6e436861696e000000815250610191565b6001600160a01b0316637aa63a866040518163ffffffff1660e01b815260040160206040518083038186803b15801561049e57600080fd5b505afa1580156104b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104d69190611419565b82516104e06102e2565b0111156104ff5760405162461bcd60e51b815260040161029690611646565b61052a8242336040516020016105169291906119a1565b604051602081830303815290604052610990565b5050565b60008082608001518060200190518101906105499190611564565b509050806105695760405162461bcd60e51b815260040161029690611833565b4261057682600154610b31565b119392505050565b6105b06040518060400160405280601181526020017027ab26afa33930bab22b32b934b334b2b960791b815250610191565b6001600160a01b0316336001600160a01b0316146105e05760405162461bcd60e51b8152600401610296906117d6565b6105e9816106de565b6106055760405162461bcd60e51b815260040161029690611749565b61060e8161052e565b61062a5760405162461bcd60e51b815260040161029690611778565b61063381610b92565b50565b60015481565b600061065f604051806060016040528060258152602001611ab560259139610191565b905090565b600061066e61063c565b6001600160a01b0316631f7b6d326040518163ffffffff1660e01b815260040160206040518083038186803b1580156106a657600080fd5b505afa1580156106ba573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065f9190611419565b60006106e861063c565b8251604051634a83e9cd60e11b81526001600160a01b039290921691639507d39a91610716916004016115be565b60206040518083038186803b15801561072e57600080fd5b505afa158015610742573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107669190611419565b61076f83610d0a565b1492915050565b60008082116107b65760405162461bcd60e51b8152600401808060200182810382526037815260200180611a316037913960400191505060405180910390fd5b8184106107f45760405162461bcd60e51b81526004018080602001828103825260248152602001806119dd6024913960400191505060405180910390fd5b6107fd82610d50565b83511461083b5760405162461bcd60e51b815260040180806020018281038252604d815260200180611a68604d913960600191505060405180910390fd5b8460005b84518110156108ee57856001166001141561089d5784818151811061086057fe5b60200260200101518260405160200180838152602001828152602001925050506040516020818303038152906040528051906020012091506108e2565b818582815181106108aa57fe5b602002602001015160405160200180838152602001828152602001925050506040516020818303038152906040528051906020012091505b600195861c950161083f565b5090951495945050505050565b600080600061090861063c565b6001600160a01b031663ccf8f9696040518163ffffffff1660e01b815260040160206040518083038186803b15801561094057600080fd5b505afa158015610954573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097891906113f3565b64ffffffffff602882901c16935060501c9150509091565b60006109bf6040518060400160405280600c81526020016b27ab26afa83937b837b9b2b960a11b815250610191565b90506000806109cc6108fb565b9092509050336001600160a01b03841614156109e9575042610a13565b426002548264ffffffffff160110610a135760405162461bcd60e51b81526004016102969061190a565b60006040518060a00160405280610a28610664565b8152602001610a3688610de6565b8152602001875181526020018464ffffffffff16815260200186815250905080600001517f16be4c5129a4e03cf3350262e181dc02ddfb4a6008d925368c0899fcd97ca9c58260200151836040015184606001518560800151604051610a9f94939291906115dd565b60405180910390a2610aaf61063c565b6001600160a01b0316632015276c610ac683610d0a565b610ada84604001518560600151018661121a565b6040518363ffffffff1660e01b8152600401610af79291906115c7565b600060405180830381600087803b158015610b1157600080fd5b505af1158015610b25573d6000803e3d6000fd5b50505050505050505050565b600082820183811015610b8b576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b610b9a61063c565b6001600160a01b0316631f7b6d326040518163ffffffff1660e01b815260040160206040518083038186803b158015610bd257600080fd5b505afa158015610be6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0a9190611419565b815110610c295760405162461bcd60e51b815260040161029690611973565b610c32816106de565b610c4e5760405162461bcd60e51b815260040161029690611749565b610c5661063c565b6001600160a01b031663167fd6818260000151610c788460600151600061121a565b6040518363ffffffff1660e01b8152600401610c959291906115c7565b600060405180830381600087803b158015610caf57600080fd5b505af1158015610cc3573d6000803e3d6000fd5b5050505080600001517f8747b69ce8fdb31c3b9b0a67bd8049ad8c1a69ea417b69b12174068abd9cbd648260200151604051610cff91906115be565b60405180910390a250565b60008160200151826040015183606001518460800151604051602001610d3394939291906115dd565b604051602081830303815290604052805190602001209050919050565b6000808211610d905760405162461bcd60e51b8152600401808060200182810382526030815260200180611a016030913960400191505060405180910390fd5b8160011415610da15750600061026a565b81600060805b60018110610dd1576000196001821b01811b831615610dc95791821c91908101905b60011c610da7565b506001811b8414610b8b576001019392505050565b600080825111610e275760405162461bcd60e51b8152600401808060200182810382526034815260200180611ada6034913960400191505060405180910390fd5b815160011415610e4d5781600081518110610e3e57fe5b6020026020010151905061026a565b60408051610200810182527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56381527f633dc4d7da7256660a892f8f1604a44b5432649cc8ec5cb3ced4c4e6ac94dd1d60208201527f890740a8eb06ce9be422cb8da5cdafc2b58c0a5e24036c578de2a433c828ff7d818301527f3b8ec09e026fdc305365dfc94e189a81b38c7597b3d941c279f042e8206e0bd86060808301919091527fecd50eee38e386bd62be9bedb990706951b65fe053bd9d8a521af753d139e2da60808301527fdefff6d330bb5403f63b14f33b578274160de3a50df4efecf0e0db73bcdd3da560a08301527f617bdd11f7c0a11f49db22f629387a12da7596f9d1704d7465177c63d88ec7d760c08301527f292c23a9aa1d8bea7e2435e555a4a60e379a5a35f3f452bae60121073fb6eead60e08301527fe1cea92ed99acdcb045a6726b2f87107e8a61620a232cf4d7d5b5766b3952e106101008301527f7ad66c0a68c72cb89e4fb4303841966e4062a76ab97451e3b9fb526a5ceb7f826101208301527fe026cc5a4aed3c22a58cbd3d2ac754c9352c5436f638042dca99034e836365166101408301527f3d04cffd8b46a874edf5cfae63077de85f849a660426697b06a829c70dd1409c6101608301527fad676aa337a485e4728a0b240d92b3ef7b3c372d06d189322bfd5f61f1e7203e6101808301527fa2fca4a49658f9fab7aa63289c91b7c7b6c832a6d0e69334ff5b0a3483d09dab6101a08301527f4ebfd9cd7bca2505f7bef59cc1c12ecc708fff26ae4af19abe852afe9e20c8626101c08301527f2def10d13dd169f550f578bda343d9717a138562e0093b380a1120789d53cf106101e083015282518381529081018352909160009190602082018180368337505085519192506000918291508180805b60018411156111f65750506002820460018084161460005b82811015611172578a816002028151811061111957fe5b602002602001015196508a816002026001018151811061113557fe5b6020026020010151955086602089015285604089015287805190602001208b828151811061115f57fe5b6020908102919091010152600101611102565b5080156111d55789600185038151811061118857fe5b6020026020010151955087836010811061119e57fe5b602002015160001b945085602088015284604088015286805190602001208a83815181106111c857fe5b6020026020010181815250505b806111e15760006111e4565b60015b60ff16820193506001909201916110ea565b8960008151811061120357fe5b602002602001015198505050505050505050919050565b602890811b91909117901b90565b600067ffffffffffffffff83111561123c57fe5b61124f601f8401601f19166020016119b8565b905082815283838301111561126357600080fd5b828260208301376000602084830101529392505050565b600082601f83011261128a578081fd5b8135602067ffffffffffffffff8211156112a057fe5b8082026112ae8282016119b8565b8381528281019086840183880185018910156112c8578687fd5b8693505b858410156112ea5780358352600193909301929184019184016112cc565b50979650505050505050565b600060a08284031215611307578081fd5b60405160a0810167ffffffffffffffff828210818311171561132557fe5b8160405282935084358352602085013560208401526040850135604084015260608501356060840152608085013591508082111561136257600080fd5b508301601f8101851361137457600080fd5b61138385823560208401611228565b6080830152505092915050565b600080604083850312156113a2578182fd5b823567ffffffffffffffff8111156113b8578283fd5b6113c48582860161127a565b95602094909401359450505050565b6000602082840312156113e4578081fd5b81518015158114610b8b578182fd5b600060208284031215611404578081fd5b815164ffffffffff1981168114610b8b578182fd5b60006020828403121561142a578081fd5b5051919050565b600080600060608486031215611445578081fd5b83359250602084013567ffffffffffffffff80821115611463578283fd5b61146f878388016112f6565b93506040860135915080821115611484578283fd5b9085019060408288031215611497578283fd5b6040516040810181811083821117156114ac57fe5b604052823581526020830135828111156114c4578485fd5b6114d08982860161127a565b6020830152508093505050509250925092565b6000602082840312156114f4578081fd5b813567ffffffffffffffff81111561150a578182fd5b8201601f8101841361151a578182fd5b61152984823560208401611228565b949350505050565b600060208284031215611542578081fd5b813567ffffffffffffffff811115611558578182fd5b611529848285016112f6565b60008060408385031215611576578182fd5b825160208401519092506001600160a01b0381168114611594578182fd5b809150509250929050565b6001600160a01b0391909116815260200190565b901515815260200190565b90815260200190565b91825264ffffffffff1916602082015260400190565b600085825260208581840152846040840152608060608401528351806080850152825b8181101561161c5785810183015185820160a001528201611600565b8181111561162d578360a083870101525b50601f01601f19169290920160a0019695505050505050565b60208082526049908201527f4e756d626572206f6620737461746520726f6f74732063616e6e6f742065786360408201527f65656420746865206e756d626572206f662063616e6f6e6963616c207472616e60608201526839b0b1ba34b7b7399760b91b608082015260a00190565b60208082526018908201527f496e76616c696420696e636c7573696f6e2070726f6f662e0000000000000000604082015260600190565b6020808252603d908201527f41637475616c20626174636820737461727420696e64657820646f6573206e6f60408201527f74206d6174636820657870656374656420737461727420696e6465782e000000606082015260800190565b60208082526015908201527424b73b30b634b2103130ba31b4103432b0b232b91760591b604082015260600190565b602080825260409082018190527f537461746520626174636865732063616e206f6e6c792062652064656c657465908201527f642077697468696e207468652066726175642070726f6f662077696e646f772e606082015260800190565b6020808252603b908201527f537461746520626174636865732063616e206f6e6c792062652064656c65746560408201527f6420627920746865204f564d5f467261756456657269666965722e0000000000606082015260800190565b60208082526025908201527f4261746368206865616465722074696d657374616d702063616e6e6f74206265604082015264207a65726f60d81b606082015260800190565b60208082526023908201527f43616e6e6f74207375626d697420616e20656d7074792073746174652062617460408201526231b41760e91b606082015260800190565b6020808252602f908201527f50726f706f73657220646f6573206e6f74206861766520656e6f75676820636f60408201526e1b1b185d195c985b081c1bdcdd1959608a1b606082015260800190565b60208082526043908201527f43616e6e6f74207075626c69736820737461746520726f6f747320776974686960408201527f6e207468652073657175656e636572207075626c69636174696f6e2077696e6460608201526237bb9760e91b608082015260a00190565b60208082526014908201527324b73b30b634b2103130ba31b41034b73232bc1760611b604082015260600190565b9182526001600160a01b0316602082015260400190565b60405181810167ffffffffffffffff811182821017156119d457fe5b60405291905056fe4c69625f4d65726b6c65547265653a20496e646578206f7574206f6620626f756e64732e4c69625f4d65726b6c65547265653a2043616e6e6f7420636f6d70757465206365696c286c6f675f3229206f6620302e4c69625f4d65726b6c65547265653a20546f74616c206c6561766573206d7573742062652067726561746572207468616e207a65726f2e4c69625f4d65726b6c65547265653a20546f74616c207369626c696e677320646f6573206e6f7420636f72726563746c7920636f72726573706f6e6420746f20746f74616c206c65617665732e4f564d5f436861696e53746f72616765436f6e7461696e65723a5343433a626174636865734c69625f4d65726b6c65547265653a204d7573742070726f76696465206174206c65617374206f6e65206c65616620686173682ea164736f6c6343000706000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000d3eed86464ff13b4bfd81a3bb1e753b7ceba3a390000000000000000000000000000000000000000000000000000000000000258000000000000000000000000000000000000000000000000000000000112a880
-----Decoded View---------------
Arg [0] : _libAddressManager (address): 0xd3EeD86464Ff13B4BFD81a3bB1e753b7ceBA3A39
Arg [1] : _fraudProofWindow (uint256): 600
Arg [2] : _sequencerPublishWindow (uint256): 18000000
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000d3eed86464ff13b4bfd81a3bb1e753b7ceba3a39
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000258
Arg [2] : 000000000000000000000000000000000000000000000000000000000112a880
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 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.