{
  "language": "Solidity",
  "sources": {
    "@openzeppelin/contracts/access/Ownable.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    constructor() {\n        _transferOwnership(_msgSender());\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions anymore. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby removing any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"
    },
    "@openzeppelin/contracts/utils/Context.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n}\n"
    },
    "contracts/L1/dispute/interfaces/IDisputeGame.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IInitializable} from \"./IInitializable.sol\";\n\nimport \"contracts/L1/dispute/lib/Types.sol\";\n\n/// @title IDisputeGame\n/// @notice The generic interface for a DisputeGame contract.\ninterface IDisputeGame is IInitializable {\n    /// @notice Emitted when the game is resolved.\n    /// @param status The status of the game after resolution.\n    event Resolved(GameStatus indexed status);\n\n    /// @notice Returns the timestamp that the DisputeGame contract was created at.\n    /// @return createdAt_ The timestamp that the DisputeGame contract was created at.\n    function createdAt() external view returns (Timestamp createdAt_);\n\n    /// @notice Returns the timestamp that the DisputeGame contract was resolved at.\n    /// @return resolvedAt_ The timestamp that the DisputeGame contract was resolved at.\n    function resolvedAt() external view returns (Timestamp resolvedAt_);\n\n    /// @notice Returns the current status of the game.\n    /// @return status_ The current status of the game.\n    function status() external view returns (GameStatus status_);\n\n    /// @notice Getter for the game type.\n    /// @dev The reference impl should be entirely different depending on the type (fault, validity)\n    ///      i.e. The game type should indicate the security model.\n    /// @return gameType_ The type of proof system being used.\n    function gameType() external view returns (GameType gameType_);\n\n    /// @notice Getter for the creator of the dispute game.\n    /// @dev `clones-with-immutable-args` argument #1\n    /// @return creator_ The creator of the dispute game.\n    function gameCreator() external pure returns (address creator_);\n\n    /// @notice Getter for the root claim.\n    /// @dev `clones-with-immutable-args` argument #2\n    /// @return rootClaim_ The root claim of the DisputeGame.\n    function rootClaim() external pure returns (Claim rootClaim_);\n\n    /// @notice Getter for the parent hash of the L1 block when the dispute game was created.\n    /// @dev `clones-with-immutable-args` argument #3\n    /// @return l1Head_ The parent hash of the L1 block when the dispute game was created.\n    function l1Head() external pure returns (Hash l1Head_);\n\n    /// @notice Getter for the extra data.\n    /// @dev `clones-with-immutable-args` argument #4\n    /// @return extraData_ Any extra data supplied to the dispute game contract by the creator.\n    function extraData() external pure returns (bytes memory extraData_);\n\n    /// @notice If all necessary information has been gathered, this function should mark the game\n    ///         status as either `CHALLENGER_WINS` or `DEFENDER_WINS` and return the status of\n    ///         the resolved game. It is at this stage that the bonds should be awarded to the\n    ///         necessary parties.\n    /// @dev May only be called if the `status` is `IN_PROGRESS`.\n    /// @return status_ The status of the game after resolution.\n    function resolve() external returns (GameStatus status_);\n\n    /// @notice A compliant implementation of this interface should return the components of the\n    ///         game UUID's preimage provided in the cwia payload. The preimage of the UUID is\n    ///         constructed as `keccak256(gameType . rootClaim . extraData)` where `.` denotes\n    ///         concatenation.\n    /// @return gameType_ The type of proof system being used.\n    /// @return rootClaim_ The root claim of the DisputeGame.\n    /// @return extraData_ Any extra data supplied to the dispute game contract by the creator.\n    function gameData() external view returns (GameType gameType_, Claim rootClaim_, bytes memory extraData_);\n}\n"
    },
    "contracts/L1/dispute/interfaces/IDisputeGameFactory.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IDisputeGame} from \"./IDisputeGame.sol\";\n\nimport \"contracts/L1/dispute/lib/Types.sol\";\n\n/// @title IDisputeGameFactory\n/// @notice The interface for a DisputeGameFactory contract.\ninterface IDisputeGameFactory {\n    /// @notice Emitted when a new dispute game is requested\n    /// @param requestor The address of the requestor\n    /// @param gameType The type of the dispute game\n    /// @param bond The bond (in wei) for initializing the game type\n    //. @param extraData Any extra data that should be provided to the created dispute game.\n    event DisputeGameRequested(address indexed requestor, GameType indexed gameType, uint256 bond, bytes extraData);\n\n    /// @notice Emitted when a new dispute game is created\n    /// @param disputeProxy The address of the dispute game proxy\n    /// @param gameType The type of the dispute game proxy's implementation\n    /// @param rootClaim The root claim of the dispute game\n    event DisputeGameCreated(address indexed disputeProxy, GameType indexed gameType, Claim indexed rootClaim);\n\n    /// @notice Emitted when a new game implementation added to the factory\n    /// @param impl The implementation contract for the given `GameType`.\n    /// @param gameType The type of the DisputeGame.\n    event ImplementationSet(address indexed impl, GameType indexed gameType);\n\n    /// @notice Emitted when a game type's initialization bond is updated\n    /// @param gameType The type of the DisputeGame.\n    /// @param newBond The new bond (in wei) for initializing the game type.\n    event InitBondUpdated(GameType indexed gameType, uint256 indexed newBond);\n\n    /// @notice Information about a dispute game found in a `findLatestGames` search.\n    struct GameSearchResult {\n        uint256 index;\n        GameId metadata;\n        Timestamp timestamp;\n        Claim rootClaim;\n        bytes extraData;\n    }\n\n    /// @notice The total number of dispute games created by this factory.\n    /// @return gameCount_ The total number of dispute games created by this factory.\n    function gameCount() external view returns (uint256 gameCount_);\n\n    /// @notice `games` queries an internal mapping that maps the hash of\n    ///         `gameType ++ rootClaim ++ extraData` to the deployed `DisputeGame` clone.\n    /// @dev `++` equates to concatenation.\n    /// @param _gameType The type of the DisputeGame - used to decide the proxy implementation\n    /// @param _rootClaim The root claim of the DisputeGame.\n    /// @param _extraData Any extra data that should be provided to the created dispute game.\n    /// @return proxy_ The clone of the `DisputeGame` created with the given parameters.\n    ///         Returns `address(0)` if nonexistent.\n    /// @return timestamp_ The timestamp of the creation of the dispute game.\n    function games(\n        GameType _gameType,\n        Claim _rootClaim,\n        bytes calldata _extraData\n    )\n    external\n    view\n    returns (IDisputeGame proxy_, Timestamp timestamp_);\n\n    /// @notice `gameAtIndex` returns the dispute game contract address and its creation timestamp\n    ///          at the given index. Each created dispute game increments the underlying index.\n    /// @param _index The index of the dispute game.\n    /// @return gameType_ The type of the DisputeGame - used to decide the proxy implementation.\n    /// @return timestamp_ The timestamp of the creation of the dispute game.\n    /// @return proxy_ The clone of the `DisputeGame` created with the given parameters.\n    ///         Returns `address(0)` if nonexistent.\n    function gameAtIndex(uint256 _index)\n    external\n    view\n    returns (GameType gameType_, Timestamp timestamp_, IDisputeGame proxy_);\n\n    /// @notice `gameImpls` is a mapping that maps `GameType`s to their respective\n    ///         `IDisputeGame` implementations.\n    /// @param _gameType The type of the dispute game.\n    /// @return impl_ The address of the implementation of the game type.\n    ///         Will be cloned on creation of a new dispute game with the given `gameType`.\n    function gameImpls(GameType _gameType) external view returns (IDisputeGame impl_);\n\n    /// @notice Returns the required bonds for initializing a dispute game of the given type.\n    /// @param _gameType The type of the dispute game.\n    /// @return bond_ The required bond for initializing a dispute game of the given type.\n    function initBonds(GameType _gameType) external view returns (uint256 bond_);\n\n    /// @notice Requests a new dispute game of the given type.\n    /// @dev Emits a `DisputeGameRequested` event.\n    /// @param _gameType The type of the dispute game.\n    /// @param _extraData Any extra data that should be provided to the created dispute game.\n    function dispute(GameType _gameType, bytes calldata _extraData) external payable;\n\n    /// @notice Creates a new DisputeGame proxy contract.\n    /// @param _gameType The type of the DisputeGame - used to decide the proxy implementation.\n    /// @param _rootClaim The root claim of the DisputeGame.\n    /// @param _extraData Any extra data that should be provided to the created dispute game.\n    /// @return proxy_ The address of the created DisputeGame proxy.\n    function create(\n        GameType _gameType,\n        Claim _rootClaim,\n        bytes calldata _extraData\n    )\n    external\n    returns (IDisputeGame proxy_);\n\n    /// @notice Sets the implementation contract for a specific `GameType`.\n    /// @dev May only be called by the `owner`.\n    /// @param _gameType The type of the DisputeGame.\n    /// @param _impl The implementation contract for the given `GameType`.\n    function setImplementation(GameType _gameType, IDisputeGame _impl) external;\n\n    /// @notice Sets the bond (in wei) for initializing a game type.\n    /// @dev May only be called by the `owner`.\n    /// @param _gameType The type of the DisputeGame.\n    /// @param _initBond The bond (in wei) for initializing a game type.\n    function setInitBond(GameType _gameType, uint256 _initBond) external;\n\n    /// @notice Returns a unique identifier for the given dispute game parameters.\n    /// @dev Hashes the concatenation of `gameType . rootClaim . extraData`\n    ///      without expanding memory.\n    /// @param _gameType The type of the DisputeGame.\n    /// @param _rootClaim The root claim of the DisputeGame.\n    /// @param _extraData Any extra data that should be provided to the created dispute game.\n    /// @return uuid_ The unique identifier for the given dispute game parameters.\n    function getGameUUID(\n        GameType _gameType,\n        Claim _rootClaim,\n        bytes memory _extraData\n    )\n    external\n    pure\n    returns (Hash uuid_);\n\n    /// @notice Finds the `_n` most recent `GameId`'s of type `_gameType` starting at `_start`. If there are less than\n    ///         `_n` games of type `_gameType` starting at `_start`, then the returned array will be shorter than `_n`.\n    /// @param _gameType The type of game to find.\n    /// @param _start The index to start the reverse search from.\n    /// @param _n The number of games to find.\n    function findLatestGames(\n        GameType _gameType,\n        uint256 _start,\n        uint256 _n\n    )\n    external\n    view\n    returns (GameSearchResult[] memory games_);\n}\n"
    },
    "contracts/L1/dispute/interfaces/IFaultDisputeGame.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IDisputeGame} from \"./IDisputeGame.sol\";\n\nimport \"contracts/L1/dispute/lib/Types.sol\";\n\n/// @title IFaultDisputeGame\n/// @notice The interface for a fault proof backed dispute game.\ninterface IFaultDisputeGame is IDisputeGame {\n    /// @notice The `ClaimData` struct represents the data associated with a Claim.\n    struct ClaimData {\n        uint32 parentIndex;\n        address counteredBy;\n        address claimant;\n        uint128 bond;\n        Claim claim;\n        Position position;\n        Clock clock;\n    }\n\n    /// @notice The `ResolutionCheckpoint` struct represents the data associated with an in-progress claim resolution.\n    struct ResolutionCheckpoint {\n        bool initialCheckpointComplete;\n        uint32 subgameIndex;\n        Position leftmostPosition;\n        address counteredBy;\n    }\n\n    /// @notice Emitted when a new claim is added to the DAG by `claimant`\n    /// @param parentIndex The index within the `claimData` array of the parent claim\n    /// @param claim The claim being added\n    /// @param claimant The address of the claimant\n    event Move(uint256 indexed parentIndex, Claim indexed claim, address indexed claimant);\n\n    /// @notice Attack a disagreed upon `Claim`.\n    /// @param _disputed The `Claim` being attacked.\n    /// @param _parentIndex Index of the `Claim` to attack in the `claimData` array. This must match the `_disputed`\n    /// claim.\n    /// @param _claim The `Claim` at the relative attack position.\n    function attack(Claim _disputed, uint256 _parentIndex, Claim _claim) external payable;\n\n    /// @notice Defend an agreed upon `Claim`.\n    /// @notice _disputed The `Claim` being defended.\n    /// @param _parentIndex Index of the claim to defend in the `claimData` array. This must match the `_disputed`\n    /// claim.\n    /// @param _claim The `Claim` at the relative defense position.\n    function defend(Claim _disputed, uint256 _parentIndex, Claim _claim) external payable;\n\n    /// @notice Perform an instruction step via an on-chain fault proof processor.\n    /// @dev This function should point to a fault proof processor in order to execute\n    ///      a step in the fault proof program on-chain. The interface of the fault proof\n    ///      processor contract should adhere to the `IBigStepper` interface.\n    /// @param _claimIndex The index of the challenged claim within `claimData`.\n    /// @param _isAttack Whether or not the step is an attack or a defense.\n    /// @param _stateData The stateData of the step is the preimage of the claim at the given\n    ///        prestate, which is at `_stateIndex` if the move is an attack and `_claimIndex` if\n    ///        the move is a defense. If the step is an attack on the first instruction, it is\n    ///        the absolute prestate of the fault proof VM.\n    /// @param _proof Proof to access memory nodes in the VM's merkle state tree.\n    function step(uint256 _claimIndex, bool _isAttack, bytes calldata _stateData, bytes calldata _proof) external;\n\n    /// @notice Posts the requested local data to the VM's `PreimageOralce`.\n    /// @param _ident The local identifier of the data to post.\n    /// @param _execLeafIdx The index of the leaf claim in an execution subgame that requires the local data for a step.\n    /// @param _partOffset The offset of the data to post.\n    function addLocalData(uint256 _ident, uint256 _execLeafIdx, uint256 _partOffset) external;\n\n    /// @notice Resolves the subgame rooted at the given claim index. `_numToResolve` specifies how many children of\n    ///         the subgame will be checked in this call. If `_numToResolve` is less than the number of children, an\n    ///         internal cursor will be updated and this function may be called again to complete resolution of the\n    ///         subgame.\n    /// @dev This function must be called bottom-up in the DAG\n    ///      A subgame is a tree of claims that has a maximum depth of 1.\n    ///      A subgame root claims is valid if, and only if, all of its child claims are invalid.\n    ///      At the deepest level in the DAG, a claim is invalid if there's a successful step against it.\n    /// @param _claimIndex The index of the subgame root claim to resolve.\n    /// @param _numToResolve The number of subgames to resolve in this call. If the input is `0`, and this is the first\n    ///                      page, this function will attempt to check all of the subgame's children at once.\n    function resolveClaim(uint256 _claimIndex, uint256 _numToResolve) external;\n\n    /// @notice Returns the number of children that still need to be resolved in order to fully resolve a subgame rooted\n    ///         at `_claimIndex`.\n    /// @param _claimIndex The subgame root claim's index within `claimData`.\n    /// @return numRemainingChildren_ The number of children that still need to be checked to resolve the subgame.\n    function getNumToResolve(uint256 _claimIndex) external view returns (uint256 numRemainingChildren_);\n\n    /// @notice The l2BlockNumber of the disputed output root in the `L2OutputOracle`.\n    function l2BlockNumber() external view returns (uint256 l2BlockNumber_);\n\n    /// @notice Starting output root and block number of the game.\n    function startingOutputRoot() external view returns (Hash startingRoot_, uint256 l2BlockNumber_);\n\n    /// @notice Only the starting block number of the game.\n    function startingBlockNumber() external view returns (uint256 startingBlockNumber_);\n\n    /// @notice Only the starting output root of the game.\n    function startingRootHash() external view returns (Hash startingRootHash_);\n}\n"
    },
    "contracts/L1/dispute/interfaces/IInitializable.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @title IInitializable\n/// @notice An interface for initializable contracts.\ninterface IInitializable {\n    /// @notice Initializes the contract.\n    /// @dev This function may only be called once.\n    function initialize() external payable;\n}\n"
    },
    "contracts/L1/dispute/lib/Errors.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\nimport \"./LibUDT.sol\";\n\n////////////////////////////////////////////////////////////////\n//                `DisputeGameFactory` Errors                 //\n////////////////////////////////////////////////////////////////\n\n/// @notice Thrown when a dispute game is attempted to be created with an unsupported game type.\n/// @param gameType The unsupported game type.\n    error NoImplementation(GameType gameType);\n\n/// @notice Thrown when a dispute game that already exists is attempted to be created.\n/// @param uuid The UUID of the dispute game that already exists.\n    error GameAlreadyExists(Hash uuid);\n\n/// @notice Thrown when the root claim has an unexpected VM status.\n///         Some games can only start with a root-claim with a specific status.\n/// @param rootClaim is the claim that was unexpected.\n    error UnexpectedRootClaim(Claim rootClaim);\n\n/// @notice Thrown when no dispute game requested.\n    error NoDisputeGameRequests();\n\n////////////////////////////////////////////////////////////////\n//                 `FaultDisputeGame` Errors                  //\n////////////////////////////////////////////////////////////////\n\n/// @notice Thrown when a dispute game has already been initialized.\n    error AlreadyInitialized();\n\n/// @notice Thrown when a supplied bond is not equal to the required bond amount to cover the cost of the interaction.\n    error IncorrectBondAmount();\n\n/// @notice Thrown when a credit claim is attempted for a value of 0.\n    error NoCreditToClaim();\n\n/// @notice Thrown when the transfer of credit to a recipient account reverts.\n    error BondTransferFailed();\n\n/// @notice Thrown when the `extraData` passed to the CWIA proxy is of improper length, or contains invalid information.\n    error BadExtraData();\n\n/// @notice Thrown when a defense against the root claim is attempted.\n    error CannotDefendRootClaim();\n\n/// @notice Thrown when a claim is attempting to be made that already exists.\n    error ClaimAlreadyExists();\n\n/// @notice Thrown when a disputed claim does not match its index in the game.\n    error InvalidDisputedClaimIndex();\n\n/// @notice Thrown when an action that requires the game to be `IN_PROGRESS` is invoked when\n///         the game is not in progress.\n    error GameNotInProgress();\n\n/// @notice Thrown when a move is attempted to be made after the clock has timed out.\n    error ClockTimeExceeded();\n\n/// @notice Thrown when the game is attempted to be resolved too early.\n    error ClockNotExpired();\n\n/// @notice Thrown when a move is attempted to be made at or greater than the max depth of the game.\n    error GameDepthExceeded();\n\n/// @notice Thrown when a step is attempted above the maximum game depth.\n    error InvalidParent();\n\n/// @notice Thrown when an invalid prestate is supplied to `step`.\n    error InvalidPrestate();\n\n/// @notice Thrown when a step is made that computes the expected post state correctly.\n    error ValidStep();\n\n/// @notice Thrown when a game is attempted to be initialized with an L1 head that does\n///         not contain the disputed output root.\n    error L1HeadTooOld();\n\n/// @notice Thrown when an invalid local identifier is passed to the `addLocalData` function.\n    error InvalidLocalIdent();\n\n/// @notice Thrown when resolving claims out of order.\n    error OutOfOrderResolution();\n\n/// @notice Thrown when resolving a claim that has already been resolved.\n    error ClaimAlreadyResolved();\n\n/// @notice Thrown when a parent output root is attempted to be found on a claim that is in\n///         the output root portion of the tree.\n    error ClaimAboveSplit();\n\n/// @notice Thrown on deployment if the split depth is greater than or equal to the max\n///         depth of the game.\n    error InvalidSplitDepth();\n\n/// @notice Thrown on deployment if the max clock duration is less than or equal to the clock extension.\n    error InvalidClockExtension();\n\n/// @notice Thrown on deployment if the PreimageOracle challenge period is too high.\n    error InvalidChallengePeriod();\n\n/// @notice Thrown on deployment if the max depth is greater than `LibPosition.`\n    error MaxDepthTooLarge();\n\n/// @notice Thrown when trying to step against a claim for a second time, after it has already been countered with\n///         an instruction step.\n    error DuplicateStep();\n\n/// @notice Thrown when an anchor root is not found for a given game type.\n    error AnchorRootNotFound();\n\n/// @notice Thrown when an output root proof is invalid.\n    error InvalidOutputRootProof();\n\n/// @notice Thrown when header RLP is invalid with respect to the block hash in an output root proof.\n    error InvalidHeaderRLP();\n\n/// @notice Thrown when there is a match between the block number in the output root proof and the block number\n///         claimed in the dispute game.\n    error BlockNumberMatches();\n\n/// @notice Thrown when the L2 block number claim has already been challenged.\n    error L2BlockNumberChallenged();\n\n////////////////////////////////////////////////////////////////\n//              `PermissionedDisputeGame` Errors              //\n////////////////////////////////////////////////////////////////\n\n/// @notice Thrown when an unauthorized address attempts to interact with the game.\n    error BadAuth();\n\n////////////////////////////////////////////////////////////////\n//              `AnchorStateRegistry` Errors                  //\n////////////////////////////////////////////////////////////////\n\n/// @notice Thrown when attempting to set an anchor state using an unregistered game.\n    error UnregisteredGame();\n\n/// @notice Thrown when attempting to set an anchor state using an invalid game result.\n    error InvalidGameStatus();\n"
    },
    "contracts/L1/dispute/lib/LibPosition.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\n    using LibPosition for Position global;\n\n/// @notice A `Position` represents a position of a claim within the game tree.\n/// @dev This is represented as a \"generalized index\" where the high-order bit\n/// is the level in the tree and the remaining bits is a unique bit pattern, allowing\n/// a unique identifier for each node in the tree. Mathematically, it is calculated\n/// as 2^{depth} + indexAtDepth.\n    type Position is uint128;\n\n/// @title LibPosition\n/// @notice This library contains helper functions for working with the `Position` type.\nlibrary LibPosition {\n    /// @notice the `MAX_POSITION_BITLEN` is the number of bits that the `Position` type, and the implementation of\n    ///         its behavior within this library, can safely support.\n    uint8 internal constant MAX_POSITION_BITLEN = 126;\n\n    /// @notice Computes a generalized index (2^{depth} + indexAtDepth).\n    /// @param _depth The depth of the position.\n    /// @param _indexAtDepth The index at the depth of the position.\n    /// @return position_ The computed generalized index.\n    function wrap(uint8 _depth, uint128 _indexAtDepth) internal pure returns (Position position_) {\n        assembly {\n        // gindex = 2^{_depth} + _indexAtDepth\n            position_ := add(shl(_depth, 1), _indexAtDepth)\n        }\n    }\n\n    /// @notice Pulls the `depth` out of a `Position` type.\n    /// @param _position The generalized index to get the `depth` of.\n    /// @return depth_ The `depth` of the `position` gindex.\n    /// @custom:attribution Solady <https://github.com/Vectorized/Solady>\n    function depth(Position _position) internal pure returns (uint8 depth_) {\n        // Return the most significant bit offset, which signifies the depth of the gindex.\n        assembly {\n            depth_ := or(depth_, shl(6, lt(0xffffffffffffffff, shr(depth_, _position))))\n            depth_ := or(depth_, shl(5, lt(0xffffffff, shr(depth_, _position))))\n\n        // For the remaining 32 bits, use a De Bruijn lookup.\n            _position := shr(depth_, _position)\n            _position := or(_position, shr(1, _position))\n            _position := or(_position, shr(2, _position))\n            _position := or(_position, shr(4, _position))\n            _position := or(_position, shr(8, _position))\n            _position := or(_position, shr(16, _position))\n\n            depth_ :=\n            or(\n                depth_,\n                byte(\n                    shr(251, mul(_position, shl(224, 0x07c4acdd))),\n                    0x0009010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f\n                )\n            )\n        }\n    }\n\n    /// @notice Pulls the `indexAtDepth` out of a `Position` type.\n    ///         The `indexAtDepth` is the left/right index of a position at a specific depth within\n    ///         the binary tree, starting from index 0. For example, at gindex 2, the `depth` = 1\n    ///         and the `indexAtDepth` = 0.\n    /// @param _position The generalized index to get the `indexAtDepth` of.\n    /// @return indexAtDepth_ The `indexAtDepth` of the `position` gindex.\n    function indexAtDepth(Position _position) internal pure returns (uint128 indexAtDepth_) {\n        // Return bits p_{msb-1}...p_{0}. This effectively pulls the 2^{depth} out of the gindex,\n        // leaving only the `indexAtDepth`.\n        uint256 msb = depth(_position);\n        assembly {\n            indexAtDepth_ := sub(_position, shl(msb, 1))\n        }\n    }\n\n    /// @notice Get the left child of `_position`.\n    /// @param _position The position to get the left position of.\n    /// @return left_ The position to the left of `position`.\n    function left(Position _position) internal pure returns (Position left_) {\n        assembly {\n            left_ := shl(1, _position)\n        }\n    }\n\n    /// @notice Get the right child of `_position`\n    /// @param _position The position to get the right position of.\n    /// @return right_ The position to the right of `position`.\n    function right(Position _position) internal pure returns (Position right_) {\n        assembly {\n            right_ := or(1, shl(1, _position))\n        }\n    }\n\n    /// @notice Get the parent position of `_position`.\n    /// @param _position The position to get the parent position of.\n    /// @return parent_ The parent position of `position`.\n    function parent(Position _position) internal pure returns (Position parent_) {\n        assembly {\n            parent_ := shr(1, _position)\n        }\n    }\n\n    /// @notice Get the deepest, right most gindex relative to the `position`. This is equivalent to\n    ///         calling `right` on a position until the maximum depth is reached.\n    /// @param _position The position to get the relative deepest, right most gindex of.\n    /// @param _maxDepth The maximum depth of the game.\n    /// @return rightIndex_ The deepest, right most gindex relative to the `position`.\n    function rightIndex(Position _position, uint256 _maxDepth) internal pure returns (Position rightIndex_) {\n        uint256 msb = depth(_position);\n        assembly {\n            let remaining := sub(_maxDepth, msb)\n            rightIndex_ := or(shl(remaining, _position), sub(shl(remaining, 1), 1))\n        }\n    }\n\n    /// @notice Get the deepest, right most trace index relative to the `position`. This is\n    ///         equivalent to calling `right` on a position until the maximum depth is reached and\n    ///         then finding its index at depth.\n    /// @param _position The position to get the relative trace index of.\n    /// @param _maxDepth The maximum depth of the game.\n    /// @return traceIndex_ The trace index relative to the `position`.\n    function traceIndex(Position _position, uint256 _maxDepth) internal pure returns (uint256 traceIndex_) {\n        uint256 msb = depth(_position);\n        assembly {\n            let remaining := sub(_maxDepth, msb)\n            traceIndex_ := sub(or(shl(remaining, _position), sub(shl(remaining, 1), 1)), shl(_maxDepth, 1))\n        }\n    }\n\n    /// @notice Gets the position of the highest ancestor of `_position` that commits to the same\n    ///         trace index.\n    /// @param _position The position to get the highest ancestor of.\n    /// @return ancestor_ The highest ancestor of `position` that commits to the same trace index.\n    function traceAncestor(Position _position) internal pure returns (Position ancestor_) {\n        // Create a field with only the lowest unset bit of `_position` set.\n        Position lsb;\n        assembly {\n            lsb := and(not(_position), add(_position, 1))\n        }\n        // Find the index of the lowest unset bit within the field.\n        uint256 msb = depth(lsb);\n        // The highest ancestor that commits to the same trace index is the original position\n        // shifted right by the index of the lowest unset bit.\n        assembly {\n            let a := shr(msb, _position)\n        // Bound the ancestor to the minimum gindex, 1.\n            ancestor_ := or(a, iszero(a))\n        }\n    }\n\n    /// @notice Gets the position of the highest ancestor of `_position` that commits to the same\n    ///         trace index, while still being below `_upperBoundExclusive`.\n    /// @param _position The position to get the highest ancestor of.\n    /// @param _upperBoundExclusive The exclusive upper depth bound, used to inform where to stop in order\n    ///                             to not escape a sub-tree.\n    /// @return ancestor_ The highest ancestor of `position` that commits to the same trace index.\n    function traceAncestorBounded(\n        Position _position,\n        uint256 _upperBoundExclusive\n    )\n    internal\n    pure\n    returns (Position ancestor_)\n    {\n        // This function only works for positions that are below the upper bound.\n        if (_position.depth() <= _upperBoundExclusive) {\n            assembly {\n            // Revert with `ClaimAboveSplit()`\n                mstore(0x00, 0xb34b5c22)\n                revert(0x1C, 0x04)\n            }\n        }\n\n        // Grab the global trace ancestor.\n        ancestor_ = traceAncestor(_position);\n\n        // If the ancestor is above or at the upper bound, shift it to be below the upper bound.\n        // This should be a special case that only covers positions that commit to the final leaf\n        // in a sub-tree.\n        if (ancestor_.depth() <= _upperBoundExclusive) {\n            ancestor_ = ancestor_.rightIndex(_upperBoundExclusive + 1);\n        }\n    }\n\n    /// @notice Get the move position of `_position`, which is the left child of:\n    ///         1. `_position` if `_isAttack` is true.\n    ///         2. `_position | 1` if `_isAttack` is false.\n    /// @param _position The position to get the relative attack/defense position of.\n    /// @param _isAttack Whether or not the move is an attack move.\n    /// @return move_ The move position relative to `position`.\n    function move(Position _position, bool _isAttack) internal pure returns (Position move_) {\n        assembly {\n            move_ := shl(1, or(iszero(_isAttack), _position))\n        }\n    }\n\n    /// @notice Get the value of a `Position` type in the form of the underlying uint128.\n    /// @param _position The position to get the value of.\n    /// @return raw_ The value of the `position` as a uint128 type.\n    function raw(Position _position) internal pure returns (uint128 raw_) {\n        assembly {\n            raw_ := _position\n        }\n    }\n}\n"
    },
    "contracts/L1/dispute/lib/LibUDT.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\nimport \"./LibPosition.sol\";\n\nusing LibClaim for Claim global;\nusing LibHash for Hash global;\nusing LibDuration for Duration global;\nusing LibClock for Clock global;\nusing LibGameId for GameId global;\nusing LibTimestamp for Timestamp global;\nusing LibVMStatus for VMStatus global;\nusing LibGameType for GameType global;\n\n/// @notice A `Clock` represents a packed `Duration` and `Timestamp`\n/// @dev The packed layout of this type is as follows:\n/// ┌────────────┬────────────────┐\n/// │    Bits    │     Value      │\n/// ├────────────┼────────────────┤\n/// │ [0, 64)    │ Duration       │\n/// │ [64, 128)  │ Timestamp      │\n/// └────────────┴────────────────┘\n    type Clock is uint128;\n\n/// @title LibClock\n/// @notice This library contains helper functions for working with the `Clock` type.\nlibrary LibClock {\n    /// @notice Packs a `Duration` and `Timestamp` into a `Clock` type.\n    /// @param _duration The `Duration` to pack into the `Clock` type.\n    /// @param _timestamp The `Timestamp` to pack into the `Clock` type.\n    /// @return clock_ The `Clock` containing the `_duration` and `_timestamp`.\n    function wrap(Duration _duration, Timestamp _timestamp) internal pure returns (Clock clock_) {\n        assembly {\n            clock_ := or(shl(0x40, _duration), _timestamp)\n        }\n    }\n\n    /// @notice Pull the `Duration` out of a `Clock` type.\n    /// @param _clock The `Clock` type to pull the `Duration` out of.\n    /// @return duration_ The `Duration` pulled out of `_clock`.\n    function duration(Clock _clock) internal pure returns (Duration duration_) {\n        // Shift the high-order 64 bits into the low-order 64 bits, leaving only the `duration`.\n        assembly {\n            duration_ := shr(0x40, _clock)\n        }\n    }\n\n    /// @notice Pull the `Timestamp` out of a `Clock` type.\n    /// @param _clock The `Clock` type to pull the `Timestamp` out of.\n    /// @return timestamp_ The `Timestamp` pulled out of `_clock`.\n    function timestamp(Clock _clock) internal pure returns (Timestamp timestamp_) {\n        // Clean the high-order 192 bits by shifting the clock left and then right again, leaving\n        // only the `timestamp`.\n        assembly {\n            timestamp_ := shr(0xC0, shl(0xC0, _clock))\n        }\n    }\n\n    /// @notice Get the value of a `Clock` type in the form of the underlying uint128.\n    /// @param _clock The `Clock` type to get the value of.\n    /// @return clock_ The value of the `Clock` type as a uint128 type.\n    function raw(Clock _clock) internal pure returns (uint128 clock_) {\n        assembly {\n            clock_ := _clock\n        }\n    }\n}\n\n/// @notice A `GameId` represents a packed 4 byte game ID, a 8 byte timestamp, and a 20 byte address.\n/// @dev The packed layout of this type is as follows:\n/// ┌───────────┬───────────┐\n/// │   Bits    │   Value   │\n/// ├───────────┼───────────┤\n/// │ [0, 32)   │ Game Type │\n/// │ [32, 96)  │ Timestamp │\n/// │ [96, 256) │ Address   │\n/// └───────────┴───────────┘\n    type GameId is bytes32;\n\n/// @title LibGameId\n/// @notice Utility functions for packing and unpacking GameIds.\nlibrary LibGameId {\n    /// @notice Packs values into a 32 byte GameId type.\n    /// @param _gameType The game type.\n    /// @param _timestamp The timestamp of the game's creation.\n    /// @param _gameProxy The game proxy address.\n    /// @return gameId_ The packed GameId.\n    function pack(\n        GameType _gameType,\n        Timestamp _timestamp,\n        address _gameProxy\n    )\n    internal\n    pure\n    returns (GameId gameId_)\n    {\n        assembly {\n            gameId_ := or(or(shl(224, _gameType), shl(160, _timestamp)), _gameProxy)\n        }\n    }\n\n    /// @notice Unpacks values from a 32 byte GameId type.\n    /// @param _gameId The packed GameId.\n    /// @return gameType_ The game type.\n    /// @return timestamp_ The timestamp of the game's creation.\n    /// @return gameProxy_ The game proxy address.\n    function unpack(GameId _gameId)\n    internal\n    pure\n    returns (GameType gameType_, Timestamp timestamp_, address gameProxy_)\n    {\n        assembly {\n            gameType_ := shr(224, _gameId)\n            timestamp_ := and(shr(160, _gameId), 0xFFFFFFFFFFFFFFFF)\n            gameProxy_ := and(_gameId, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\n        }\n    }\n}\n\n/// @notice A claim represents an MPT root representing the state of the fault proof program.\n    type Claim is bytes32;\n\n/// @title LibClaim\n/// @notice This library contains helper functions for working with the `Claim` type.\nlibrary LibClaim {\n    /// @notice Get the value of a `Claim` type in the form of the underlying bytes32.\n    /// @param _claim The `Claim` type to get the value of.\n    /// @return claim_ The value of the `Claim` type as a bytes32 type.\n    function raw(Claim _claim) internal pure returns (bytes32 claim_) {\n        assembly {\n            claim_ := _claim\n        }\n    }\n\n    /// @notice Hashes a claim and a position together.\n    /// @param _claim A Claim type.\n    /// @param _position The position of `claim`.\n    /// @param _challengeIndex The index of the claim being moved against.\n    /// @return claimHash_ A hash of abi.encodePacked(claim, position|challengeIndex);\n    function hashClaimPos(\n        Claim _claim,\n        Position _position,\n        uint256 _challengeIndex\n    )\n    internal\n    pure\n    returns (Hash claimHash_)\n    {\n        assembly {\n            mstore(0x00, _claim)\n            mstore(0x20, or(shl(128, _position), and(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, _challengeIndex)))\n            claimHash_ := keccak256(0x00, 0x40)\n        }\n    }\n}\n\n/// @notice A dedicated duration type.\n/// @dev Unit: seconds\n    type Duration is uint64;\n\n/// @title LibDuration\n/// @notice This library contains helper functions for working with the `Duration` type.\nlibrary LibDuration {\n    /// @notice Get the value of a `Duration` type in the form of the underlying uint64.\n    /// @param _duration The `Duration` type to get the value of.\n    /// @return duration_ The value of the `Duration` type as a uint64 type.\n    function raw(Duration _duration) internal pure returns (uint64 duration_) {\n        assembly {\n            duration_ := _duration\n        }\n    }\n}\n\n/// @notice A custom type for a generic hash.\n    type Hash is bytes32;\n\n/// @title LibHash\n/// @notice This library contains helper functions for working with the `Hash` type.\nlibrary LibHash {\n    /// @notice Get the value of a `Hash` type in the form of the underlying bytes32.\n    /// @param _hash The `Hash` type to get the value of.\n    /// @return hash_ The value of the `Hash` type as a bytes32 type.\n    function raw(Hash _hash) internal pure returns (bytes32 hash_) {\n        assembly {\n            hash_ := _hash\n        }\n    }\n}\n\n/// @notice A dedicated timestamp type.\n    type Timestamp is uint64;\n\n/// @title LibTimestamp\n/// @notice This library contains helper functions for working with the `Timestamp` type.\nlibrary LibTimestamp {\n    /// @notice Get the value of a `Timestamp` type in the form of the underlying uint64.\n    /// @param _timestamp The `Timestamp` type to get the value of.\n    /// @return timestamp_ The value of the `Timestamp` type as a uint64 type.\n    function raw(Timestamp _timestamp) internal pure returns (uint64 timestamp_) {\n        assembly {\n            timestamp_ := _timestamp\n        }\n    }\n}\n\n/// @notice A `VMStatus` represents the status of a VM execution.\n    type VMStatus is uint8;\n\n/// @title LibVMStatus\n/// @notice This library contains helper functions for working with the `VMStatus` type.\nlibrary LibVMStatus {\n    /// @notice Get the value of a `VMStatus` type in the form of the underlying uint8.\n    /// @param _vmstatus The `VMStatus` type to get the value of.\n    /// @return vmstatus_ The value of the `VMStatus` type as a uint8 type.\n    function raw(VMStatus _vmstatus) internal pure returns (uint8 vmstatus_) {\n        assembly {\n            vmstatus_ := _vmstatus\n        }\n    }\n}\n\n/// @notice A `GameType` represents the type of game being played.\n    type GameType is uint32;\n\n/// @title LibGameType\n/// @notice This library contains helper functions for working with the `GameType` type.\nlibrary LibGameType {\n    /// @notice Get the value of a `GameType` type in the form of the underlying uint32.\n    /// @param _gametype The `GameType` type to get the value of.\n    /// @return gametype_ The value of the `GameType` type as a uint32 type.\n    function raw(GameType _gametype) internal pure returns (uint32 gametype_) {\n        assembly {\n            gametype_ := _gametype\n        }\n    }\n}\n"
    },
    "contracts/L1/dispute/lib/Types.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\nimport \"./LibUDT.sol\";\n\n/// @notice The current status of the dispute game.\n    enum GameStatus {\n        // The game is currently in progress, and has not been resolved.\n        IN_PROGRESS,\n        // The game has concluded, and the `rootClaim` was challenged successfully.\n        CHALLENGER_WINS,\n        // The game has concluded, and the `rootClaim` could not be contested.\n        DEFENDER_WINS\n    }\n\n/// @notice Represents an L2 output root and the L2 block number at which it was generated.\n/// @custom:field root The output root.\n/// @custom:field l2BlockNumber The L2 block number at which the output root was generated.\n    struct OutputRoot {\n        Hash root;\n        uint256 l2BlockNumber;\n    }\n\n/// @title GameTypes\n/// @notice A library that defines the IDs of games that can be played.\nlibrary GameTypes {\n    /// @dev A dispute game type the uses the cannon vm.\n    GameType internal constant CANNON = GameType.wrap(0);\n\n    /// @dev A permissioned dispute game type the uses the cannon vm.\n    GameType internal constant PERMISSIONED_CANNON = GameType.wrap(1);\n\n    /// @notice A dispute game type the uses the asterisc VM\n    GameType internal constant ASTERISC = GameType.wrap(2);\n\n    /// @notice A dispute game type with short game duration for testing withdrawals.\n    ///         Not intended for production use.\n    GameType internal constant FAST = GameType.wrap(254);\n\n    /// @notice A dispute game type that uses an alphabet vm.\n    ///         Not intended for production use.\n    GameType internal constant ALPHABET = GameType.wrap(255);\n}\n\n/// @title VMStatuses\n/// @notice Named type aliases for the various valid VM status bytes.\nlibrary VMStatuses {\n    /// @notice The VM has executed successfully and the outcome is valid.\n    VMStatus internal constant VALID = VMStatus.wrap(0);\n\n    /// @notice The VM has executed successfully and the outcome is invalid.\n    VMStatus internal constant INVALID = VMStatus.wrap(1);\n\n    /// @notice The VM has paniced.\n    VMStatus internal constant PANIC = VMStatus.wrap(2);\n\n    /// @notice The VM execution is still in progress.\n    VMStatus internal constant UNFINISHED = VMStatus.wrap(3);\n}\n\n/// @title LocalPreimageKey\n/// @notice Named type aliases for local `PreimageOracle` key identifiers.\nlibrary LocalPreimageKey {\n    /// @notice The identifier for the L1 head hash.\n    uint256 internal constant L1_HEAD_HASH = 0x01;\n\n    /// @notice The identifier for the starting output root.\n    uint256 internal constant STARTING_OUTPUT_ROOT = 0x02;\n\n    /// @notice The identifier for the disputed output root.\n    uint256 internal constant DISPUTED_OUTPUT_ROOT = 0x03;\n\n    /// @notice The identifier for the disputed L2 block number.\n    uint256 internal constant DISPUTED_L2_BLOCK_NUMBER = 0x04;\n\n    /// @notice The identifier for the chain ID.\n    uint256 internal constant CHAIN_ID = 0x05;\n}\n"
    },
    "contracts/L1/rollup/IChainStorageContainer.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity >0.5.0 <0.9.0;\n\n/**\n * @title IChainStorageContainer\n */\ninterface IChainStorageContainer {\n    /********************\n     * Public Functions *\n     ********************/\n\n    /**\n     * Sets the container's global metadata field. We're using `bytes27` here because we use five\n     * bytes to maintain the length of the underlying data structure, meaning we have an extra\n     * 27 bytes to store arbitrary data.\n     * @param _globalMetadata New global metadata to set.\n     */\n    function setGlobalMetadata(bytes27 _globalMetadata) external;\n\n    /**\n     * Retrieves the container's global metadata field.\n     * @return Container global metadata field.\n     */\n    function getGlobalMetadata() external view returns (bytes27);\n\n    /**\n     * Retrieves the number of objects stored in the container.\n     * @return Number of objects in the container.\n     */\n    function length() external view returns (uint256);\n\n    /**\n     * Pushes an object into the container.\n     * @param _object A 32 byte value to insert into the container.\n     */\n    function push(bytes32 _object) external;\n\n    /**\n     * Pushes an object into the container. Function allows setting the global metadata since\n     * we'll need to touch the \"length\" storage slot anyway, which also contains the global\n     * metadata (it's an optimization).\n     * @param _object A 32 byte value to insert into the container.\n     * @param _globalMetadata New global metadata for the container.\n     */\n    function push(bytes32 _object, bytes27 _globalMetadata) external;\n\n    /**\n     * Set an object into the container. Function allows setting the global metadata since\n     * we'll need to touch the \"length\" storage slot anyway, which also contains the global\n     * metadata (it's an optimization).\n     * @param _index position.\n     * @param _object A 32 byte value to insert into the container.\n     */\n    function setByChainId(\n        uint256 _chainId,\n        uint256 _index,\n        bytes32 _object\n    ) external;\n\n    /**\n     * Retrieves an object from the container.\n     * @param _index Index of the particular object to access.\n     * @return 32 byte object value.\n     */\n    function get(uint256 _index) external view returns (bytes32);\n\n    /**\n     * Removes all objects after and including a given index.\n     * @param _index Object index to delete from.\n     */\n    function deleteElementsAfterInclusive(uint256 _index) external;\n\n    /**\n     * Removes all objects after and including a given index. Also allows setting the global\n     * metadata field.\n     * @param _index Object index to delete from.\n     * @param _globalMetadata New global metadata for the container.\n     */\n    function deleteElementsAfterInclusive(uint256 _index, bytes27 _globalMetadata) external;\n\n    /**\n     * Sets the container's global metadata field. We're using `bytes27` here because we use five\n     * bytes to maintain the length of the underlying data structure, meaning we have an extra\n     * 27 bytes to store arbitrary data.\n     * @param _chainId identity for the l2 chain.\n     * @param _globalMetadata New global metadata to set.\n     */\n    function setGlobalMetadataByChainId(uint256 _chainId, bytes27 _globalMetadata) external;\n\n    /**\n     * Retrieves the container's global metadata field.\n     * @param _chainId identity for the l2 chain.\n     * @return Container global metadata field.\n     */\n    function getGlobalMetadataByChainId(uint256 _chainId) external view returns (bytes27);\n\n    /**\n     * Retrieves the number of objects stored in the container.\n     * @param _chainId identity for the l2 chain.\n     * @return Number of objects in the container.\n     */\n    function lengthByChainId(uint256 _chainId) external view returns (uint256);\n\n    /**\n     * Pushes an object into the container.\n     * @param _chainId identity for the l2 chain.\n     * @param _object A 32 byte value to insert into the container.\n     */\n    function pushByChainId(uint256 _chainId, bytes32 _object) external;\n\n    /**\n     * Pushes an object into the container. Function allows setting the global metadata since\n     * we'll need to touch the \"length\" storage slot anyway, which also contains the global\n     * metadata (it's an optimization).\n     * @param _chainId identity for the l2 chain.\n     * @param _object A 32 byte value to insert into the container.\n     * @param _globalMetadata New global metadata for the container.\n     */\n    function pushByChainId(\n        uint256 _chainId,\n        bytes32 _object,\n        bytes27 _globalMetadata\n    ) external;\n\n    /**\n     * Retrieves an object from the container.\n     * @param _chainId identity for the l2 chain.\n     * @param _index Index of the particular object to access.\n     * @return 32 byte object value.\n     */\n    function getByChainId(uint256 _chainId, uint256 _index) external view returns (bytes32);\n\n    /**\n     * Removes all objects after and including a given index.\n     * @param _chainId identity for the l2 chain.\n     * @param _index Object index to delete from.\n     */\n    function deleteElementsAfterInclusiveByChainId(uint256 _chainId, uint256 _index) external;\n\n    /**\n     * Removes all objects after and including a given index. Also allows setting the global\n     * metadata field.\n     * @param _chainId identity for the l2 chain.\n     * @param _index Object index to delete from.\n     * @param _globalMetadata New global metadata for the container.\n     */\n    function deleteElementsAfterInclusiveByChainId(\n        uint256 _chainId,\n        uint256 _index,\n        bytes27 _globalMetadata\n    ) external;\n}\n"
    },
    "contracts/L1/rollup/IMVMStateCommitmentChain.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity >0.5.0 <0.9.0;\n\n/* Library Imports */\nimport { Lib_OVMCodec } from \"../../libraries/codec/Lib_OVMCodec.sol\";\nimport { IChainStorageContainer } from \"./IChainStorageContainer.sol\";\n\n/**\n * @title IStateCommitmentChain\n */\ninterface IMVMStateCommitmentChain {\n    /**********\n     * Events *\n     **********/\n\n    event StateBatchAppended(\n        uint256 _chainId,\n        uint256 indexed _batchIndex,\n        bytes32 _batchRoot,\n        uint256 _batchSize,\n        uint256 _prevTotalElements,\n        bytes _extraData\n    );\n\n    event StateBatchDeleted(uint256 _chainId, uint256 indexed _batchIndex, bytes32 _batchRoot);\n\n    /********************\n     * Public Functions *\n     ********************/\n\n    /**\n     * Get the earliest disputable state root.\n     * @param _chainId chain id for the l2 chain.\n     * @return _earliestDisputableBatch Earliest disputable state root.\n     */\n    function findEarliestDisputableBatch(uint256 _chainId) external view returns (bytes32 _earliestDisputableBatch, uint256 blockNumber);\n\n    function batches() external view returns (IChainStorageContainer);\n\n    /**\n     * Retrieves the total number of elements submitted.\n     * @return _totalElements Total submitted elements.\n     */\n    function getTotalElements() external view returns (uint256 _totalElements);\n\n    /**\n     * Retrieves the total number of batches submitted.\n     * @return _totalBatches Total submitted batches.\n     */\n    function getTotalBatches() external view returns (uint256 _totalBatches);\n\n    /**\n     * Retrieves the timestamp of the last batch submitted by the sequencer.\n     * @return _lastSequencerTimestamp Last sequencer batch timestamp.\n     */\n    function getLastSequencerTimestamp() external view returns (uint256 _lastSequencerTimestamp);\n\n    /**\n     * Appends a batch of state roots to the chain.\n     * @param _batch Batch of state roots.\n     * @param _shouldStartAtElement Index of the element at which this batch should start.\n     * @param _lastBatchBlockHash Block hash of the last batch.\n     * @param _lastBatchBlockNumber Block number of the last batch.\n     */\n    function appendStateBatch(bytes32[] calldata _batch, uint256 _shouldStartAtElement, bytes32 _lastBatchBlockHash, uint256 _lastBatchBlockNumber) external;\n\n    /**\n     * Deletes all state roots after (and including) a given batch.\n     * @param _batchHeader Header of the batch to start deleting from.\n     */\n    function deleteStateBatch(Lib_OVMCodec.ChainBatchHeader memory _batchHeader) external;\n\n    /**\n     * Verifies a batch inclusion proof.\n     * @param _element Hash of the element to verify a proof for.\n     * @param _batchHeader Header of the batch in which the element was included.\n     * @param _proof Merkle inclusion proof for the element.\n     */\n    function verifyStateCommitment(\n        bytes32 _element,\n        Lib_OVMCodec.ChainBatchHeader memory _batchHeader,\n        Lib_OVMCodec.ChainInclusionProof memory _proof\n    ) external view returns (bool _verified);\n\n    /**\n     * Checks whether a given batch is still inside its fraud proof window.\n     * @param _batchHeader Header of the batch to check.\n     * @return _inside Whether or not the batch is inside the fraud proof window.\n     */\n    function insideFraudProofWindow(Lib_OVMCodec.ChainBatchHeader memory _batchHeader)\n        external\n        view\n        returns (bool _inside);\n\n    /**\n     * Saves a batch as disputed.\n     * @param stateHeaderHash Hash of the disputed state header.\n     */\n    function saveDisputedBatch(bytes32 stateHeaderHash) external;\n\n    /**\n     * Checks if a batch is disputed.\n     * @param stateHeaderHash Hash of the disputed state header.\n     * @return _disputed Whether or not the batch is disputed.\n     */\n    function isDisputedBatch(bytes32 stateHeaderHash) external view returns (bool _disputed);\n\n    /********************\n     * chain id added func *\n     ********************/\n\n    /**\n     * Retrieves the total number of elements submitted.\n     * @param _chainId identity for the l2 chain.\n     * @return _totalElements Total submitted elements.\n     */\n    function getTotalElementsByChainId(uint256 _chainId)\n        external\n        view\n        returns (uint256 _totalElements);\n\n    /**\n     * Retrieves the total number of batches submitted.\n     * @param _chainId identity for the l2 chain.\n     * @return _totalBatches Total submitted batches.\n     */\n    function getTotalBatchesByChainId(uint256 _chainId)\n        external\n        view\n        returns (uint256 _totalBatches);\n\n    /**\n     * Retrieves the timestamp of the last batch submitted by the sequencer.\n     * @param _chainId identity for the l2 chain.\n     * @return _lastSequencerTimestamp Last sequencer batch timestamp.\n     */\n    function getLastSequencerTimestampByChainId(uint256 _chainId)\n        external\n        view\n        returns (uint256 _lastSequencerTimestamp);\n\n    /**\n     * Appends a batch of state roots to the chain.\n     * @param _chainId identity for the l2 chain.\n     * @param _batch Batch of state roots.\n     * @param _shouldStartAtElement Index of the element at which this batch should start.\n     * @param _proposer proposer of the batch\n     * @param _lastBatchBlockHash Block hash of the last batch.\n     * @param _lastBatchBlockNumber Block number of the last batch.\n     */\n    function appendStateBatchByChainId(\n        uint256 _chainId,\n        bytes32[] calldata _batch,\n        uint256 _shouldStartAtElement,\n        string calldata _proposer,\n        bytes32 _lastBatchBlockHash,\n        uint256 _lastBatchBlockNumber\n    ) external;\n\n    /**\n     * Deletes all state roots after (and including) a given batch.\n     * @param _chainId identity for the l2 chain.\n     * @param _batchHeader Header of the batch to start deleting from.\n     */\n    function deleteStateBatchByChainId(\n        uint256 _chainId,\n        Lib_OVMCodec.ChainBatchHeader memory _batchHeader\n    ) external;\n\n    /**\n     * Verifies a batch inclusion proof.\n     * @param _chainId identity for the l2 chain.\n     * @param _element Hash of the element to verify a proof for.\n     * @param _batchHeader Header of the batch in which the element was included.\n     * @param _proof Merkle inclusion proof for the element.\n     */\n    function verifyStateCommitmentByChainId(\n        uint256 _chainId,\n        bytes32 _element,\n        Lib_OVMCodec.ChainBatchHeader memory _batchHeader,\n        Lib_OVMCodec.ChainInclusionProof memory _proof\n    ) external view returns (bool _verified);\n\n    /**\n     * Checks whether a given batch is still inside its fraud proof window.\n     * @param _chainId identity for the l2 chain.\n     * @param _batchHeader Header of the batch to check.\n     * @return _inside Whether or not the batch is inside the fraud proof window.\n     */\n    function insideFraudProofWindowByChainId(\n        uint256 _chainId,\n        Lib_OVMCodec.ChainBatchHeader memory _batchHeader\n    ) external view returns (bool _inside);\n}\n"
    },
    "contracts/L1/rollup/IStateCommitmentChain.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity >0.5.0 <0.9.0;\n\n/* Library Imports */\nimport { Lib_OVMCodec } from \"../../libraries/codec/Lib_OVMCodec.sol\";\nimport { IChainStorageContainer } from \"./IChainStorageContainer.sol\";\n\n/**\n * @title IStateCommitmentChain\n */\ninterface IStateCommitmentChain {\n    /**********\n     * Events *\n     **********/\n\n    event StateBatchAppended(\n        uint256 _chainId,\n        uint256 indexed _batchIndex,\n        bytes32 _batchRoot,\n        uint256 _batchSize,\n        uint256 _prevTotalElements,\n        bytes _extraData\n    );\n\n    event StateBatchDeleted(uint256 _chainId, uint256 indexed _batchIndex, bytes32 _batchRoot);\n\n    /********************\n     * Public Functions *\n     ********************/\n\n    function batches() external view returns (IChainStorageContainer);\n\n    /**\n     * Retrieves the total number of elements submitted.\n     * @return _totalElements Total submitted elements.\n     */\n    function getTotalElements() external view returns (uint256 _totalElements);\n\n    /**\n     * Retrieves the total number of batches submitted.\n     * @return _totalBatches Total submitted batches.\n     */\n    function getTotalBatches() external view returns (uint256 _totalBatches);\n\n    /**\n     * Retrieves the timestamp of the last batch submitted by the sequencer.\n     * @return _lastSequencerTimestamp Last sequencer batch timestamp.\n     */\n    function getLastSequencerTimestamp() external view returns (uint256 _lastSequencerTimestamp);\n\n    /**\n     * Appends a batch of state roots to the chain.\n     * @param _batch Batch of state roots.\n     * @param _shouldStartAtElement Index of the element at which this batch should start.\n     */\n    function appendStateBatch(bytes32[] calldata _batch, uint256 _shouldStartAtElement) external;\n\n    /**\n     * Deletes all state roots after (and including) a given batch.\n     * @param _batchHeader Header of the batch to start deleting from.\n     */\n    function deleteStateBatch(Lib_OVMCodec.ChainBatchHeader memory _batchHeader) external;\n\n    /**\n     * Verifies a batch inclusion proof.\n     * @param _element Hash of the element to verify a proof for.\n     * @param _batchHeader Header of the batch in which the element was included.\n     * @param _proof Merkle inclusion proof for the element.\n     */\n    function verifyStateCommitment(\n        bytes32 _element,\n        Lib_OVMCodec.ChainBatchHeader memory _batchHeader,\n        Lib_OVMCodec.ChainInclusionProof memory _proof\n    ) external view returns (bool _verified);\n\n    /**\n     * Checks whether a given batch is still inside its fraud proof window.\n     * @param _batchHeader Header of the batch to check.\n     * @return _inside Whether or not the batch is inside the fraud proof window.\n     */\n    function insideFraudProofWindow(Lib_OVMCodec.ChainBatchHeader memory _batchHeader)\n        external\n        view\n        returns (bool _inside);\n\n    /********************\n     * chain id added func *\n     ********************/\n\n    /**\n     * Retrieves the total number of elements submitted.\n     * @param _chainId identity for the l2 chain.\n     * @return _totalElements Total submitted elements.\n     */\n    function getTotalElementsByChainId(uint256 _chainId)\n        external\n        view\n        returns (uint256 _totalElements);\n\n    /**\n     * Retrieves the total number of batches submitted.\n     * @param _chainId identity for the l2 chain.\n     * @return _totalBatches Total submitted batches.\n     */\n    function getTotalBatchesByChainId(uint256 _chainId)\n        external\n        view\n        returns (uint256 _totalBatches);\n\n    /**\n     * Retrieves the timestamp of the last batch submitted by the sequencer.\n     * @param _chainId identity for the l2 chain.\n     * @return _lastSequencerTimestamp Last sequencer batch timestamp.\n     */\n    function getLastSequencerTimestampByChainId(uint256 _chainId)\n        external\n        view\n        returns (uint256 _lastSequencerTimestamp);\n\n    /**\n     * Appends a batch of state roots to the chain.\n     * @param _chainId identity for the l2 chain.\n     * @param _batch Batch of state roots.\n     * @param _shouldStartAtElement Index of the element at which this batch should start.\n     */\n    function appendStateBatchByChainId(\n        uint256 _chainId,\n        bytes32[] calldata _batch,\n        uint256 _shouldStartAtElement,\n        string calldata proposer\n    ) external;\n\n    /**\n     * Deletes all state roots after (and including) a given batch.\n     * @param _chainId identity for the l2 chain.\n     * @param _batchHeader Header of the batch to start deleting from.\n     */\n    function deleteStateBatchByChainId(\n        uint256 _chainId,\n        Lib_OVMCodec.ChainBatchHeader memory _batchHeader\n    ) external;\n\n    /**\n     * Verifies a batch inclusion proof.\n     * @param _chainId identity for the l2 chain.\n     * @param _element Hash of the element to verify a proof for.\n     * @param _batchHeader Header of the batch in which the element was included.\n     * @param _proof Merkle inclusion proof for the element.\n     */\n    function verifyStateCommitmentByChainId(\n        uint256 _chainId,\n        bytes32 _element,\n        Lib_OVMCodec.ChainBatchHeader memory _batchHeader,\n        Lib_OVMCodec.ChainInclusionProof memory _proof\n    ) external view returns (bool _verified);\n\n    /**\n     * Checks whether a given batch is still inside its fraud proof window.\n     * @param _chainId identity for the l2 chain.\n     * @param _batchHeader Header of the batch to check.\n     * @return _inside Whether or not the batch is inside the fraud proof window.\n     */\n    function insideFraudProofWindowByChainId(\n        uint256 _chainId,\n        Lib_OVMCodec.ChainBatchHeader memory _batchHeader\n    ) external view returns (bool _inside);\n}\n"
    },
    "contracts/L1/verification/IBondManager.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/**\n * @title IBondManager\n */\ninterface IBondManager {\n    /********************\n     * Public Functions *\n     ********************/\n\n    function isCollateralized(address _who) external view returns (bool);\n\n    function isCollateralizedByChainId(\n        uint256 _chainId,\n        address _who,\n        address _prop\n    ) external view returns (bool);\n}\n"
    },
    "contracts/libraries/codec/Lib_OVMCodec.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/* Library Imports */\nimport { Lib_RLPReader } from \"../rlp/Lib_RLPReader.sol\";\n\n/**\n * @title Lib_OVMCodec\n */\nlibrary Lib_OVMCodec {\n    /*********\n     * Enums *\n     *********/\n\n    enum QueueOrigin {\n        SEQUENCER_QUEUE,\n        L1TOL2_QUEUE\n    }\n\n    /***********\n     * Structs *\n     ***********/\n\n    struct EVMAccount {\n        uint256 nonce;\n        uint256 balance;\n        bytes32 storageRoot;\n        bytes32 codeHash;\n    }\n\n    struct ChainBatchHeader {\n        uint256 batchIndex;\n        bytes32 batchRoot;\n        uint256 batchSize;\n        uint256 prevTotalElements;\n        bytes extraData;\n    }\n\n    struct ChainInclusionProof {\n        uint256 index;\n        bytes32[] siblings;\n    }\n\n    struct Transaction {\n        uint256 timestamp;\n        uint256 blockNumber;\n        QueueOrigin l1QueueOrigin;\n        address l1TxOrigin;\n        address entrypoint;\n        uint256 gasLimit;\n        bytes data;\n    }\n\n    struct TransactionChainElement {\n        bool isSequenced;\n        uint256 queueIndex; // QUEUED TX ONLY\n        uint256 timestamp; // SEQUENCER TX ONLY\n        uint256 blockNumber; // SEQUENCER TX ONLY\n        bytes txData; // SEQUENCER TX ONLY\n    }\n\n    struct QueueElement {\n        bytes32 transactionHash;\n        uint40 timestamp;\n        uint40 blockNumber;\n    }\n\n    /**********************\n     * Internal Functions *\n     **********************/\n\n    /**\n     * Encodes a standard OVM transaction.\n     * @param _transaction OVM transaction to encode.\n     * @return Encoded transaction bytes.\n     */\n    function encodeTransaction(Transaction memory _transaction)\n        internal\n        pure\n        returns (bytes memory)\n    {\n        return\n            abi.encodePacked(\n                _transaction.timestamp,\n                _transaction.blockNumber,\n                _transaction.l1QueueOrigin,\n                _transaction.l1TxOrigin,\n                _transaction.entrypoint,\n                _transaction.gasLimit,\n                _transaction.data\n            );\n    }\n\n    /**\n     * Hashes a standard OVM transaction.\n     * @param _transaction OVM transaction to encode.\n     * @return Hashed transaction\n     */\n    function hashTransaction(Transaction memory _transaction) internal pure returns (bytes32) {\n        return keccak256(encodeTransaction(_transaction));\n    }\n\n    /**\n     * @notice Decodes an RLP-encoded account state into a useful struct.\n     * @param _encoded RLP-encoded account state.\n     * @return Account state struct.\n     */\n    function decodeEVMAccount(bytes memory _encoded) internal pure returns (EVMAccount memory) {\n        Lib_RLPReader.RLPItem[] memory accountState = Lib_RLPReader.readList(_encoded);\n\n        return\n            EVMAccount({\n                nonce: Lib_RLPReader.readUint256(accountState[0]),\n                balance: Lib_RLPReader.readUint256(accountState[1]),\n                storageRoot: Lib_RLPReader.readBytes32(accountState[2]),\n                codeHash: Lib_RLPReader.readBytes32(accountState[3])\n            });\n    }\n\n    /**\n     * Calculates a hash for a given batch header.\n     * @param _batchHeader Header to hash.\n     * @return Hash of the header.\n     */\n    function hashBatchHeader(Lib_OVMCodec.ChainBatchHeader memory _batchHeader)\n        internal\n        pure\n        returns (bytes32)\n    {\n        return\n            keccak256(\n                abi.encode(\n                    _batchHeader.batchRoot,\n                    _batchHeader.batchSize,\n                    _batchHeader.prevTotalElements,\n                    _batchHeader.extraData\n                )\n            );\n    }\n}\n"
    },
    "contracts/libraries/resolver/Lib_AddressManager.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/* External Imports */\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @title Lib_AddressManager\n */\ncontract Lib_AddressManager is Ownable {\n    /**********\n     * Events *\n     **********/\n\n    event AddressSet(string indexed _name, address _newAddress, address _oldAddress);\n\n    /*************\n     * Variables *\n     *************/\n\n    mapping(bytes32 => address) private addresses;\n\n    /********************\n     * Public Functions *\n     ********************/\n\n    /**\n     * Changes the address associated with a particular name.\n     * @param _name String name to associate an address with.\n     * @param _address Address to associate with the name.\n     */\n    function setAddress(string memory _name, address _address) external onlyOwner {\n        bytes32 nameHash = _getNameHash(_name);\n        address oldAddress = addresses[nameHash];\n        addresses[nameHash] = _address;\n\n        emit AddressSet(_name, _address, oldAddress);\n    }\n\n    /**\n     * Retrieves the address associated with a given name.\n     * @param _name Name to retrieve an address for.\n     * @return Address associated with the given name.\n     */\n    function getAddress(string memory _name) external view returns (address) {\n        return addresses[_getNameHash(_name)];\n    }\n\n    /**********************\n     * Internal Functions *\n     **********************/\n\n    /**\n     * Computes the hash of a name.\n     * @param _name Name to compute a hash for.\n     * @return Hash of the given name.\n     */\n    function _getNameHash(string memory _name) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(_name));\n    }\n}\n"
    },
    "contracts/libraries/resolver/Lib_AddressResolver.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/* Library Imports */\nimport { Lib_AddressManager } from \"./Lib_AddressManager.sol\";\n\n/**\n * @title Lib_AddressResolver\n */\nabstract contract Lib_AddressResolver {\n    /*************\n     * Variables *\n     *************/\n\n    Lib_AddressManager public libAddressManager;\n\n    /***************\n     * Constructor *\n     ***************/\n\n    /**\n     * @param _libAddressManager Address of the Lib_AddressManager.\n     */\n    constructor(address _libAddressManager) {\n        libAddressManager = Lib_AddressManager(_libAddressManager);\n    }\n\n    /********************\n     * Public Functions *\n     ********************/\n\n    /**\n     * Resolves the address associated with a given name.\n     * @param _name Name to resolve an address for.\n     * @return Address associated with the given name.\n     */\n    function resolve(string memory _name) public view returns (address) {\n        return libAddressManager.getAddress(_name);\n    }\n}\n"
    },
    "contracts/libraries/rlp/Lib_RLPReader.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/**\n * @title Lib_RLPReader\n * @dev Adapted from \"RLPReader\" by Hamdi Allam (hamdi.allam97@gmail.com).\n */\nlibrary Lib_RLPReader {\n    /*************\n     * Constants *\n     *************/\n\n    uint256 internal constant MAX_LIST_LENGTH = 32;\n\n    /*********\n     * Enums *\n     *********/\n\n    enum RLPItemType {\n        DATA_ITEM,\n        LIST_ITEM\n    }\n\n    /***********\n     * Structs *\n     ***********/\n\n    struct RLPItem {\n        uint256 length;\n        uint256 ptr;\n    }\n\n    /**********************\n     * Internal Functions *\n     **********************/\n\n    /**\n     * Converts bytes to a reference to memory position and length.\n     * @param _in Input bytes to convert.\n     * @return Output memory reference.\n     */\n    function toRLPItem(bytes memory _in) internal pure returns (RLPItem memory) {\n        uint256 ptr;\n        assembly {\n            ptr := add(_in, 32)\n        }\n\n        return RLPItem({ length: _in.length, ptr: ptr });\n    }\n\n    /**\n     * Reads an RLP list value into a list of RLP items.\n     * @param _in RLP list value.\n     * @return Decoded RLP list items.\n     */\n    function readList(RLPItem memory _in) internal pure returns (RLPItem[] memory) {\n        (uint256 listOffset, , RLPItemType itemType) = _decodeLength(_in);\n\n        require(itemType == RLPItemType.LIST_ITEM, \"Invalid RLP list value.\");\n\n        // Solidity in-memory arrays can't be increased in size, but *can* be decreased in size by\n        // writing to the length. Since we can't know the number of RLP items without looping over\n        // the entire input, we'd have to loop twice to accurately size this array. It's easier to\n        // simply set a reasonable maximum list length and decrease the size before we finish.\n        RLPItem[] memory out = new RLPItem[](MAX_LIST_LENGTH);\n\n        uint256 itemCount = 0;\n        uint256 offset = listOffset;\n        while (offset < _in.length) {\n            require(itemCount < MAX_LIST_LENGTH, \"Provided RLP list exceeds max list length.\");\n\n            (uint256 itemOffset, uint256 itemLength, ) = _decodeLength(\n                RLPItem({ length: _in.length - offset, ptr: _in.ptr + offset })\n            );\n\n            out[itemCount] = RLPItem({ length: itemLength + itemOffset, ptr: _in.ptr + offset });\n\n            itemCount += 1;\n            offset += itemOffset + itemLength;\n        }\n\n        // Decrease the array size to match the actual item count.\n        assembly {\n            mstore(out, itemCount)\n        }\n\n        return out;\n    }\n\n    /**\n     * Reads an RLP list value into a list of RLP items.\n     * @param _in RLP list value.\n     * @return Decoded RLP list items.\n     */\n    function readList(bytes memory _in) internal pure returns (RLPItem[] memory) {\n        return readList(toRLPItem(_in));\n    }\n\n    /**\n     * Reads an RLP bytes value into bytes.\n     * @param _in RLP bytes value.\n     * @return Decoded bytes.\n     */\n    function readBytes(RLPItem memory _in) internal pure returns (bytes memory) {\n        (uint256 itemOffset, uint256 itemLength, RLPItemType itemType) = _decodeLength(_in);\n\n        require(itemType == RLPItemType.DATA_ITEM, \"Invalid RLP bytes value.\");\n\n        return _copy(_in.ptr, itemOffset, itemLength);\n    }\n\n    /**\n     * Reads an RLP bytes value into bytes.\n     * @param _in RLP bytes value.\n     * @return Decoded bytes.\n     */\n    function readBytes(bytes memory _in) internal pure returns (bytes memory) {\n        return readBytes(toRLPItem(_in));\n    }\n\n    /**\n     * Reads an RLP string value into a string.\n     * @param _in RLP string value.\n     * @return Decoded string.\n     */\n    function readString(RLPItem memory _in) internal pure returns (string memory) {\n        return string(readBytes(_in));\n    }\n\n    /**\n     * Reads an RLP string value into a string.\n     * @param _in RLP string value.\n     * @return Decoded string.\n     */\n    function readString(bytes memory _in) internal pure returns (string memory) {\n        return readString(toRLPItem(_in));\n    }\n\n    /**\n     * Reads an RLP bytes32 value into a bytes32.\n     * @param _in RLP bytes32 value.\n     * @return Decoded bytes32.\n     */\n    function readBytes32(RLPItem memory _in) internal pure returns (bytes32) {\n        require(_in.length <= 33, \"Invalid RLP bytes32 value.\");\n\n        (uint256 itemOffset, uint256 itemLength, RLPItemType itemType) = _decodeLength(_in);\n\n        require(itemType == RLPItemType.DATA_ITEM, \"Invalid RLP bytes32 value.\");\n\n        uint256 ptr = _in.ptr + itemOffset;\n        bytes32 out;\n        assembly {\n            out := mload(ptr)\n\n            // Shift the bytes over to match the item size.\n            if lt(itemLength, 32) {\n                out := div(out, exp(256, sub(32, itemLength)))\n            }\n        }\n\n        return out;\n    }\n\n    /**\n     * Reads an RLP bytes32 value into a bytes32.\n     * @param _in RLP bytes32 value.\n     * @return Decoded bytes32.\n     */\n    function readBytes32(bytes memory _in) internal pure returns (bytes32) {\n        return readBytes32(toRLPItem(_in));\n    }\n\n    /**\n     * Reads an RLP uint256 value into a uint256.\n     * @param _in RLP uint256 value.\n     * @return Decoded uint256.\n     */\n    function readUint256(RLPItem memory _in) internal pure returns (uint256) {\n        return uint256(readBytes32(_in));\n    }\n\n    /**\n     * Reads an RLP uint256 value into a uint256.\n     * @param _in RLP uint256 value.\n     * @return Decoded uint256.\n     */\n    function readUint256(bytes memory _in) internal pure returns (uint256) {\n        return readUint256(toRLPItem(_in));\n    }\n\n    /**\n     * Reads an RLP bool value into a bool.\n     * @param _in RLP bool value.\n     * @return Decoded bool.\n     */\n    function readBool(RLPItem memory _in) internal pure returns (bool) {\n        require(_in.length == 1, \"Invalid RLP boolean value.\");\n\n        uint256 ptr = _in.ptr;\n        uint256 out;\n        assembly {\n            out := byte(0, mload(ptr))\n        }\n\n        require(out == 0 || out == 1, \"Lib_RLPReader: Invalid RLP boolean value, must be 0 or 1\");\n\n        return out != 0;\n    }\n\n    /**\n     * Reads an RLP bool value into a bool.\n     * @param _in RLP bool value.\n     * @return Decoded bool.\n     */\n    function readBool(bytes memory _in) internal pure returns (bool) {\n        return readBool(toRLPItem(_in));\n    }\n\n    /**\n     * Reads an RLP address value into a address.\n     * @param _in RLP address value.\n     * @return Decoded address.\n     */\n    function readAddress(RLPItem memory _in) internal pure returns (address) {\n        if (_in.length == 1) {\n            return address(0);\n        }\n\n        require(_in.length == 21, \"Invalid RLP address value.\");\n\n        return address(uint160(readUint256(_in)));\n    }\n\n    /**\n     * Reads an RLP address value into a address.\n     * @param _in RLP address value.\n     * @return Decoded address.\n     */\n    function readAddress(bytes memory _in) internal pure returns (address) {\n        return readAddress(toRLPItem(_in));\n    }\n\n    /**\n     * Reads the raw bytes of an RLP item.\n     * @param _in RLP item to read.\n     * @return Raw RLP bytes.\n     */\n    function readRawBytes(RLPItem memory _in) internal pure returns (bytes memory) {\n        return _copy(_in);\n    }\n\n    /*********************\n     * Private Functions *\n     *********************/\n\n    /**\n     * Decodes the length of an RLP item.\n     * @param _in RLP item to decode.\n     * @return Offset of the encoded data.\n     * @return Length of the encoded data.\n     * @return RLP item type (LIST_ITEM or DATA_ITEM).\n     */\n    function _decodeLength(RLPItem memory _in)\n        private\n        pure\n        returns (\n            uint256,\n            uint256,\n            RLPItemType\n        )\n    {\n        require(_in.length > 0, \"RLP item cannot be null.\");\n\n        uint256 ptr = _in.ptr;\n        uint256 prefix;\n        assembly {\n            prefix := byte(0, mload(ptr))\n        }\n\n        if (prefix <= 0x7f) {\n            // Single byte.\n\n            return (0, 1, RLPItemType.DATA_ITEM);\n        } else if (prefix <= 0xb7) {\n            // Short string.\n\n            uint256 strLen = prefix - 0x80;\n\n            require(_in.length > strLen, \"Invalid RLP short string.\");\n\n            return (1, strLen, RLPItemType.DATA_ITEM);\n        } else if (prefix <= 0xbf) {\n            // Long string.\n            uint256 lenOfStrLen = prefix - 0xb7;\n\n            require(_in.length > lenOfStrLen, \"Invalid RLP long string length.\");\n\n            uint256 strLen;\n            assembly {\n                // Pick out the string length.\n                strLen := div(mload(add(ptr, 1)), exp(256, sub(32, lenOfStrLen)))\n            }\n\n            require(_in.length > lenOfStrLen + strLen, \"Invalid RLP long string.\");\n\n            return (1 + lenOfStrLen, strLen, RLPItemType.DATA_ITEM);\n        } else if (prefix <= 0xf7) {\n            // Short list.\n            uint256 listLen = prefix - 0xc0;\n\n            require(_in.length > listLen, \"Invalid RLP short list.\");\n\n            return (1, listLen, RLPItemType.LIST_ITEM);\n        } else {\n            // Long list.\n            uint256 lenOfListLen = prefix - 0xf7;\n\n            require(_in.length > lenOfListLen, \"Invalid RLP long list length.\");\n\n            uint256 listLen;\n            assembly {\n                // Pick out the list length.\n                listLen := div(mload(add(ptr, 1)), exp(256, sub(32, lenOfListLen)))\n            }\n\n            require(_in.length > lenOfListLen + listLen, \"Invalid RLP long list.\");\n\n            return (1 + lenOfListLen, listLen, RLPItemType.LIST_ITEM);\n        }\n    }\n\n    /**\n     * Copies the bytes from a memory location.\n     * @param _src Pointer to the location to read from.\n     * @param _offset Offset to start reading from.\n     * @param _length Number of bytes to read.\n     * @return Copied bytes.\n     */\n    function _copy(\n        uint256 _src,\n        uint256 _offset,\n        uint256 _length\n    ) private pure returns (bytes memory) {\n        bytes memory out = new bytes(_length);\n        if (out.length == 0) {\n            return out;\n        }\n\n        uint256 src = _src + _offset;\n        uint256 dest;\n        assembly {\n            dest := add(out, 32)\n        }\n\n        // Copy over as many complete words as we can.\n        for (uint256 i = 0; i < _length / 32; i++) {\n            assembly {\n                mstore(dest, mload(src))\n            }\n\n            src += 32;\n            dest += 32;\n        }\n\n        // Pick out the remaining bytes.\n        uint256 mask;\n        unchecked {\n            mask = 256**(32 - (_length % 32)) - 1;\n        }\n\n        assembly {\n            mstore(dest, or(and(mload(src), not(mask)), and(mload(dest), mask)))\n        }\n        return out;\n    }\n\n    /**\n     * Copies an RLP item into bytes.\n     * @param _in RLP item to copy.\n     * @return Copied bytes.\n     */\n    function _copy(RLPItem memory _in) private pure returns (bytes memory) {\n        return _copy(_in.ptr, 0, _in.length);\n    }\n}\n"
    },
    "contracts/libraries/utils/Lib_MerkleTree.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/**\n * @title Lib_MerkleTree\n * @author River Keefer\n */\nlibrary Lib_MerkleTree {\n    /**********************\n     * Internal Functions *\n     **********************/\n\n    /**\n     * Calculates a merkle root for a list of 32-byte leaf hashes.  WARNING: If the number\n     * of leaves passed in is not a power of two, it pads out the tree with zero hashes.\n     * If you do not know the original length of elements for the tree you are verifying, then\n     * this may allow empty leaves past _elements.length to pass a verification check down the line.\n     * Note that the _elements argument is modified, therefore it must not be used again afterwards\n     * @param _elements Array of hashes from which to generate a merkle root.\n     * @return Merkle root of the leaves, with zero hashes for non-powers-of-two (see above).\n     */\n    function getMerkleRoot(bytes32[] memory _elements) internal pure returns (bytes32) {\n        require(_elements.length > 0, \"Lib_MerkleTree: Must provide at least one leaf hash.\");\n\n        if (_elements.length == 1) {\n            return _elements[0];\n        }\n\n        uint256[16] memory defaults = [\n            0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563,\n            0x633dc4d7da7256660a892f8f1604a44b5432649cc8ec5cb3ced4c4e6ac94dd1d,\n            0x890740a8eb06ce9be422cb8da5cdafc2b58c0a5e24036c578de2a433c828ff7d,\n            0x3b8ec09e026fdc305365dfc94e189a81b38c7597b3d941c279f042e8206e0bd8,\n            0xecd50eee38e386bd62be9bedb990706951b65fe053bd9d8a521af753d139e2da,\n            0xdefff6d330bb5403f63b14f33b578274160de3a50df4efecf0e0db73bcdd3da5,\n            0x617bdd11f7c0a11f49db22f629387a12da7596f9d1704d7465177c63d88ec7d7,\n            0x292c23a9aa1d8bea7e2435e555a4a60e379a5a35f3f452bae60121073fb6eead,\n            0xe1cea92ed99acdcb045a6726b2f87107e8a61620a232cf4d7d5b5766b3952e10,\n            0x7ad66c0a68c72cb89e4fb4303841966e4062a76ab97451e3b9fb526a5ceb7f82,\n            0xe026cc5a4aed3c22a58cbd3d2ac754c9352c5436f638042dca99034e83636516,\n            0x3d04cffd8b46a874edf5cfae63077de85f849a660426697b06a829c70dd1409c,\n            0xad676aa337a485e4728a0b240d92b3ef7b3c372d06d189322bfd5f61f1e7203e,\n            0xa2fca4a49658f9fab7aa63289c91b7c7b6c832a6d0e69334ff5b0a3483d09dab,\n            0x4ebfd9cd7bca2505f7bef59cc1c12ecc708fff26ae4af19abe852afe9e20c862,\n            0x2def10d13dd169f550f578bda343d9717a138562e0093b380a1120789d53cf10\n        ];\n\n        // Reserve memory space for our hashes.\n        bytes memory buf = new bytes(64);\n\n        // We'll need to keep track of left and right siblings.\n        bytes32 leftSibling;\n        bytes32 rightSibling;\n\n        // Number of non-empty nodes at the current depth.\n        uint256 rowSize = _elements.length;\n\n        // Current depth, counting from 0 at the leaves\n        uint256 depth = 0;\n\n        // Common sub-expressions\n        uint256 halfRowSize; // rowSize / 2\n        bool rowSizeIsOdd; // rowSize % 2 == 1\n\n        while (rowSize > 1) {\n            halfRowSize = rowSize / 2;\n            rowSizeIsOdd = rowSize % 2 == 1;\n\n            for (uint256 i = 0; i < halfRowSize; i++) {\n                leftSibling = _elements[(2 * i)];\n                rightSibling = _elements[(2 * i) + 1];\n                assembly {\n                    mstore(add(buf, 32), leftSibling)\n                    mstore(add(buf, 64), rightSibling)\n                }\n\n                _elements[i] = keccak256(buf);\n            }\n\n            if (rowSizeIsOdd) {\n                leftSibling = _elements[rowSize - 1];\n                rightSibling = bytes32(defaults[depth]);\n                assembly {\n                    mstore(add(buf, 32), leftSibling)\n                    mstore(add(buf, 64), rightSibling)\n                }\n\n                _elements[halfRowSize] = keccak256(buf);\n            }\n\n            rowSize = halfRowSize + (rowSizeIsOdd ? 1 : 0);\n            depth++;\n        }\n\n        return _elements[0];\n    }\n\n    /**\n     * Verifies a merkle branch for the given leaf hash.  Assumes the original length\n     * of leaves generated is a known, correct input, and does not return true for indices\n     * extending past that index (even if _siblings would be otherwise valid.)\n     * @param _root The Merkle root to verify against.\n     * @param _leaf The leaf hash to verify inclusion of.\n     * @param _index The index in the tree of this leaf.\n     * @param _siblings Array of sibline nodes in the inclusion proof, starting from depth 0\n     * (bottom of the tree).\n     * @param _totalLeaves The total number of leaves originally passed into.\n     * @return Whether or not the merkle branch and leaf passes verification.\n     */\n    function verify(\n        bytes32 _root,\n        bytes32 _leaf,\n        uint256 _index,\n        bytes32[] memory _siblings,\n        uint256 _totalLeaves\n    ) internal pure returns (bool) {\n        require(_totalLeaves > 0, \"Lib_MerkleTree: Total leaves must be greater than zero.\");\n\n        require(_index < _totalLeaves, \"Lib_MerkleTree: Index out of bounds.\");\n\n        require(\n            _siblings.length == _ceilLog2(_totalLeaves),\n            \"Lib_MerkleTree: Total siblings does not correctly correspond to total leaves.\"\n        );\n\n        bytes32 computedRoot = _leaf;\n\n        for (uint256 i = 0; i < _siblings.length; i++) {\n            if ((_index & 1) == 1) {\n                computedRoot = keccak256(abi.encodePacked(_siblings[i], computedRoot));\n            } else {\n                computedRoot = keccak256(abi.encodePacked(computedRoot, _siblings[i]));\n            }\n\n            _index >>= 1;\n        }\n\n        return _root == computedRoot;\n    }\n\n    /*********************\n     * Private Functions *\n     *********************/\n\n    /**\n     * Calculates the integer ceiling of the log base 2 of an input.\n     * @param _in Unsigned input to calculate the log.\n     * @return ceil(log_base_2(_in))\n     */\n    function _ceilLog2(uint256 _in) private pure returns (uint256) {\n        require(_in > 0, \"Lib_MerkleTree: Cannot compute ceil(log_2) of 0.\");\n\n        if (_in == 1) {\n            return 0;\n        }\n\n        // Find the highest set bit (will be floor(log_2)).\n        // Borrowed with <3 from https://github.com/ethereum/solidity-examples\n        uint256 val = _in;\n        uint256 highest = 0;\n        for (uint256 i = 128; i >= 1; i >>= 1) {\n            if (val & (((uint256(1) << i) - 1) << i) != 0) {\n                highest += i;\n                val >>= i;\n            }\n        }\n\n        // Increment by one if this is not a perfect logarithm.\n        if ((uint256(1) << highest) != _in) {\n            highest += 1;\n        }\n\n        return highest;\n    }\n}\n"
    },
    "contracts/libraries/utils/Lib_Uint.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/**\n * @title Lib_Uint\n * @author\n */\nlibrary Lib_Uint {\n    /**********************\n     * Internal Functions *\n     **********************/\n\n    /**\n     * Convert uint to string\n     * @param _i uint value.\n     * @return _uintAsString string momery value.\n     */\n    function uint2str(uint256 _i) internal pure returns (string memory _uintAsString) {\n        if (_i == 0) {\n            return \"0\";\n        }\n        uint256 j = _i;\n        uint256 len;\n        while (j != 0) {\n            len++;\n            j /= 10;\n        }\n        bytes memory bstr = new bytes(len);\n        uint256 k = len;\n        while (_i != 0) {\n            k = k - 1;\n            uint8 temp = (48 + uint8(_i - (_i / 10) * 10));\n            bytes1 b1 = bytes1(temp);\n            bstr[k] = b1;\n            _i /= 10;\n        }\n        return string(bstr);\n    }\n}\n"
    },
    "contracts/MVM/MVM_StateCommitmentChain.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/* Library Imports */\nimport \"../L1/dispute/interfaces/IFaultDisputeGame.sol\";\nimport \"contracts/L1/dispute/lib/Types.sol\";\nimport \"contracts/L1/dispute/lib/Errors.sol\";\nimport { IBondManager } from \"../L1/verification/IBondManager.sol\";\nimport { IChainStorageContainer } from \"../L1/rollup/IChainStorageContainer.sol\";\nimport { IMVMStateCommitmentChain } from \"../L1/rollup/IMVMStateCommitmentChain.sol\";\n\n/* Interface Imports */\nimport { IStateCommitmentChain } from \"../L1/rollup/IStateCommitmentChain.sol\";\n// import { ICanonicalTransactionChain } from \"../L1/rollup/ICanonicalTransactionChain.sol\";\nimport { Lib_AddressResolver } from \"../libraries/resolver/Lib_AddressResolver.sol\";\nimport { Lib_MerkleTree } from \"../libraries/utils/Lib_MerkleTree.sol\";\nimport { Lib_OVMCodec } from \"../libraries/codec/Lib_OVMCodec.sol\";\nimport { Lib_Uint } from \"../libraries/utils/Lib_Uint.sol\";\nimport { IDisputeGameFactory } from \"../L1/dispute/interfaces/IDisputeGameFactory.sol\";\n\n/**\n * @title MVM_StateCommitmentChain\n * @dev The State Commitment Chain (SCC) contract contains a list of proposed state roots which\n * Proposers assert to be a result of each transaction in the Canonical Transaction Chain (CTC).\n * Elements here have a 1:1 correspondence with transactions in the CTC, and should be the unique\n * state root calculated off-chain by applying the canonical transactions one by one.\n *\n * Runtime target: EVM\n */\ncontract MVM_StateCommitmentChain is IMVMStateCommitmentChain, Lib_AddressResolver {\n    /*************\n     * Constants *\n     *************/\n\n    uint256 public FRAUD_PROOF_WINDOW;\n    uint256 public SEQUENCER_PUBLISH_WINDOW;\n\n    uint256 public DEFAULT_CHAINID = 1088;\n\n    IDisputeGameFactory public DISPUTE_GAME_FACTORY;\n\n    /*****************\n     * Public States *\n     *****************/\n    // key: chain id\n    // value: [8B Timestamp][8B Index]\n    mapping(uint256 => bytes16[]) public batchTimes;\n    // key: state batch hash\n    // value: last L2 block number of the given batch\n    mapping(bytes32 => uint256) public batchLastL2BlockNumbers;\n\n    mapping(bytes32 => bool) public disputedBatches;\n\n    /***************\n     * Constructor *\n     ***************/\n\n    /**\n     * @param _libAddressManager Address of the Address Manager.\n     */\n    constructor(\n        address _libAddressManager,\n        uint256 _fraudProofWindow,\n        uint256 _sequencerPublishWindow,\n        IDisputeGameFactory _disputeGameFactory\n    ) Lib_AddressResolver(_libAddressManager) {\n        FRAUD_PROOF_WINDOW = _fraudProofWindow;\n        SEQUENCER_PUBLISH_WINDOW = _sequencerPublishWindow;\n        DISPUTE_GAME_FACTORY = _disputeGameFactory;\n    }\n\n    function setFraudProofWindow(uint256 window) external {\n        require(msg.sender == resolve(\"METIS_MANAGER\"), \"not allowed\");\n        FRAUD_PROOF_WINDOW = window;\n    }\n\n    /********************\n     * Public Functions *\n     ********************/\n\n    /**\n     * @inheritdoc IMVMStateCommitmentChain\n     */\n    function findEarliestDisputableBatch(uint256 _chainId) public view returns (bytes32, uint256) {\n        uint256 earliestDisputableTime = block.timestamp - FRAUD_PROOF_WINDOW;\n        return _findBatchWithinTimeWindow(_chainId, earliestDisputableTime);\n    }\n\n    /**\n     * Accesses the batch storage container.\n     * @return Reference to the batch storage container.\n     */\n    function batches() public view returns (IChainStorageContainer) {\n        return IChainStorageContainer(resolve(\"ChainStorageContainer-SCC-batches\"));\n    }\n\n    /**\n     * @inheritdoc IMVMStateCommitmentChain\n     */\n    function getTotalElements() external view returns (uint256 _totalElements) {\n        return getTotalElementsByChainId(DEFAULT_CHAINID);\n    }\n\n    /**\n     * @inheritdoc IMVMStateCommitmentChain\n     */\n    function getTotalBatches() external view returns (uint256 _totalBatches) {\n        return getTotalBatchesByChainId(DEFAULT_CHAINID);\n    }\n\n    /**\n     * @inheritdoc IMVMStateCommitmentChain\n     */\n    function getLastSequencerTimestamp() external view returns (uint256 _lastSequencerTimestamp) {\n        return getLastSequencerTimestampByChainId(DEFAULT_CHAINID);\n    }\n\n    /**\n     * @inheritdoc IMVMStateCommitmentChain\n     */\n    function appendStateBatch(bytes32[] memory _batch, uint256 _shouldStartAtElement, bytes32 _lastBatchBlockHash, uint256 _lastBatchBlockNumber) external {\n        //require (1==0, \"don't use\");\n        string memory proposer = string(\n            abi.encodePacked(Lib_Uint.uint2str(DEFAULT_CHAINID), \"_MVM_Proposer\")\n        );\n        appendStateBatchByChainId(DEFAULT_CHAINID, _batch, _shouldStartAtElement, proposer, _lastBatchBlockHash, _lastBatchBlockNumber);\n    }\n\n    /**\n     * @inheritdoc IMVMStateCommitmentChain\n     */\n    function deleteStateBatch(Lib_OVMCodec.ChainBatchHeader memory _batchHeader) external {\n        deleteStateBatchByChainId(DEFAULT_CHAINID, _batchHeader);\n    }\n\n    /**\n     * @inheritdoc IMVMStateCommitmentChain\n     */\n    function verifyStateCommitment(\n        bytes32 _element,\n        Lib_OVMCodec.ChainBatchHeader memory _batchHeader,\n        Lib_OVMCodec.ChainInclusionProof memory _proof\n    ) external view returns (bool) {\n        return verifyStateCommitmentByChainId(DEFAULT_CHAINID, _element, _batchHeader, _proof);\n    }\n\n    /**\n     * @inheritdoc IMVMStateCommitmentChain\n     */\n    function insideFraudProofWindow(Lib_OVMCodec.ChainBatchHeader memory _batchHeader)\n        public\n        view\n        returns (bool _inside)\n    {\n        (uint256 timestamp, , , ) = abi.decode(_batchHeader.extraData, (uint256, address, bytes32, uint256));\n\n        require(timestamp != 0, \"Batch header timestamp cannot be zero\");\n        return (timestamp + FRAUD_PROOF_WINDOW) > block.timestamp;\n    }\n\n    function insideFraudProofWindowByChainId(\n        uint256,\n        Lib_OVMCodec.ChainBatchHeader memory _batchHeader\n    ) public view override returns (bool _inside) {\n        (uint256 timestamp, , , ) = abi.decode(_batchHeader.extraData, (uint256, address, bytes32, uint256));\n\n        return _insideFraudProofWindowByChainId(timestamp);\n    }\n\n    function isDisputedBatch(bytes32 stateHeaderHash) public view returns (bool) {\n        return disputedBatches[stateHeaderHash];\n    }\n\n    function saveDisputedBatch(bytes32 stateHeaderHash) public {\n        // Grab the game and game data.\n        IFaultDisputeGame game = IFaultDisputeGame(msg.sender);\n        (GameType gameType, Claim rootClaim, bytes memory extraData) = game.gameData();\n\n        // Grab the verified address of the game based on the game data.\n        // slither-disable-next-line unused-return\n        (IDisputeGame factoryRegisteredGame,) =\n                            DISPUTE_GAME_FACTORY.games({ _gameType: gameType, _rootClaim: rootClaim, _extraData: extraData });\n\n        // Must be a valid game.\n        if (address(factoryRegisteredGame) != address(game)) revert UnregisteredGame();\n\n        if (disputedBatches[stateHeaderHash]) revert ClaimAlreadyResolved();\n\n        // We only record the disputed batch if the challenger wins.\n        if (game.status() == GameStatus.CHALLENGER_WINS) {\n            disputedBatches[stateHeaderHash] = true;\n        }\n    }\n\n    /**********************\n     * Internal Functions *\n     **********************/\n\n    function _findBatchWithinTimeWindow(uint256 _chainId, uint256 earliestTime) public view returns (bytes32, uint256) {\n        bytes16[] storage batchTimesOfChain = batchTimes[_chainId];\n\n        require(batchTimesOfChain.length > 0, \"No batch has been appended yet\");\n\n        uint256 found = 0;\n        uint256 lastTimeIndex = batchTimesOfChain.length - 1;\n        uint256 lastElementTime = uint256(uint128(batchTimesOfChain[lastTimeIndex]) >> 64);\n        uint256 firstElementTime = uint256(uint128(batchTimesOfChain[0]) >> 64);\n\n        require(earliestTime <= lastElementTime, \"No batch to dispute\");\n\n        if (earliestTime <= firstElementTime) {\n            found = 0;\n        } else {\n            // binary search the batch times to find the closest time of earliestTime,\n            // but the time must >= earliestTime\n            uint256 left = 0;\n            uint256 right = lastTimeIndex;\n\n            while (left < right) {\n                uint256 mid = left + (right - left) / 2;\n                uint256 time = uint256(uint128(batchTimesOfChain[mid]) >> 64);\n                if (time < earliestTime) {\n                    left = mid + 1;\n                } else {\n                    right = mid;\n                }\n            }\n            found = left;\n        }\n\n        uint256 batchIndex = uint256(uint64(uint128(batchTimesOfChain[found])));\n        bytes32 batchHeaderHash = batches().getByChainId(_chainId, batchIndex);\n        return (batchHeaderHash, batchLastL2BlockNumbers[batchHeaderHash]);\n    }\n\n    /**\n     * Checks whether a given batch is still inside its fraud proof window.\n     * @param _timestamp Timestamp of the batch to check.\n     * @return _inside Whether or not the batch is inside the fraud proof window.\n     */\n    function _insideFraudProofWindowByChainId(\n       uint256 _timestamp\n    ) internal view returns (bool _inside) {\n        require(_timestamp != 0, \"Batch header timestamp cannot be zero\");\n        return _timestamp + FRAUD_PROOF_WINDOW > block.timestamp;\n    }\n\n    /**\n     * Parses the batch context from the extra data.\n     * @return Total number of elements submitted.\n     * @return Timestamp of the last batch submitted by the sequencer.\n     */\n    function _getBatchExtraData() internal view returns (uint40, uint40) {\n        return _getBatchExtraDataByChainId(DEFAULT_CHAINID);\n    }\n\n    /**\n     * Encodes the batch context for the extra data.\n     * @param _totalElements Total number of elements submitted.\n     * @param _lastSequencerTimestamp Timestamp of the last batch submitted by the sequencer.\n     * @return Encoded batch context.\n     */\n    function _makeBatchExtraData(uint40 _totalElements, uint40 _lastSequencerTimestamp)\n        internal\n        pure\n        returns (bytes27)\n    {\n        bytes27 extraData;\n        assembly {\n            extraData := _totalElements\n            extraData := or(extraData, shl(40, _lastSequencerTimestamp))\n            extraData := shl(40, extraData)\n        }\n\n        return extraData;\n    }\n\n    /**\n     * @inheritdoc IMVMStateCommitmentChain\n     */\n    function getTotalElementsByChainId(uint256 _chainId)\n        public\n        view\n        override\n        returns (uint256 _totalElements)\n    {\n        (uint40 totalElements, ) = _getBatchExtraDataByChainId(_chainId);\n        return uint256(totalElements);\n    }\n\n    /**\n     * @inheritdoc IMVMStateCommitmentChain\n     */\n    function getTotalBatchesByChainId(uint256 _chainId)\n        public\n        view\n        override\n        returns (uint256 _totalBatches)\n    {\n        return batches().lengthByChainId(_chainId);\n    }\n\n    /**\n     * @inheritdoc IMVMStateCommitmentChain\n     */\n    function getLastSequencerTimestampByChainId(uint256 _chainId)\n        public\n        view\n        override\n        returns (uint256 _lastSequencerTimestamp)\n    {\n        (, uint40 lastSequencerTimestamp) = _getBatchExtraDataByChainId(_chainId);\n        return uint256(lastSequencerTimestamp);\n    }\n\n    /**\n     * @inheritdoc IMVMStateCommitmentChain\n     */\n    function appendStateBatchByChainId(\n        uint256 _chainId,\n        bytes32[] memory _batch,\n        uint256 _shouldStartAtElement,\n        string memory _proposer,\n        bytes32 _lastBatchBlockHash,\n        uint256 _lastBatchBlockNumber\n    ) public override {\n        // Fail fast in to make sure our batch roots aren't accidentally made fraudulent by the\n        // publication of batches by some other user.\n        require(\n            _shouldStartAtElement == getTotalElementsByChainId(_chainId),\n            \"Actual batch start index does not match expected start index.\"\n        );\n\n        address proposerAddr = resolve(_proposer);\n\n        // Proposers must have previously staked at the BondManager\n        require(\n            IBondManager(resolve(\"BondManager\")).isCollateralizedByChainId(\n                _chainId,\n                msg.sender,\n                proposerAddr\n            ),\n            \"Proposer does not have enough collateral posted\"\n        );\n\n        require(_batch.length > 0, \"Cannot submit an empty state batch.\");\n\n        // Not check this when submit transaction batch to inbox address\n        // require(\n        //     getTotalElementsByChainId(_chainId) + _batch.length <=\n        //         ICanonicalTransactionChain(resolve(\"CanonicalTransactionChain\"))\n        //             .getTotalElementsByChainId(_chainId),\n        //     \"Number of state roots cannot exceed the number of canonical transactions.\"\n        // );\n\n        // Pass the block's timestamp and the publisher of the data\n        // to be used in the fraud proofs\n        _appendBatchByChainId(\n            _chainId,\n            _batch,\n            abi.encode(block.timestamp, msg.sender, _lastBatchBlockHash, _lastBatchBlockNumber),\n            proposerAddr\n        );\n    }\n\n    /**\n     * @inheritdoc IMVMStateCommitmentChain\n     */\n    function deleteStateBatchByChainId(\n        uint256 _chainId,\n        Lib_OVMCodec.ChainBatchHeader memory _batchHeader\n    ) public override {\n        require(\n            msg.sender ==\n                resolve(\n                    string(abi.encodePacked(Lib_Uint.uint2str(_chainId), \"_MVM_FraudVerifier\"))\n                ),\n            \"State batches can only be deleted by the MVM_FraudVerifier.\"\n        );\n\n        require(\n            insideFraudProofWindow(_batchHeader),\n            \"State batches can only be deleted within the fraud proof window.\"\n        );\n\n        _deleteBatchByChainId(_chainId, _batchHeader);\n    }\n\n    /**\n     * @inheritdoc IMVMStateCommitmentChain\n     */\n    function verifyStateCommitmentByChainId(\n        uint256 _chainId,\n        bytes32 _element,\n        Lib_OVMCodec.ChainBatchHeader memory _batchHeader,\n        Lib_OVMCodec.ChainInclusionProof memory _proof\n    ) public view override returns (bool) {\n        require(_isValidBatchHeaderByChainId(_chainId, _batchHeader), \"Invalid batch header.\");\n\n        require(\n            Lib_MerkleTree.verify(\n                _batchHeader.batchRoot,\n                _element,\n                _proof.index,\n                _proof.siblings,\n                _batchHeader.batchSize\n            ),\n            \"Invalid inclusion proof.\"\n        );\n\n        return true;\n    }\n\n    /**********************\n     * Internal Functions *\n     **********************/\n\n    /**\n     * Parses the batch context from the extra data.\n     * @return Total number of elements submitted.\n     * @return Timestamp of the last batch submitted by the sequencer.\n     */\n    function _getBatchExtraDataByChainId(uint256 _chainId) internal view returns (uint40, uint40) {\n        bytes27 extraData = batches().getGlobalMetadataByChainId(_chainId);\n\n        uint40 totalElements;\n        uint40 lastSequencerTimestamp;\n        assembly {\n            extraData := shr(40, extraData)\n            totalElements := and(\n                extraData,\n                0x000000000000000000000000000000000000000000000000000000FFFFFFFFFF\n            )\n            lastSequencerTimestamp := shr(\n                40,\n                and(extraData, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000)\n            )\n        }\n\n        return (totalElements, lastSequencerTimestamp);\n    }\n\n    /**\n     * Encodes the batch context for the extra data.\n     * @param _totalElements Total number of elements submitted.\n     * @param _lastSequencerTimestamp Timestamp of the last batch submitted by the sequencer.\n     * @return Encoded batch context.\n     */\n    function _makeBatchExtraDataByChainId(uint40 _totalElements, uint40 _lastSequencerTimestamp)\n        internal\n        pure\n        returns (bytes27)\n    {\n        bytes27 extraData;\n        assembly {\n            extraData := _totalElements\n            extraData := or(extraData, shl(40, _lastSequencerTimestamp))\n            extraData := shl(40, extraData)\n        }\n\n        return extraData;\n    }\n\n    /**\n     * Appends a batch to the chain.\n     * @param _batch Elements within the batch.\n     * @param _extraData Any extra data to append to the batch.\n     */\n    function _appendBatchByChainId(\n        uint256 _chainId,\n        bytes32[] memory _batch,\n        bytes memory _extraData,\n        address\n    ) internal {\n        (uint40 totalElements, uint40 lastSequencerTimestamp) = _getBatchExtraDataByChainId(\n            _chainId\n        );\n\n        lastSequencerTimestamp = uint40(block.timestamp);\n\n        // For efficiency reasons getMerkleRoot modifies the `_batch` argument in place\n        // while calculating the root hash therefore any arguments passed to it must not\n        // be used again afterwards\n        Lib_OVMCodec.ChainBatchHeader memory batchHeader = Lib_OVMCodec.ChainBatchHeader({\n            batchIndex: getTotalBatchesByChainId(_chainId),\n            batchRoot: Lib_MerkleTree.getMerkleRoot(_batch),\n            batchSize: _batch.length,\n            prevTotalElements: totalElements,\n            extraData: _extraData\n        });\n\n        emit StateBatchAppended(\n            _chainId,\n            batchHeader.batchIndex,\n            batchHeader.batchRoot,\n            batchHeader.batchSize,\n            batchHeader.prevTotalElements,\n            batchHeader.extraData\n        );\n\n        bytes32 batchHeaderHash = Lib_OVMCodec.hashBatchHeader(batchHeader);\n\n        batches().pushByChainId(\n            _chainId,\n            batchHeaderHash,\n            _makeBatchExtraDataByChainId(\n                uint40(batchHeader.prevTotalElements + batchHeader.batchSize),\n                lastSequencerTimestamp\n            )\n        );\n\n        bytes16[] storage batchTimesOfChain = batchTimes[_chainId];\n        batchTimesOfChain.push(bytes16(uint128(uint256(lastSequencerTimestamp) << 64) | uint128(batchHeader.batchIndex)));\n        batchLastL2BlockNumbers[batchHeaderHash] = batchHeader.prevTotalElements + batchHeader.batchSize;\n    }\n\n    /**\n     * Removes a batch and all subsequent batches from the chain.\n     * @param _batchHeader Header of the batch to remove.\n     */\n    function _deleteBatchByChainId(\n        uint256 _chainId,\n        Lib_OVMCodec.ChainBatchHeader memory _batchHeader\n    ) internal {\n        require(\n            _batchHeader.batchIndex < batches().lengthByChainId(_chainId),\n            \"Invalid batch index.\"\n        );\n\n        require(_isValidBatchHeaderByChainId(_chainId, _batchHeader), \"Invalid batch header.\");\n\n        // clear the fdg extra data if needed\n        if (_batchHeader.extraData.length >= 0x80) {\n            (uint256 timestamp, , , ) = abi.decode(_batchHeader.extraData, (uint256, address, bytes32, uint256));\n            (bytes32 anchoredBatchHeaderHash, ) = _findBatchWithinTimeWindow(_chainId, timestamp);\n\n            bytes32 batchHeaderHash = Lib_OVMCodec.hashBatchHeader(_batchHeader);\n            require(\n                batchHeaderHash == anchoredBatchHeaderHash,\n                \"Anchored batch header does not match the submitted.\"\n            );\n            delete batchLastL2BlockNumbers[batchHeaderHash];\n\n            bytes16[] storage batchTimesOfChain = batchTimes[_chainId];\n            uint256 batchesToPop = 0;\n            for (uint256 i = batchTimesOfChain.length - 1; i >= 0; --i) {\n                if (uint64(uint128(batchTimesOfChain[i])) >= _batchHeader.batchIndex) {\n                    ++batchesToPop;\n                } else {\n                    break;\n                }\n            }\n            for (uint256 i = 0; i < batchesToPop; ++i) {\n                batchTimesOfChain.pop();\n            }\n        }\n\n        batches().deleteElementsAfterInclusiveByChainId(\n            _chainId,\n            _batchHeader.batchIndex,\n            _makeBatchExtraDataByChainId(uint40(_batchHeader.prevTotalElements), 0)\n        );\n\n        emit StateBatchDeleted(_chainId, _batchHeader.batchIndex, _batchHeader.batchRoot);\n    }\n\n    /**\n     * Checks that a batch header matches the stored hash for the given index.\n     * @param _batchHeader Batch header to validate.\n     * @return Whether or not the header matches the stored one.\n     */\n    function _isValidBatchHeaderByChainId(\n        uint256 _chainId,\n        Lib_OVMCodec.ChainBatchHeader memory _batchHeader\n    ) internal view returns (bool) {\n        return\n            Lib_OVMCodec.hashBatchHeader(_batchHeader) ==\n            batches().getByChainId(_chainId, _batchHeader.batchIndex);\n    }\n}\n"
    }
  },
  "settings": {
    "optimizer": {
      "enabled": true,
      "runs": 5000
    },
    "outputSelection": {
      "*": {
        "*": [
          "abi",
          "evm.bytecode",
          "evm.deployedBytecode",
          "evm.methodIdentifiers",
          "metadata",
          "storageLayout",
          "devdoc",
          "userdoc",
          "evm.gasEstimates"
        ],
        "": [
          "ast"
        ]
      }
    },
    "metadata": {
      "useLiteralContent": true
    }
  }
}