creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "src/dispute/PermissionedDisputeGame.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { IDelayedWETH } from \"src/dispute/interfaces/IDelayedWETH.sol\";\nimport { FaultDisputeGame, IFaultDisputeGame, IBigStepper, IInitializable } from \"src/dispute/FaultDisputeGame.sol\";\nimport \"src/libraries/DisputeTypes.sol\";\nimport \"src/libraries/DisputeErrors.sol\";\n\n/// @title PermissionedDisputeGame\n/// @notice PermissionedDisputeGame is a contract that inherits from `FaultDisputeGame`, and contains two roles:\n///         - The `challenger` role, which is allowed to challenge a dispute.\n///         - The `proposer` role, which is allowed to create proposals and participate in their game.\n///         This contract exists as a fallback mechanism in case of the failure of the fault proof system in the stage\n///         one release. It will not be the default implementation used, and eventually will be deprecated in favor of\n///         a fully permissionless system.\ncontract PermissionedDisputeGame is FaultDisputeGame {\n    /// @notice The proposer role is allowed to create proposals and participate in the dispute game.\n    address internal immutable PROPOSER;\n    /// @notice The challenger role is allowed to participate in the dispute game.\n    address internal immutable CHALLENGER;\n\n    /// @notice Modifier that gates access to the `challenger` and `proposer` roles.\n    modifier onlyAuthorized() {\n        if (!(msg.sender == PROPOSER || msg.sender == CHALLENGER)) {\n            revert BadAuth();\n        }\n        _;\n    }\n\n    /// @param _gameType The type ID of the game.\n    /// @param _absolutePrestate The absolute prestate of the instruction trace.\n    /// @param _genesisBlockNumber The block number of the genesis block.\n    /// @param _genesisOutputRoot The output root of the genesis block.\n    /// @param _maxGameDepth The maximum depth of bisection.\n    /// @param _splitDepth The final depth of the output bisection portion of the game.\n    /// @param _gameDuration The duration of the game.\n    /// @param _vm An onchain VM that performs single instruction steps on an FPP trace.\n    /// @param _weth WETH contract for holding ETH.\n    /// @param _l2ChainId Chain ID of the L2 network this contract argues about.\n    /// @param _proposer Address that is allowed to create instances of this contract.\n    /// @param _challenger Address that is allowed to challenge instances of this contract.\n    constructor(\n        GameType _gameType,\n        Claim _absolutePrestate,\n        uint256 _genesisBlockNumber,\n        Hash _genesisOutputRoot,\n        uint256 _maxGameDepth,\n        uint256 _splitDepth,\n        Duration _gameDuration,\n        IBigStepper _vm,\n        IDelayedWETH _weth,\n        uint256 _l2ChainId,\n        address _proposer,\n        address _challenger\n    )\n        FaultDisputeGame(\n            _gameType,\n            _absolutePrestate,\n            _genesisBlockNumber,\n            _genesisOutputRoot,\n            _maxGameDepth,\n            _splitDepth,\n            _gameDuration,\n            _vm,\n            _weth,\n            _l2ChainId\n        )\n    {\n        PROPOSER = _proposer;\n        CHALLENGER = _challenger;\n    }\n\n    /// @inheritdoc IFaultDisputeGame\n    function step(\n        uint256 _claimIndex,\n        bool _isAttack,\n        bytes calldata _stateData,\n        bytes calldata _proof\n    )\n        public\n        override\n        onlyAuthorized\n    {\n        super.step(_claimIndex, _isAttack, _stateData, _proof);\n    }\n\n    /// @notice Generic move function, used for both `attack` and `defend` moves.\n    /// @param _challengeIndex The index of the claim being moved against.\n    /// @param _claim The claim at the next logical position in the game.\n    /// @param _isAttack Whether or not the move is an attack or defense.\n    function move(uint256 _challengeIndex, Claim _claim, bool _isAttack) public payable override onlyAuthorized {\n        super.move(_challengeIndex, _claim, _isAttack);\n    }\n\n    /// @inheritdoc IInitializable\n    function initialize() public payable override {\n        // The creator of the dispute game must be the proposer EOA.\n        if (tx.origin != PROPOSER) revert BadAuth();\n\n        // Fallthrough initialization.\n        super.initialize();\n    }\n}\n"
      },
      "src/dispute/interfaces/IDelayedWETH.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\nimport { IWETH } from \"src/dispute/interfaces/IWETH.sol\";\n\n/// @title IDelayedWETH\n/// @notice Interface for the DelayedWETH contract.\ninterface IDelayedWETH is IWETH {\n    /// @notice Represents a withdrawal request.\n    struct WithdrawalRequest {\n        uint256 amount;\n        uint256 timestamp;\n    }\n\n    /// @notice Emitted when an unwrap is started.\n    /// @param src The address that started the unwrap.\n    /// @param wad The amount of WETH that was unwrapped.\n    event Unwrap(address indexed src, uint256 wad);\n\n    /// @notice Returns the withdrawal delay in seconds.\n    /// @return The withdrawal delay in seconds.\n    function delay() external view returns (uint256);\n\n    /// @notice Returns a withdrawal request for the given address.\n    /// @param _owner The address to query the withdrawal request of.\n    /// @param _guy Sub-account to query the withdrawal request of.\n    /// @return The withdrawal request for the given address-subaccount pair.\n    function withdrawals(address _owner, address _guy) external view returns (uint256, uint256);\n\n    /// @notice Unlocks withdrawals for the sender's account, after a time delay.\n    /// @param _guy Sub-account to unlock.\n    /// @param _wad The amount of WETH to unlock.\n    function unlock(address _guy, uint256 _wad) external;\n\n    /// @notice Extension to withdrawal, must provide a sub-account to withdraw from.\n    /// @param _guy Sub-account to withdraw from.\n    /// @param _wad The amount of WETH to withdraw.\n    function withdraw(address _guy, uint256 _wad) external;\n\n    /// @notice Allows the owner to recover from error cases by pulling ETH out of the contract.\n    /// @param _wad The amount of WETH to recover.\n    function recover(uint256 _wad) external;\n\n    /// @notice Allows the owner to recover from error cases by pulling ETH from a specific owner.\n    /// @param _guy The address to recover the WETH from.\n    /// @param _wad The amount of WETH to recover.\n    function hold(address _guy, uint256 _wad) external;\n}\n"
      },
      "src/dispute/FaultDisputeGame.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { FixedPointMathLib } from \"solady/utils/FixedPointMathLib.sol\";\n\nimport { IDelayedWETH } from \"src/dispute/interfaces/IDelayedWETH.sol\";\nimport { IDisputeGame } from \"src/dispute/interfaces/IDisputeGame.sol\";\nimport { IFaultDisputeGame } from \"src/dispute/interfaces/IFaultDisputeGame.sol\";\nimport { IInitializable } from \"src/dispute/interfaces/IInitializable.sol\";\nimport { IBigStepper, IPreimageOracle } from \"src/dispute/interfaces/IBigStepper.sol\";\n\nimport { Clone } from \"src/libraries/Clone.sol\";\nimport { Types } from \"src/libraries/Types.sol\";\nimport { ISemver } from \"src/universal/ISemver.sol\";\nimport { LibClock } from \"src/dispute/lib/LibUDT.sol\";\n\nimport \"src/libraries/DisputeTypes.sol\";\nimport \"src/libraries/DisputeErrors.sol\";\n\n/// @title FaultDisputeGame\n/// @notice An implementation of the `IFaultDisputeGame` interface.\ncontract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver {\n    ////////////////////////////////////////////////////////////////\n    //                         State Vars                         //\n    ////////////////////////////////////////////////////////////////\n\n    /// @notice The absolute prestate of the instruction trace. This is a constant that is defined\n    ///         by the program that is being used to execute the trace.\n    Claim internal immutable ABSOLUTE_PRESTATE;\n\n    /// @notice The max depth of the game.\n    uint256 internal immutable MAX_GAME_DEPTH;\n\n    /// @notice The max depth of the output bisection portion of the position tree. Immediately beneath\n    ///         this depth, execution trace bisection begins.\n    uint256 internal immutable SPLIT_DEPTH;\n\n    /// @notice The duration of the game.\n    Duration internal immutable GAME_DURATION;\n\n    /// @notice An onchain VM that performs single instruction steps on a fault proof program trace.\n    IBigStepper internal immutable VM;\n\n    /// @notice The genesis block number.\n    uint256 internal immutable GENESIS_BLOCK_NUMBER;\n\n    /// @notice The genesis output root.\n    Hash internal immutable GENESIS_OUTPUT_ROOT;\n\n    /// @notice The game type ID.\n    GameType internal immutable GAME_TYPE;\n\n    /// @notice WETH contract for holding ETH.\n    IDelayedWETH internal immutable WETH;\n\n    /// @notice The chain ID of the L2 network this contract argues about.\n    uint256 internal immutable L2_CHAIN_ID;\n\n    /// @notice The global root claim's position is always at gindex 1.\n    Position internal constant ROOT_POSITION = Position.wrap(1);\n\n    /// @notice The flag set in the `bond` field of a `ClaimData` struct to indicate that the bond has been claimed.\n    uint128 internal constant CLAIMED_BOND_FLAG = type(uint128).max;\n\n    /// @notice The starting timestamp of the game\n    Timestamp public createdAt;\n\n    /// @notice The timestamp of the game's global resolution.\n    Timestamp public resolvedAt;\n\n    /// @inheritdoc IDisputeGame\n    GameStatus public status;\n\n    /// @notice An append-only array of all claims made during the dispute game.\n    ClaimData[] public claimData;\n\n    /// @notice Credited balances for winning participants.\n    mapping(address => uint256) public credit;\n\n    /// @notice An internal mapping to allow for constant-time lookups of existing claims.\n    mapping(ClaimHash => bool) internal claims;\n\n    /// @notice An internal mapping of subgames rooted at a claim index to other claim indices in the subgame.\n    mapping(uint256 => uint256[]) internal subgames;\n\n    /// @notice Indicates whether the subgame rooted at the root claim has been resolved.\n    bool internal subgameAtRootResolved;\n\n    /// @notice Flag for the `initialize` function to prevent re-initialization.\n    bool internal initialized;\n\n    /// @notice Semantic version.\n    /// @custom:semver 0.7.1\n    string public constant version = \"0.7.1\";\n\n    /// @param _gameType The type ID of the game.\n    /// @param _absolutePrestate The absolute prestate of the instruction trace.\n    /// @param _genesisBlockNumber The block number of the genesis block.\n    /// @param _genesisOutputRoot The output root of the genesis block.\n    /// @param _maxGameDepth The maximum depth of bisection.\n    /// @param _splitDepth The final depth of the output bisection portion of the game.\n    /// @param _gameDuration The duration of the game.\n    /// @param _vm An onchain VM that performs single instruction steps on an FPP trace.\n    /// @param _weth WETH contract for holding ETH.\n    /// @param _l2ChainId Chain ID of the L2 network this contract argues about.\n    constructor(\n        GameType _gameType,\n        Claim _absolutePrestate,\n        uint256 _genesisBlockNumber,\n        Hash _genesisOutputRoot,\n        uint256 _maxGameDepth,\n        uint256 _splitDepth,\n        Duration _gameDuration,\n        IBigStepper _vm,\n        IDelayedWETH _weth,\n        uint256 _l2ChainId\n    ) {\n        // The split depth cannot be greater than or equal to the max game depth.\n        if (_splitDepth >= _maxGameDepth) revert InvalidSplitDepth();\n\n        GAME_TYPE = _gameType;\n        ABSOLUTE_PRESTATE = _absolutePrestate;\n        GENESIS_BLOCK_NUMBER = _genesisBlockNumber;\n        GENESIS_OUTPUT_ROOT = _genesisOutputRoot;\n        MAX_GAME_DEPTH = _maxGameDepth;\n        SPLIT_DEPTH = _splitDepth;\n        GAME_DURATION = _gameDuration;\n        VM = _vm;\n        WETH = _weth;\n        L2_CHAIN_ID = _l2ChainId;\n    }\n\n    /// @notice Receive function to allow the contract to receive ETH.\n    receive() external payable { }\n\n    /// @notice Fallback function to allow the contract to receive ETH.\n    fallback() external payable { }\n\n    ////////////////////////////////////////////////////////////////\n    //                  `IFaultDisputeGame` impl                  //\n    ////////////////////////////////////////////////////////////////\n\n    /// @inheritdoc IFaultDisputeGame\n    function step(\n        uint256 _claimIndex,\n        bool _isAttack,\n        bytes calldata _stateData,\n        bytes calldata _proof\n    )\n        public\n        virtual\n    {\n        // INVARIANT: Steps cannot be made unless the game is currently in progress.\n        if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress();\n\n        // Get the parent. If it does not exist, the call will revert with OOB.\n        ClaimData storage parent = claimData[_claimIndex];\n\n        // Pull the parent position out of storage.\n        Position parentPos = parent.position;\n        // Determine the position of the step.\n        Position stepPos = parentPos.move(_isAttack);\n\n        // INVARIANT: A step cannot be made unless the move position is 1 below the `MAX_GAME_DEPTH`\n        if (stepPos.depth() != MAX_GAME_DEPTH + 1) revert InvalidParent();\n\n        // Determine the expected pre & post states of the step.\n        Claim preStateClaim;\n        ClaimData storage postState;\n        if (_isAttack) {\n            // If the step position's index at depth is 0, the prestate is the absolute\n            // prestate.\n            // If the step is an attack at a trace index > 0, the prestate exists elsewhere in\n            // the game state.\n            // NOTE: We localize the `indexAtDepth` for the current execution trace subgame by finding\n            //       the remainder of the index at depth divided by 2 ** (MAX_GAME_DEPTH - SPLIT_DEPTH),\n            //       which is the number of leaves in each execution trace subgame. This is so that we can\n            //       determine whether or not the step position is represents the `ABSOLUTE_PRESTATE`.\n            preStateClaim = (stepPos.indexAtDepth() % (1 << (MAX_GAME_DEPTH - SPLIT_DEPTH))) == 0\n                ? ABSOLUTE_PRESTATE\n                : _findTraceAncestor(Position.wrap(parentPos.raw() - 1), parent.parentIndex, false).claim;\n            // For all attacks, the poststate is the parent claim.\n            postState = parent;\n        } else {\n            // If the step is a defense, the poststate exists elsewhere in the game state,\n            // and the parent claim is the expected pre-state.\n            preStateClaim = parent.claim;\n            postState = _findTraceAncestor(Position.wrap(parentPos.raw() + 1), parent.parentIndex, false);\n        }\n\n        // INVARIANT: The prestate is always invalid if the passed `_stateData` is not the\n        //            preimage of the prestate claim hash.\n        //            We ignore the highest order byte of the digest because it is used to\n        //            indicate the VM Status and is added after the digest is computed.\n        if (keccak256(_stateData) << 8 != preStateClaim.raw() << 8) revert InvalidPrestate();\n\n        // Compute the local preimage context for the step.\n        Hash uuid = _findLocalContext(_claimIndex);\n\n        // INVARIANT: If a step is an attack, the poststate is valid if the step produces\n        //            the same poststate hash as the parent claim's value.\n        //            If a step is a defense:\n        //              1. If the parent claim and the found post state agree with each other\n        //                 (depth diff % 2 == 0), the step is valid if it produces the same\n        //                 state hash as the post state's claim.\n        //              2. If the parent claim and the found post state disagree with each other\n        //                 (depth diff % 2 != 0), the parent cannot be countered unless the step\n        //                 produces the same state hash as `postState.claim`.\n        // SAFETY:    While the `attack` path does not need an extra check for the post\n        //            state's depth in relation to the parent, we don't need another\n        //            branch because (n - n) % 2 == 0.\n        bool validStep = VM.step(_stateData, _proof, uuid.raw()) == postState.claim.raw();\n        bool parentPostAgree = (parentPos.depth() - postState.position.depth()) % 2 == 0;\n        if (parentPostAgree == validStep) revert ValidStep();\n\n        // INVARIANT: A step cannot be made against a claim for a second time.\n        if (parent.counteredBy != address(0)) revert DuplicateStep();\n\n        // Set the parent claim as countered. We do not need to append a new claim to the game;\n        // instead, we can just set the existing parent as countered.\n        parent.counteredBy = msg.sender;\n    }\n\n    /// @notice Generic move function, used for both `attack` and `defend` moves.\n    /// @param _challengeIndex The index of the claim being moved against.\n    /// @param _claim The claim at the next logical position in the game.\n    /// @param _isAttack Whether or not the move is an attack or defense.\n    function move(uint256 _challengeIndex, Claim _claim, bool _isAttack) public payable virtual {\n        // INVARIANT: Moves cannot be made unless the game is currently in progress.\n        if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress();\n\n        // Get the parent. If it does not exist, the call will revert with OOB.\n        ClaimData memory parent = claimData[_challengeIndex];\n\n        // Compute the position that the claim commits to. Because the parent's position is already\n        // known, we can compute the next position by moving left or right depending on whether\n        // or not the move is an attack or defense.\n        Position parentPos = parent.position;\n        Position nextPosition = parentPos.move(_isAttack);\n        uint256 nextPositionDepth = nextPosition.depth();\n\n        // INVARIANT: A defense can never be made against the root claim of either the output root game or any\n        //            of the execution trace bisection subgames. This is because the root claim commits to the\n        //            entire state. Therefore, the only valid defense is to do nothing if it is agreed with.\n        if ((_challengeIndex == 0 || nextPositionDepth == SPLIT_DEPTH + 2) && !_isAttack) {\n            revert CannotDefendRootClaim();\n        }\n\n        // INVARIANT: A move can never surpass the `MAX_GAME_DEPTH`. The only option to counter a\n        //            claim at this depth is to perform a single instruction step on-chain via\n        //            the `step` function to prove that the state transition produces an unexpected\n        //            post-state.\n        if (nextPositionDepth > MAX_GAME_DEPTH) revert GameDepthExceeded();\n\n        // When the next position surpasses the split depth (i.e., it is the root claim of an execution\n        // trace bisection sub-game), we need to perform some extra verification steps.\n        if (nextPositionDepth == SPLIT_DEPTH + 1) {\n            _verifyExecBisectionRoot(_claim, _challengeIndex, parentPos, _isAttack);\n        }\n\n        // INVARIANT: The `msg.value` must be sufficient to cover the required bond.\n        if (getRequiredBond(nextPosition) > msg.value) revert InsufficientBond();\n\n        // Fetch the grandparent clock, if it exists.\n        // The grandparent clock should always exist unless the parent is the root claim.\n        Clock grandparentClock;\n        if (parent.parentIndex != type(uint32).max) {\n            grandparentClock = claimData[parent.parentIndex].clock;\n        }\n\n        // Compute the duration of the next clock. This is done by adding the duration of the\n        // grandparent claim to the difference between the current block timestamp and the\n        // parent's clock timestamp.\n        Duration nextDuration = Duration.wrap(\n            uint64(\n                // First, fetch the duration of the grandparent claim.\n                grandparentClock.duration().raw()\n                // Second, add the difference between the current block timestamp and the\n                // parent's clock timestamp.\n                + block.timestamp - parent.clock.timestamp().raw()\n            )\n        );\n\n        // INVARIANT: A move can never be made once its clock has exceeded `GAME_DURATION / 2`\n        //            seconds of time.\n        if (nextDuration.raw() > GAME_DURATION.raw() >> 1) revert ClockTimeExceeded();\n\n        // Construct the next clock with the new duration and the current block timestamp.\n        Clock nextClock = LibClock.wrap(nextDuration, Timestamp.wrap(uint64(block.timestamp)));\n\n        // INVARIANT: There cannot be multiple identical claims with identical moves on the same challengeIndex. Multiple\n        //            claims at the same position may dispute the same challengeIndex. However, they must have different\n        //            values.\n        ClaimHash claimHash = _claim.hashClaimPos(nextPosition, _challengeIndex);\n        if (claims[claimHash]) revert ClaimAlreadyExists();\n        claims[claimHash] = true;\n\n        // Create the new claim.\n        claimData.push(\n            ClaimData({\n                parentIndex: uint32(_challengeIndex),\n                // This is updated during subgame resolution\n                counteredBy: address(0),\n                claimant: msg.sender,\n                bond: uint128(msg.value),\n                claim: _claim,\n                position: nextPosition,\n                clock: nextClock\n            })\n        );\n\n        // Update the subgame rooted at the parent claim.\n        subgames[_challengeIndex].push(claimData.length - 1);\n\n        // Deposit the bond.\n        WETH.deposit{ value: msg.value }();\n\n        // Emit the appropriate event for the attack or defense.\n        emit Move(_challengeIndex, _claim, msg.sender);\n    }\n\n    /// @inheritdoc IFaultDisputeGame\n    function attack(uint256 _parentIndex, Claim _claim) external payable {\n        move(_parentIndex, _claim, true);\n    }\n\n    /// @inheritdoc IFaultDisputeGame\n    function defend(uint256 _parentIndex, Claim _claim) external payable {\n        move(_parentIndex, _claim, false);\n    }\n\n    /// @inheritdoc IFaultDisputeGame\n    function addLocalData(uint256 _ident, uint256 _execLeafIdx, uint256 _partOffset) external {\n        // INVARIANT: Local data can only be added if the game is currently in progress.\n        if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress();\n\n        (Claim starting, Position startingPos, Claim disputed, Position disputedPos) =\n            _findStartingAndDisputedOutputs(_execLeafIdx);\n        Hash uuid = _computeLocalContext(starting, startingPos, disputed, disputedPos);\n\n        IPreimageOracle oracle = VM.oracle();\n        if (_ident == LocalPreimageKey.L1_HEAD_HASH) {\n            // Load the L1 head hash\n            oracle.loadLocalData(_ident, uuid.raw(), l1Head().raw(), 32, _partOffset);\n        } else if (_ident == LocalPreimageKey.STARTING_OUTPUT_ROOT) {\n            // Load the starting proposal's output root.\n            oracle.loadLocalData(_ident, uuid.raw(), starting.raw(), 32, _partOffset);\n        } else if (_ident == LocalPreimageKey.DISPUTED_OUTPUT_ROOT) {\n            // Load the disputed proposal's output root\n            oracle.loadLocalData(_ident, uuid.raw(), disputed.raw(), 32, _partOffset);\n        } else if (_ident == LocalPreimageKey.DISPUTED_L2_BLOCK_NUMBER) {\n            // Load the disputed proposal's L2 block number as a big-endian uint64 in the\n            // high order 8 bytes of the word.\n\n            // We add the index at depth + 1 to the genesis block number to get the disputed L2 block number.\n            uint256 l2Number = GENESIS_BLOCK_NUMBER + disputedPos.traceIndex(SPLIT_DEPTH) + 1;\n\n            oracle.loadLocalData(_ident, uuid.raw(), bytes32(l2Number << 0xC0), 8, _partOffset);\n        } else if (_ident == LocalPreimageKey.CHAIN_ID) {\n            // Load the chain ID as a big-endian uint64 in the high order 8 bytes of the word.\n            oracle.loadLocalData(_ident, uuid.raw(), bytes32(L2_CHAIN_ID << 0xC0), 8, _partOffset);\n        } else {\n            revert InvalidLocalIdent();\n        }\n    }\n\n    /// @inheritdoc IFaultDisputeGame\n    function l1Head() public pure returns (Hash l1Head_) {\n        l1Head_ = Hash.wrap(_getArgFixedBytes(0x20));\n    }\n\n    /// @inheritdoc IFaultDisputeGame\n    function l2BlockNumber() public pure returns (uint256 l2BlockNumber_) {\n        l2BlockNumber_ = _getArgUint256(0x40);\n    }\n\n    ////////////////////////////////////////////////////////////////\n    //                    `IDisputeGame` impl                     //\n    ////////////////////////////////////////////////////////////////\n\n    /// @inheritdoc IDisputeGame\n    function gameType() public view override returns (GameType gameType_) {\n        gameType_ = GAME_TYPE;\n    }\n\n    /// @inheritdoc IDisputeGame\n    function resolve() external returns (GameStatus status_) {\n        // INVARIANT: Resolution cannot occur unless the game is currently in progress.\n        if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress();\n\n        // INVARIANT: Resolution cannot occur unless the absolute root subgame has been resolved.\n        if (!subgameAtRootResolved) revert OutOfOrderResolution();\n\n        // Update the global game status; The dispute has concluded.\n        status_ = claimData[0].counteredBy == address(0) ? GameStatus.DEFENDER_WINS : GameStatus.CHALLENGER_WINS;\n        resolvedAt = Timestamp.wrap(uint64(block.timestamp));\n\n        emit Resolved(status = status_);\n    }\n\n    /// @inheritdoc IFaultDisputeGame\n    function resolveClaim(uint256 _claimIndex) external payable {\n        // INVARIANT: Resolution cannot occur unless the game is currently in progress.\n        if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress();\n\n        ClaimData storage parent = claimData[_claimIndex];\n\n        // INVARIANT: Cannot resolve a subgame unless the clock of its root has expired\n        uint64 parentClockDuration = parent.clock.duration().raw();\n        uint64 timeSinceParentMove = uint64(block.timestamp) - parent.clock.timestamp().raw();\n        if (parentClockDuration + timeSinceParentMove <= GAME_DURATION.raw() >> 1) {\n            revert ClockNotExpired();\n        }\n\n        uint256[] storage challengeIndices = subgames[_claimIndex];\n        uint256 challengeIndicesLen = challengeIndices.length;\n\n        // INVARIANT: Cannot resolve subgames twice\n        if (_claimIndex == 0 && subgameAtRootResolved) {\n            revert ClaimAlreadyResolved();\n        }\n\n        // Uncontested claims are resolved implicitly unless they are the root claim. Pay out the bond to the claimant\n        // and return early.\n        if (challengeIndicesLen == 0 && _claimIndex != 0) {\n            // In the event that the parent claim is at the max depth, there will always be 0 subgames. If the\n            // `counteredBy` field is set and there are no subgames, this implies that the parent claim was successfully\n            // stepped against. In this case, we pay out the bond to the party that stepped against the parent claim.\n            // Otherwise, the parent claim is uncontested, and the bond is returned to the claimant.\n            address counteredBy = parent.counteredBy;\n            address recipient = counteredBy == address(0) ? parent.claimant : counteredBy;\n            _distributeBond(recipient, parent);\n            return;\n        }\n\n        // Assume parent is honest until proven otherwise\n        address countered = address(0);\n        Position leftmostCounter = Position.wrap(type(uint128).max);\n        for (uint256 i = 0; i < challengeIndicesLen; ++i) {\n            uint256 challengeIndex = challengeIndices[i];\n\n            // INVARIANT: Cannot resolve a subgame containing an unresolved claim\n            if (subgames[challengeIndex].length != 0) revert OutOfOrderResolution();\n\n            ClaimData storage claim = claimData[challengeIndex];\n\n            // If the child subgame is uncountered and further left than the current left-most counter,\n            // update the parent subgame's `countered` address and the current `leftmostCounter`.\n            // The left-most correct counter is preferred in bond payouts in order to discourage attackers\n            // from countering invalid subgame roots via an invalid defense position. As such positions\n            // cannot be correctly countered.\n            // Note that correctly positioned defense, but invalid claimes can still be successfully countered.\n            if (claim.counteredBy == address(0) && leftmostCounter.raw() > claim.position.raw()) {\n                countered = claim.claimant;\n                leftmostCounter = claim.position;\n            }\n        }\n\n        // If the parent was not successfully countered, pay out the parent's bond to the claimant.\n        // If the parent was successfully countered, pay out the parent's bond to the challenger.\n        _distributeBond(countered == address(0) ? parent.claimant : countered, parent);\n\n        // Once a subgame is resolved, we percolate the result up the DAG so subsequent calls to\n        // resolveClaim will not need to traverse this subgame.\n        parent.counteredBy = countered;\n\n        // Resolved subgames have no entries\n        delete subgames[_claimIndex];\n\n        // Indicate the game is ready to be resolved globally.\n        if (_claimIndex == 0) {\n            subgameAtRootResolved = true;\n        }\n    }\n\n    /// @inheritdoc IDisputeGame\n    function rootClaim() public pure returns (Claim rootClaim_) {\n        rootClaim_ = Claim.wrap(_getArgFixedBytes(0x00));\n    }\n\n    /// @inheritdoc IDisputeGame\n    function extraData() public pure returns (bytes memory extraData_) {\n        // The extra data starts at the second word within the cwia calldata and\n        // is 32 bytes long.\n        extraData_ = _getArgDynBytes(0x40, 0x20);\n    }\n\n    /// @inheritdoc IDisputeGame\n    function gameData() external view returns (GameType gameType_, Claim rootClaim_, bytes memory extraData_) {\n        gameType_ = gameType();\n        rootClaim_ = rootClaim();\n        extraData_ = extraData();\n    }\n\n    ////////////////////////////////////////////////////////////////\n    //                       MISC EXTERNAL                        //\n    ////////////////////////////////////////////////////////////////\n\n    /// @inheritdoc IInitializable\n    function initialize() public payable virtual {\n        // SAFETY: Any revert in this function will bubble up to the DisputeGameFactory and\n        // prevent the game from being created.\n        //\n        // Implicit assumptions:\n        // - The `gameStatus` state variable defaults to 0, which is `GameStatus.IN_PROGRESS`\n        // - The dispute game factory will enforce the required bond to initialize the game.\n        //\n        // Explicit checks:\n        // - The game must not have already been initialized.\n        // - An output root cannot be proposed at or before the genesis block.\n\n        // INVARIANT: The game must not have already been initialized.\n        if (initialized) revert AlreadyInitialized();\n\n        // Do not allow the game to be initialized if the root claim corresponds to a block at or before the\n        // configured genesis block number.\n        if (l2BlockNumber() <= GENESIS_BLOCK_NUMBER) revert UnexpectedRootClaim(rootClaim());\n\n        // Revert if the calldata size is too large, which signals that the `extraData` contains more than expected.\n        // This is to prevent adding extra bytes to the `extraData` that result in a different game UUID in the factory,\n        // but are not used by the game, which would allow for multiple dispute games for the same output proposal to\n        // be created.\n        // Expected length: 0x66 (0x04 selector + 0x20 root claim + 0x20 l1 head + 0x20 extraData + 0x02 CWIA bytes)\n        assembly {\n            if gt(calldatasize(), 0x66) {\n                // Store the selector for `ExtraDataTooLong()` & revert\n                mstore(0x00, 0xc407e025)\n                revert(0x1C, 0x04)\n            }\n        }\n\n        // Set the root claim\n        claimData.push(\n            ClaimData({\n                parentIndex: type(uint32).max,\n                counteredBy: address(0),\n                claimant: tx.origin,\n                bond: uint128(msg.value),\n                claim: rootClaim(),\n                position: ROOT_POSITION,\n                clock: LibClock.wrap(Duration.wrap(0), Timestamp.wrap(uint64(block.timestamp)))\n            })\n        );\n\n        // Deposit the bond.\n        WETH.deposit{ value: msg.value }();\n\n        // Set the game's starting timestamp\n        createdAt = Timestamp.wrap(uint64(block.timestamp));\n\n        // Set the game as initialized.\n        initialized = true;\n    }\n\n    /// @notice Returns the length of the `claimData` array.\n    function claimDataLen() external view returns (uint256 len_) {\n        len_ = claimData.length;\n    }\n\n    /// @notice Returns the required bond for a given move kind.\n    /// @param _position The position of the bonded interaction.\n    /// @return requiredBond_ The required ETH bond for the given move, in wei.\n    function getRequiredBond(Position _position) public view returns (uint256 requiredBond_) {\n        uint256 depth = uint256(_position.depth());\n        if (depth > MAX_GAME_DEPTH) revert GameDepthExceeded();\n\n        // Values taken from Big Bonds v1.5 (TM) spec.\n        uint256 assumedBaseFee = 200 gwei;\n        uint256 baseGasCharged = 400_000;\n        uint256 highGasCharged = 200_000_000;\n\n        // Goal here is to compute the fixed multiplier that will be applied to the base gas\n        // charged to get the required gas amount for the given depth. We apply this multiplier\n        // some `n` times where `n` is the depth of the position. We are looking for some number\n        // that, when multiplied by itself `MAX_GAME_DEPTH` times and then multiplied by the base\n        // gas charged, will give us the maximum gas that we want to charge.\n        // We want to solve for (highGasCharged/baseGasCharged) ** (1/MAX_GAME_DEPTH).\n        // We know that a ** (b/c) is equal to e ** (ln(a) * (b/c)).\n        // We can compute e ** (ln(a) * (b/c)) quite easily with FixedPointMathLib.\n\n        // Set up a, b, and c.\n        uint256 a = highGasCharged / baseGasCharged;\n        uint256 b = FixedPointMathLib.WAD;\n        uint256 c = MAX_GAME_DEPTH * FixedPointMathLib.WAD;\n\n        // Compute ln(a).\n        // slither-disable-next-line divide-before-multiply\n        uint256 lnA = uint256(FixedPointMathLib.lnWad(int256(a * FixedPointMathLib.WAD)));\n\n        // Computes (b / c) with full precision using WAD = 1e18.\n        uint256 bOverC = FixedPointMathLib.divWad(b, c);\n\n        // Compute e ** (ln(a) * (b/c))\n        // sMulWad can be used here since WAD = 1e18 maintains the same precision.\n        uint256 numerator = FixedPointMathLib.mulWad(lnA, bOverC);\n        int256 base = FixedPointMathLib.expWad(int256(numerator));\n\n        // Compute the required gas amount.\n        int256 rawGas = FixedPointMathLib.powWad(base, int256(depth * FixedPointMathLib.WAD));\n        uint256 requiredGas = FixedPointMathLib.mulWad(baseGasCharged, uint256(rawGas));\n\n        // Compute the required bond.\n        requiredBond_ = assumedBaseFee * requiredGas;\n    }\n\n    /// @notice Claim the credit belonging to the recipient address.\n    /// @param _recipient The owner and recipient of the credit.\n    function claimCredit(address _recipient) external {\n        // Remove the credit from the recipient prior to performing the external call.\n        uint256 recipientCredit = credit[_recipient];\n        credit[_recipient] = 0;\n\n        // Revert if the recipient has no credit to claim.\n        if (recipientCredit == 0) {\n            revert NoCreditToClaim();\n        }\n\n        // Try to withdraw the WETH amount so it can be used here.\n        WETH.withdraw(_recipient, recipientCredit);\n\n        // Transfer the credit to the recipient.\n        (bool success,) = _recipient.call{ value: recipientCredit }(hex\"\");\n        if (!success) revert BondTransferFailed();\n    }\n\n    /// @notice Returns the flag set in the `bond` field of a `ClaimData` struct to indicate that the bond has been\n    ///         claimed.\n    function claimedBondFlag() external pure returns (uint128 claimedBondFlag_) {\n        claimedBondFlag_ = CLAIMED_BOND_FLAG;\n    }\n\n    ////////////////////////////////////////////////////////////////\n    //                     IMMUTABLE GETTERS                      //\n    ////////////////////////////////////////////////////////////////\n\n    /// @notice Returns the absolute prestate of the instruction trace.\n    function absolutePrestate() external view returns (Claim absolutePrestate_) {\n        absolutePrestate_ = ABSOLUTE_PRESTATE;\n    }\n\n    /// @notice Returns the max game depth.\n    function maxGameDepth() external view returns (uint256 maxGameDepth_) {\n        maxGameDepth_ = MAX_GAME_DEPTH;\n    }\n\n    /// @notice Returns the split depth.\n    function splitDepth() external view returns (uint256 splitDepth_) {\n        splitDepth_ = SPLIT_DEPTH;\n    }\n\n    /// @notice Returns the game duration.\n    function gameDuration() external view returns (Duration gameDuration_) {\n        gameDuration_ = GAME_DURATION;\n    }\n\n    /// @notice Returns the address of the VM.\n    function vm() external view returns (IBigStepper vm_) {\n        vm_ = VM;\n    }\n\n    /// @notice Returns the genesis block number.\n    function genesisBlockNumber() external view returns (uint256 genesisBlockNumber_) {\n        genesisBlockNumber_ = GENESIS_BLOCK_NUMBER;\n    }\n\n    /// @notice Returns the genesis output root.\n    function genesisOutputRoot() external view returns (Hash genesisOutputRoot_) {\n        genesisOutputRoot_ = GENESIS_OUTPUT_ROOT;\n    }\n\n    /// @notice Returns the WETH contract for holding ETH.\n    function weth() external view returns (IDelayedWETH weth_) {\n        weth_ = WETH;\n    }\n\n    /// @notice Returns the chain ID of the L2 network this contract argues about.\n    function l2ChainId() external view returns (uint256 l2ChainId_) {\n        l2ChainId_ = L2_CHAIN_ID;\n    }\n\n    ////////////////////////////////////////////////////////////////\n    //                          HELPERS                           //\n    ////////////////////////////////////////////////////////////////\n\n    /// @notice Pays out the bond of a claim to a given recipient.\n    /// @param _recipient The recipient of the bond.\n    /// @param _bonded The claim to pay out the bond of.\n    function _distributeBond(address _recipient, ClaimData storage _bonded) internal {\n        // Set all bits in the bond value to indicate that the bond has been paid out.\n        uint256 bond = _bonded.bond;\n        if (bond == CLAIMED_BOND_FLAG) revert ClaimAlreadyResolved();\n        _bonded.bond = CLAIMED_BOND_FLAG;\n\n        // Increase the recipient's credit.\n        credit[_recipient] += bond;\n\n        // Unlock the bond.\n        WETH.unlock(_recipient, bond);\n    }\n\n    /// @notice Verifies the integrity of an execution bisection subgame's root claim. Reverts if the claim\n    ///         is invalid.\n    /// @param _rootClaim The root claim of the execution bisection subgame.\n    function _verifyExecBisectionRoot(\n        Claim _rootClaim,\n        uint256 _parentIdx,\n        Position _parentPos,\n        bool _isAttack\n    )\n        internal\n        view\n    {\n        // The root claim of an execution trace bisection sub-game must:\n        // 1. Signal that the VM panicked or resulted in an invalid transition if the disputed output root\n        //    was made by the opposing party.\n        // 2. Signal that the VM resulted in a valid transition if the disputed output root was made by the same party.\n\n        // If the move is a defense, the disputed output could have been made by either party. In this case, we\n        // need to search for the parent output to determine what the expected status byte should be.\n        Position disputedLeafPos = Position.wrap(_parentPos.raw() + 1);\n        ClaimData storage disputed = _findTraceAncestor({ _pos: disputedLeafPos, _start: _parentIdx, _global: true });\n        uint8 vmStatus = uint8(_rootClaim.raw()[0]);\n\n        if (_isAttack || disputed.position.depth() % 2 == SPLIT_DEPTH % 2) {\n            // If the move is an attack, the parent output is always deemed to be disputed. In this case, we only need\n            // to check that the root claim signals that the VM panicked or resulted in an invalid transition.\n            // If the move is a defense, and the disputed output and creator of the execution trace subgame disagree,\n            // the root claim should also signal that the VM panicked or resulted in an invalid transition.\n            if (!(vmStatus == VMStatuses.INVALID.raw() || vmStatus == VMStatuses.PANIC.raw())) {\n                revert UnexpectedRootClaim(_rootClaim);\n            }\n        } else if (vmStatus != VMStatuses.VALID.raw()) {\n            // The disputed output and the creator of the execution trace subgame agree. The status byte should\n            // have signaled that the VM succeeded.\n            revert UnexpectedRootClaim(_rootClaim);\n        }\n    }\n\n    /// @notice Finds the trace ancestor of a given position within the DAG.\n    /// @param _pos The position to find the trace ancestor claim of.\n    /// @param _start The index to start searching from.\n    /// @param _global Whether or not to search the entire dag or just within an execution trace subgame. If set to\n    ///                `true`, and `_pos` is at or above the split depth, this function will revert.\n    /// @return ancestor_ The ancestor claim that commits to the same trace index as `_pos`.\n    function _findTraceAncestor(\n        Position _pos,\n        uint256 _start,\n        bool _global\n    )\n        internal\n        view\n        returns (ClaimData storage ancestor_)\n    {\n        // Grab the trace ancestor's expected position.\n        Position traceAncestorPos = _global ? _pos.traceAncestor() : _pos.traceAncestorBounded(SPLIT_DEPTH);\n\n        // Walk up the DAG to find a claim that commits to the same trace index as `_pos`. It is\n        // guaranteed that such a claim exists.\n        ancestor_ = claimData[_start];\n        while (ancestor_.position.raw() != traceAncestorPos.raw()) {\n            ancestor_ = claimData[ancestor_.parentIndex];\n        }\n    }\n\n    /// @notice Finds the starting and disputed output root for a given `ClaimData` within the DAG. This\n    ///         `ClaimData` must be below the `SPLIT_DEPTH`.\n    /// @param _start The index within `claimData` of the claim to start searching from.\n    /// @return startingClaim_ The starting output root claim.\n    /// @return startingPos_ The starting output root position.\n    /// @return disputedClaim_ The disputed output root claim.\n    /// @return disputedPos_ The disputed output root position.\n    function _findStartingAndDisputedOutputs(uint256 _start)\n        internal\n        view\n        returns (Claim startingClaim_, Position startingPos_, Claim disputedClaim_, Position disputedPos_)\n    {\n        // Fatch the starting claim.\n        uint256 claimIdx = _start;\n        ClaimData storage claim = claimData[claimIdx];\n\n        // If the starting claim's depth is less than or equal to the split depth, we revert as this is UB.\n        if (claim.position.depth() <= SPLIT_DEPTH) revert ClaimAboveSplit();\n\n        // We want to:\n        // 1. Find the first claim at the split depth.\n        // 2. Determine whether it was the starting or disputed output for the exec game.\n        // 3. Find the complimentary claim depending on the info from #2 (pre or post).\n\n        // Walk up the DAG until the ancestor's depth is equal to the split depth.\n        uint256 currentDepth;\n        ClaimData storage execRootClaim = claim;\n        while ((currentDepth = claim.position.depth()) > SPLIT_DEPTH) {\n            uint256 parentIndex = claim.parentIndex;\n\n            // If we're currently at the split depth + 1, we're at the root of the execution sub-game.\n            // We need to keep track of the root claim here to determine whether the execution sub-game was\n            // started with an attack or defense against the output leaf claim.\n            if (currentDepth == SPLIT_DEPTH + 1) execRootClaim = claim;\n\n            claim = claimData[parentIndex];\n            claimIdx = parentIndex;\n        }\n\n        // Determine whether the start of the execution sub-game was an attack or defense to the output root\n        // above. This is important because it determines which claim is the starting output root and which\n        // is the disputed output root.\n        (Position execRootPos, Position outputPos) = (execRootClaim.position, claim.position);\n        bool wasAttack = execRootPos.parent().raw() == outputPos.raw();\n\n        // Determine the starting and disputed output root indices.\n        // 1. If it was an attack, the disputed output root is `claim`, and the starting output root is\n        //    elsewhere in the DAG (it must commit to the block # index at depth of `outputPos - 1`).\n        // 2. If it was a defense, the starting output root is `claim`, and the disputed output root is\n        //    elsewhere in the DAG (it must commit to the block # index at depth of `outputPos + 1`).\n        if (wasAttack) {\n            // If this is an attack on the first output root (the block directly after genesis), the\n            // starting claim nor position exists in the tree. We leave these as 0, which can be easily\n            // identified due to 0 being an invalid Gindex.\n            if (outputPos.indexAtDepth() > 0) {\n                ClaimData storage starting = _findTraceAncestor(Position.wrap(outputPos.raw() - 1), claimIdx, true);\n                (startingClaim_, startingPos_) = (starting.claim, starting.position);\n            } else {\n                startingClaim_ = Claim.wrap(GENESIS_OUTPUT_ROOT.raw());\n            }\n            (disputedClaim_, disputedPos_) = (claim.claim, claim.position);\n        } else {\n            ClaimData storage disputed = _findTraceAncestor(Position.wrap(outputPos.raw() + 1), claimIdx, true);\n            (startingClaim_, startingPos_) = (claim.claim, claim.position);\n            (disputedClaim_, disputedPos_) = (disputed.claim, disputed.position);\n        }\n    }\n\n    /// @notice Finds the local context hash for a given claim index that is present in an execution trace subgame.\n    /// @param _claimIndex The index of the claim to find the local context hash for.\n    /// @return uuid_ The local context hash.\n    function _findLocalContext(uint256 _claimIndex) internal view returns (Hash uuid_) {\n        (Claim starting, Position startingPos, Claim disputed, Position disputedPos) =\n            _findStartingAndDisputedOutputs(_claimIndex);\n        uuid_ = _computeLocalContext(starting, startingPos, disputed, disputedPos);\n    }\n\n    /// @notice Computes the local context hash for a set of starting/disputed claim values and positions.\n    /// @param _starting The starting claim.\n    /// @param _startingPos The starting claim's position.\n    /// @param _disputed The disputed claim.\n    /// @param _disputedPos The disputed claim's position.\n    /// @return uuid_ The local context hash.\n    function _computeLocalContext(\n        Claim _starting,\n        Position _startingPos,\n        Claim _disputed,\n        Position _disputedPos\n    )\n        internal\n        pure\n        returns (Hash uuid_)\n    {\n        // A position of 0 indicates that the starting claim is the absolute prestate. In this special case,\n        // we do not include the starting claim within the local context hash.\n        if (_startingPos.raw() == 0) {\n            uuid_ = Hash.wrap(keccak256(abi.encode(_disputed, _disputedPos)));\n        } else {\n            uuid_ = Hash.wrap(keccak256(abi.encode(_starting, _startingPos, _disputed, _disputedPos)));\n        }\n    }\n}\n"
      },
      "src/libraries/DisputeTypes.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\nimport { LibHashing } from \"src/dispute/lib/LibHashing.sol\";\nimport {\n    LibClaim,\n    LibHash,\n    LibDuration,\n    LibClock,\n    LibTimestamp,\n    LibVMStatus,\n    LibGameType\n} from \"src/dispute/lib/LibUDT.sol\";\nimport { LibPosition } from \"src/dispute/lib/LibPosition.sol\";\nimport { LibGameId } from \"src/dispute/lib/LibGameId.sol\";\n\nusing LibClaim for Claim global;\nusing LibHashing for Claim global;\nusing LibHash for Hash global;\nusing LibPosition for Position 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 custom type for a generic hash.\ntype Hash is bytes32;\n\n/// @notice A claim represents an MPT root representing the state of the fault proof program.\ntype Claim is bytes32;\n\n/// @notice A claim hash represents a hash of a claim and a position within the game tree.\n/// @dev Keccak hash of abi.encodePacked(Claim, Position);\ntype ClaimHash is bytes32;\n\n/// @notice A bondamount represents the amount of collateral that a user has locked up in a claim.\ntype BondAmount is uint256;\n\n/// @notice A dedicated timestamp type.\ntype Timestamp is uint64;\n\n/// @notice A dedicated duration type.\n/// @dev Unit: seconds\ntype Duration is uint64;\n\n/// @notice A `GameId` represents a packed 1 byte game ID, an 11 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, 8)    │ Game Type │\n/// │ [8, 96)   │ Timestamp │\n/// │ [96, 256) │ Address   │\n/// └───────────┴───────────┘\ntype GameId is bytes32;\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/// └────────────┴────────────────┘\ntype Clock is uint128;\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.\ntype Position is uint128;\n\n/// @notice A `GameType` represents the type of game being played.\ntype GameType is uint32;\n\n/// @notice A `VMStatus` represents the status of a VM execution.\ntype VMStatus is uint8;\n\n/// @notice The current status of the dispute game.\nenum 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/// @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 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"
      },
      "src/libraries/DisputeErrors.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\nimport \"src/libraries/DisputeTypes.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.\nerror 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.\nerror 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.\nerror UnexpectedRootClaim(Claim rootClaim);\n\n////////////////////////////////////////////////////////////////\n//                 `FaultDisputeGame` Errors                  //\n////////////////////////////////////////////////////////////////\n\n/// @notice Thrown when a dispute game has already been initialized.\nerror AlreadyInitialized();\n\n/// @notice Thrown when a supplied bond is too low to cover the cost of the interaction.\nerror InsufficientBond();\n\n/// @notice Thrown when a credit claim is attempted for a value of 0.\nerror NoCreditToClaim();\n\n/// @notice Thrown when the transfer of credit to a recipient account reverts.\nerror BondTransferFailed();\n\n/// @notice Thrown when the `extraData` passed to the CWIA proxy is too long for the `FaultDisputeGame`.\nerror ExtraDataTooLong();\n\n/// @notice Thrown when a defense against the root claim is attempted.\nerror CannotDefendRootClaim();\n\n/// @notice Thrown when a claim is attempting to be made that already exists.\nerror ClaimAlreadyExists();\n\n/// @notice Thrown when a given claim is invalid (0).\nerror InvalidClaim();\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.\nerror GameNotInProgress();\n\n/// @notice Thrown when a move is attempted to be made after the clock has timed out.\nerror ClockTimeExceeded();\n\n/// @notice Thrown when the game is attempted to be resolved too early.\nerror ClockNotExpired();\n\n/// @notice Thrown when a move is attempted to be made at or greater than the max depth of the game.\nerror GameDepthExceeded();\n\n/// @notice Thrown when a step is attempted above the maximum game depth.\nerror InvalidParent();\n\n/// @notice Thrown when an invalid prestate is supplied to `step`.\nerror InvalidPrestate();\n\n/// @notice Thrown when a step is made that computes the expected post state correctly.\nerror 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.\nerror L1HeadTooOld();\n\n/// @notice Thrown when an invalid local identifier is passed to the `addLocalData` function.\nerror InvalidLocalIdent();\n\n/// @notice Thrown when resolving claims out of order.\nerror OutOfOrderResolution();\n\n/// @notice Thrown when resolving a claim that has already been resolved.\nerror 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.\nerror ClaimAboveSplit();\n\n/// @notice Thrown on deployment if the split depth is greater than or equal to the max\n///         depth of the game.\nerror InvalidSplitDepth();\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.\nerror DuplicateStep();\n\n////////////////////////////////////////////////////////////////\n//              `PermissionedDisputeGame` Errors              //\n////////////////////////////////////////////////////////////////\n\n/// @notice Thrown when an unauthorized address attempts to interact with the game.\nerror BadAuth();\n"
      },
      "src/dispute/interfaces/IWETH.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\n/// @title IWETH\n/// @notice Interface for WETH9.\ninterface IWETH {\n    /// @notice Emitted when an approval is made.\n    /// @param src The address that approved the transfer.\n    /// @param guy The address that was approved to transfer.\n    /// @param wad The amount that was approved to transfer.\n    event Approval(address indexed src, address indexed guy, uint256 wad);\n\n    /// @notice Emitted when a transfer is made.\n    /// @param src The address that transferred the WETH.\n    /// @param dst The address that received the WETH.\n    /// @param wad The amount of WETH that was transferred.\n    event Transfer(address indexed src, address indexed dst, uint256 wad);\n\n    /// @notice Emitted when a deposit is made.\n    /// @param dst The address that deposited the WETH.\n    /// @param wad The amount of WETH that was deposited.\n    event Deposit(address indexed dst, uint256 wad);\n\n    /// @notice Emitted when a withdrawal is made.\n    /// @param src The address that withdrew the WETH.\n    /// @param wad The amount of WETH that was withdrawn.\n    event Withdrawal(address indexed src, uint256 wad);\n\n    /// @notice Returns the name of the token.\n    /// @return The name of the token.\n    function name() external pure returns (string memory);\n\n    /// @notice Returns the symbol of the token.\n    /// @return The symbol of the token.\n    function symbol() external pure returns (string memory);\n\n    /// @notice Returns the number of decimals the token uses.\n    /// @return The number of decimals the token uses.\n    function decimals() external pure returns (uint8);\n\n    /// @notice Returns the balance of the given address.\n    /// @param owner The address to query the balance of.\n    /// @return The balance of the given address.\n    function balanceOf(address owner) external view returns (uint256);\n\n    /// @notice Returns the amount of WETH that the spender can transfer on behalf of the owner.\n    /// @param owner The address that owns the WETH.\n    /// @param spender The address that is approved to transfer the WETH.\n    /// @return The amount of WETH that the spender can transfer on behalf of the owner.\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /// @notice Allows WETH to be deposited by sending ether to the contract.\n    function deposit() external payable;\n\n    /// @notice Withdraws an amount of ETH.\n    /// @param wad The amount of ETH to withdraw.\n    function withdraw(uint256 wad) external;\n\n    /// @notice Returns the total supply of WETH.\n    /// @return The total supply of WETH.\n    function totalSupply() external view returns (uint256);\n\n    /// @notice Approves the given address to transfer the WETH on behalf of the caller.\n    /// @param guy The address that is approved to transfer the WETH.\n    /// @param wad The amount that is approved to transfer.\n    /// @return True if the approval was successful.\n    function approve(address guy, uint256 wad) external returns (bool);\n\n    /// @notice Transfers the given amount of WETH to the given address.\n    /// @param dst The address to transfer the WETH to.\n    /// @param wad The amount of WETH to transfer.\n    /// @return True if the transfer was successful.\n    function transfer(address dst, uint256 wad) external returns (bool);\n\n    /// @notice Transfers the given amount of WETH from the given address to the given address.\n    /// @param src The address to transfer the WETH from.\n    /// @param dst The address to transfer the WETH to.\n    /// @param wad The amount of WETH to transfer.\n    /// @return True if the transfer was successful.\n    function transferFrom(address src, address dst, uint256 wad) external returns (bool);\n}\n"
      },
      "lib/solady/src/utils/FixedPointMathLib.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/// @notice Arithmetic library with operations for fixed-point numbers.\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/FixedPointMathLib.sol)\n/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol)\nlibrary FixedPointMathLib {\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                       CUSTOM ERRORS                        */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The operation failed, as the output exceeds the maximum value of uint256.\n    error ExpOverflow();\n\n    /// @dev The operation failed, as the output exceeds the maximum value of uint256.\n    error FactorialOverflow();\n\n    /// @dev The operation failed, due to an overflow.\n    error RPowOverflow();\n\n    /// @dev The mantissa is too big to fit.\n    error MantissaOverflow();\n\n    /// @dev The operation failed, due to an multiplication overflow.\n    error MulWadFailed();\n\n    /// @dev The operation failed, due to an multiplication overflow.\n    error SMulWadFailed();\n\n    /// @dev The operation failed, either due to a multiplication overflow, or a division by a zero.\n    error DivWadFailed();\n\n    /// @dev The operation failed, either due to a multiplication overflow, or a division by a zero.\n    error SDivWadFailed();\n\n    /// @dev The operation failed, either due to a multiplication overflow, or a division by a zero.\n    error MulDivFailed();\n\n    /// @dev The division failed, as the denominator is zero.\n    error DivFailed();\n\n    /// @dev The full precision multiply-divide operation failed, either due\n    /// to the result being larger than 256 bits, or a division by a zero.\n    error FullMulDivFailed();\n\n    /// @dev The output is undefined, as the input is less-than-or-equal to zero.\n    error LnWadUndefined();\n\n    /// @dev The input outside the acceptable domain.\n    error OutOfDomain();\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                         CONSTANTS                          */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The scalar of ETH and most ERC20s.\n    uint256 internal constant WAD = 1e18;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*              SIMPLIFIED FIXED POINT OPERATIONS             */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Equivalent to `(x * y) / WAD` rounded down.\n    function mulWad(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Equivalent to `require(y == 0 || x <= type(uint256).max / y)`.\n            if mul(y, gt(x, div(not(0), y))) {\n                mstore(0x00, 0xbac65e5b) // `MulWadFailed()`.\n                revert(0x1c, 0x04)\n            }\n            z := div(mul(x, y), WAD)\n        }\n    }\n\n    /// @dev Equivalent to `(x * y) / WAD` rounded down.\n    function sMulWad(int256 x, int256 y) internal pure returns (int256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := mul(x, y)\n            // Equivalent to `require((x == 0 || z / x == y) && !(x == -1 && y == type(int256).min))`.\n            if iszero(gt(or(iszero(x), eq(sdiv(z, x), y)), lt(not(x), eq(y, shl(255, 1))))) {\n                mstore(0x00, 0xedcd4dd4) // `SMulWadFailed()`.\n                revert(0x1c, 0x04)\n            }\n            z := sdiv(z, WAD)\n        }\n    }\n\n    /// @dev Equivalent to `(x * y) / WAD` rounded down, but without overflow checks.\n    function rawMulWad(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := div(mul(x, y), WAD)\n        }\n    }\n\n    /// @dev Equivalent to `(x * y) / WAD` rounded down, but without overflow checks.\n    function rawSMulWad(int256 x, int256 y) internal pure returns (int256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := sdiv(mul(x, y), WAD)\n        }\n    }\n\n    /// @dev Equivalent to `(x * y) / WAD` rounded up.\n    function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Equivalent to `require(y == 0 || x <= type(uint256).max / y)`.\n            if mul(y, gt(x, div(not(0), y))) {\n                mstore(0x00, 0xbac65e5b) // `MulWadFailed()`.\n                revert(0x1c, 0x04)\n            }\n            z := add(iszero(iszero(mod(mul(x, y), WAD))), div(mul(x, y), WAD))\n        }\n    }\n\n    /// @dev Equivalent to `(x * y) / WAD` rounded up, but without overflow checks.\n    function rawMulWadUp(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := add(iszero(iszero(mod(mul(x, y), WAD))), div(mul(x, y), WAD))\n        }\n    }\n\n    /// @dev Equivalent to `(x * WAD) / y` rounded down.\n    function divWad(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Equivalent to `require(y != 0 && (WAD == 0 || x <= type(uint256).max / WAD))`.\n            if iszero(mul(y, iszero(mul(WAD, gt(x, div(not(0), WAD)))))) {\n                mstore(0x00, 0x7c5f487d) // `DivWadFailed()`.\n                revert(0x1c, 0x04)\n            }\n            z := div(mul(x, WAD), y)\n        }\n    }\n\n    /// @dev Equivalent to `(x * WAD) / y` rounded down.\n    function sDivWad(int256 x, int256 y) internal pure returns (int256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := mul(x, WAD)\n            // Equivalent to `require(y != 0 && ((x * WAD) / WAD == x))`.\n            if iszero(and(iszero(iszero(y)), eq(sdiv(z, WAD), x))) {\n                mstore(0x00, 0x5c43740d) // `SDivWadFailed()`.\n                revert(0x1c, 0x04)\n            }\n            z := sdiv(mul(x, WAD), y)\n        }\n    }\n\n    /// @dev Equivalent to `(x * WAD) / y` rounded down, but without overflow and divide by zero checks.\n    function rawDivWad(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := div(mul(x, WAD), y)\n        }\n    }\n\n    /// @dev Equivalent to `(x * WAD) / y` rounded down, but without overflow and divide by zero checks.\n    function rawSDivWad(int256 x, int256 y) internal pure returns (int256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := sdiv(mul(x, WAD), y)\n        }\n    }\n\n    /// @dev Equivalent to `(x * WAD) / y` rounded up.\n    function divWadUp(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Equivalent to `require(y != 0 && (WAD == 0 || x <= type(uint256).max / WAD))`.\n            if iszero(mul(y, iszero(mul(WAD, gt(x, div(not(0), WAD)))))) {\n                mstore(0x00, 0x7c5f487d) // `DivWadFailed()`.\n                revert(0x1c, 0x04)\n            }\n            z := add(iszero(iszero(mod(mul(x, WAD), y))), div(mul(x, WAD), y))\n        }\n    }\n\n    /// @dev Equivalent to `(x * WAD) / y` rounded up, but without overflow and divide by zero checks.\n    function rawDivWadUp(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := add(iszero(iszero(mod(mul(x, WAD), y))), div(mul(x, WAD), y))\n        }\n    }\n\n    /// @dev Equivalent to `x` to the power of `y`.\n    /// because `x ** y = (e ** ln(x)) ** y = e ** (ln(x) * y)`.\n    function powWad(int256 x, int256 y) internal pure returns (int256) {\n        // Using `ln(x)` means `x` must be greater than 0.\n        return expWad((lnWad(x) * y) / int256(WAD));\n    }\n\n    /// @dev Returns `exp(x)`, denominated in `WAD`.\n    /// Credit to Remco Bloemen under MIT license: https://2π.com/21/exp-ln\n    function expWad(int256 x) internal pure returns (int256 r) {\n        unchecked {\n            // When the result is less than 0.5 we return zero.\n            // This happens when `x <= floor(log(0.5e18) * 1e18) ≈ -42e18`.\n            if (x <= -41446531673892822313) return r;\n\n            /// @solidity memory-safe-assembly\n            assembly {\n                // When the result is greater than `(2**255 - 1) / 1e18` we can not represent it as\n                // an int. This happens when `x >= floor(log((2**255 - 1) / 1e18) * 1e18) ≈ 135`.\n                if iszero(slt(x, 135305999368893231589)) {\n                    mstore(0x00, 0xa37bfec9) // `ExpOverflow()`.\n                    revert(0x1c, 0x04)\n                }\n            }\n\n            // `x` is now in the range `(-42, 136) * 1e18`. Convert to `(-42, 136) * 2**96`\n            // for more intermediate precision and a binary basis. This base conversion\n            // is a multiplication by 1e18 / 2**96 = 5**18 / 2**78.\n            x = (x << 78) / 5 ** 18;\n\n            // Reduce range of x to (-½ ln 2, ½ ln 2) * 2**96 by factoring out powers\n            // of two such that exp(x) = exp(x') * 2**k, where k is an integer.\n            // Solving this gives k = round(x / log(2)) and x' = x - k * log(2).\n            int256 k = ((x << 96) / 54916777467707473351141471128 + 2 ** 95) >> 96;\n            x = x - k * 54916777467707473351141471128;\n\n            // `k` is in the range `[-61, 195]`.\n\n            // Evaluate using a (6, 7)-term rational approximation.\n            // `p` is made monic, we'll multiply by a scale factor later.\n            int256 y = x + 1346386616545796478920950773328;\n            y = ((y * x) >> 96) + 57155421227552351082224309758442;\n            int256 p = y + x - 94201549194550492254356042504812;\n            p = ((p * y) >> 96) + 28719021644029726153956944680412240;\n            p = p * x + (4385272521454847904659076985693276 << 96);\n\n            // We leave `p` in `2**192` basis so we don't need to scale it back up for the division.\n            int256 q = x - 2855989394907223263936484059900;\n            q = ((q * x) >> 96) + 50020603652535783019961831881945;\n            q = ((q * x) >> 96) - 533845033583426703283633433725380;\n            q = ((q * x) >> 96) + 3604857256930695427073651918091429;\n            q = ((q * x) >> 96) - 14423608567350463180887372962807573;\n            q = ((q * x) >> 96) + 26449188498355588339934803723976023;\n\n            /// @solidity memory-safe-assembly\n            assembly {\n                // Div in assembly because solidity adds a zero check despite the unchecked.\n                // The q polynomial won't have zeros in the domain as all its roots are complex.\n                // No scaling is necessary because p is already `2**96` too large.\n                r := sdiv(p, q)\n            }\n\n            // r should be in the range `(0.09, 0.25) * 2**96`.\n\n            // We now need to multiply r by:\n            // - The scale factor `s ≈ 6.031367120`.\n            // - The `2**k` factor from the range reduction.\n            // - The `1e18 / 2**96` factor for base conversion.\n            // We do this all at once, with an intermediate result in `2**213`\n            // basis, so the final right shift is always by a positive amount.\n            r = int256(\n                (uint256(r) * 3822833074963236453042738258902158003155416615667) >> uint256(195 - k)\n            );\n        }\n    }\n\n    /// @dev Returns `ln(x)`, denominated in `WAD`.\n    /// Credit to Remco Bloemen under MIT license: https://2π.com/21/exp-ln\n    function lnWad(int256 x) internal pure returns (int256 r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // We want to convert `x` from `10**18` fixed point to `2**96` fixed point.\n            // We do this by multiplying by `2**96 / 10**18`. But since\n            // `ln(x * C) = ln(x) + ln(C)`, we can simply do nothing here\n            // and add `ln(2**96 / 10**18)` at the end.\n\n            // Compute `k = log2(x) - 96`, `r = 159 - k = 255 - log2(x) = 255 ^ log2(x)`.\n            r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))\n            r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))\n            r := or(r, shl(5, lt(0xffffffff, shr(r, x))))\n            r := or(r, shl(4, lt(0xffff, shr(r, x))))\n            r := or(r, shl(3, lt(0xff, shr(r, x))))\n            // We place the check here for more optimal stack operations.\n            if iszero(sgt(x, 0)) {\n                mstore(0x00, 0x1615e638) // `LnWadUndefined()`.\n                revert(0x1c, 0x04)\n            }\n            // forgefmt: disable-next-item\n            r := xor(r, byte(and(0x1f, shr(shr(r, x), 0x8421084210842108cc6318c6db6d54be)),\n                0xf8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff))\n\n            // Reduce range of x to (1, 2) * 2**96\n            // ln(2^k * x) = k * ln(2) + ln(x)\n            x := shr(159, shl(r, x))\n\n            // Evaluate using a (8, 8)-term rational approximation.\n            // `p` is made monic, we will multiply by a scale factor later.\n            // forgefmt: disable-next-item\n            let p := sub( // This heavily nested expression is to avoid stack-too-deep for via-ir.\n                sar(96, mul(add(43456485725739037958740375743393,\n                sar(96, mul(add(24828157081833163892658089445524,\n                sar(96, mul(add(3273285459638523848632254066296,\n                    x), x))), x))), x)), 11111509109440967052023855526967)\n            p := sub(sar(96, mul(p, x)), 45023709667254063763336534515857)\n            p := sub(sar(96, mul(p, x)), 14706773417378608786704636184526)\n            p := sub(mul(p, x), shl(96, 795164235651350426258249787498))\n            // We leave `p` in `2**192` basis so we don't need to scale it back up for the division.\n\n            // `q` is monic by convention.\n            let q := add(5573035233440673466300451813936, x)\n            q := add(71694874799317883764090561454958, sar(96, mul(x, q)))\n            q := add(283447036172924575727196451306956, sar(96, mul(x, q)))\n            q := add(401686690394027663651624208769553, sar(96, mul(x, q)))\n            q := add(204048457590392012362485061816622, sar(96, mul(x, q)))\n            q := add(31853899698501571402653359427138, sar(96, mul(x, q)))\n            q := add(909429971244387300277376558375, sar(96, mul(x, q)))\n\n            // `p / q` is in the range `(0, 0.125) * 2**96`.\n\n            // Finalization, we need to:\n            // - Multiply by the scale factor `s = 5.549…`.\n            // - Add `ln(2**96 / 10**18)`.\n            // - Add `k * ln(2)`.\n            // - Multiply by `10**18 / 2**96 = 5**18 >> 78`.\n\n            // The q polynomial is known not to have zeros in the domain.\n            // No scaling required because p is already `2**96` too large.\n            p := sdiv(p, q)\n            // Multiply by the scaling factor: `s * 5**18 * 2**96`, base is now `5**18 * 2**192`.\n            p := mul(1677202110996718588342820967067443963516166, p)\n            // Add `ln(2) * k * 5**18 * 2**192`.\n            // forgefmt: disable-next-item\n            p := add(mul(16597577552685614221487285958193947469193820559219878177908093499208371, sub(159, r)), p)\n            // Add `ln(2**96 / 10**18) * 5**18 * 2**192`.\n            p := add(600920179829731861736702779321621459595472258049074101567377883020018308, p)\n            // Base conversion: mul `2**18 / 2**192`.\n            r := sar(174, p)\n        }\n    }\n\n    /// @dev Returns `W_0(x)`, denominated in `WAD`.\n    /// See: https://en.wikipedia.org/wiki/Lambert_W_function\n    /// a.k.a. Product log function. This is an approximation of the principal branch.\n    function lambertW0Wad(int256 x) internal pure returns (int256 w) {\n        // forgefmt: disable-next-item\n        unchecked {\n            if ((w = x) <= -367879441171442322) revert OutOfDomain(); // `x` less than `-1/e`.\n            int256 wad = int256(WAD);\n            int256 p = x;\n            uint256 c; // Whether we need to avoid catastrophic cancellation.\n            uint256 i = 4; // Number of iterations.\n            if (w <= 0x1ffffffffffff) {\n                if (-0x4000000000000 <= w) {\n                    i = 1; // Inputs near zero only take one step to converge.\n                } else if (w <= -0x3ffffffffffffff) {\n                    i = 32; // Inputs near `-1/e` take very long to converge.\n                }\n            } else if (w >> 63 == 0) {\n                /// @solidity memory-safe-assembly\n                assembly {\n                    // Inline log2 for more performance, since the range is small.\n                    let v := shr(49, w)\n                    let l := shl(3, lt(0xff, v))\n                    l := add(or(l, byte(and(0x1f, shr(shr(l, v), 0x8421084210842108cc6318c6db6d54be)),\n                        0x0706060506020504060203020504030106050205030304010505030400000000)), 49)\n                    w := sdiv(shl(l, 7), byte(sub(l, 31), 0x0303030303030303040506080c13))\n                    c := gt(l, 60)\n                    i := add(2, add(gt(l, 53), c))\n                }\n            } else {\n                int256 ll = lnWad(w = lnWad(w));\n                /// @solidity memory-safe-assembly\n                assembly {\n                    // `w = ln(x) - ln(ln(x)) + b * ln(ln(x)) / ln(x)`.\n                    w := add(sdiv(mul(ll, 1023715080943847266), w), sub(w, ll))\n                    i := add(3, iszero(shr(68, x)))\n                    c := iszero(shr(143, x))\n                }\n                if (c == 0) {\n                    do { // If `x` is big, use Newton's so that intermediate values won't overflow.\n                        int256 e = expWad(w);\n                        /// @solidity memory-safe-assembly\n                        assembly {\n                            let t := mul(w, div(e, wad))\n                            w := sub(w, sdiv(sub(t, x), div(add(e, t), wad)))\n                        }\n                        if (p <= w) break;\n                        p = w;\n                    } while (--i != 0);\n                    /// @solidity memory-safe-assembly\n                    assembly {\n                        w := sub(w, sgt(w, 2))\n                    }\n                    return w;\n                }\n            }\n            do { // Otherwise, use Halley's for faster convergence.\n                int256 e = expWad(w);\n                /// @solidity memory-safe-assembly\n                assembly {\n                    let t := add(w, wad)\n                    let s := sub(mul(w, e), mul(x, wad))\n                    w := sub(w, sdiv(mul(s, wad), sub(mul(e, t), sdiv(mul(add(t, wad), s), add(t, t)))))\n                }\n                if (p <= w) break;\n                p = w;\n            } while (--i != c);\n            /// @solidity memory-safe-assembly\n            assembly {\n                w := sub(w, sgt(w, 2))\n            }\n            // For certain ranges of `x`, we'll use the quadratic-rate recursive formula of\n            // R. Iacono and J.P. Boyd for the last iteration, to avoid catastrophic cancellation.\n            if (c != 0) {\n                int256 t = w | 1;\n                /// @solidity memory-safe-assembly\n                assembly {\n                    x := sdiv(mul(x, wad), t)\n                }\n                x = (t * (wad + lnWad(x)));\n                /// @solidity memory-safe-assembly\n                assembly {\n                    w := sdiv(x, add(wad, t))\n                }\n            }\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                  GENERAL NUMBER UTILITIES                  */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Calculates `floor(a * b / d)` with full precision.\n    /// Throws if result overflows a uint256 or when `d` is zero.\n    /// Credit to Remco Bloemen under MIT license: https://2π.com/21/muldiv\n    function fullMulDiv(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            for {} 1 {} {\n                // 512-bit multiply `[p1 p0] = x * y`.\n                // Compute the product mod `2**256` and mod `2**256 - 1`\n                // then use the Chinese Remainder Theorem to reconstruct\n                // the 512 bit result. The result is stored in two 256\n                // variables such that `product = p1 * 2**256 + p0`.\n\n                // Least significant 256 bits of the product.\n                result := mul(x, y) // Temporarily use `result` as `p0` to save gas.\n                let mm := mulmod(x, y, not(0))\n                // Most significant 256 bits of the product.\n                let p1 := sub(mm, add(result, lt(mm, result)))\n\n                // Handle non-overflow cases, 256 by 256 division.\n                if iszero(p1) {\n                    if iszero(d) {\n                        mstore(0x00, 0xae47f702) // `FullMulDivFailed()`.\n                        revert(0x1c, 0x04)\n                    }\n                    result := div(result, d)\n                    break\n                }\n\n                // Make sure the result is less than `2**256`. Also prevents `d == 0`.\n                if iszero(gt(d, p1)) {\n                    mstore(0x00, 0xae47f702) // `FullMulDivFailed()`.\n                    revert(0x1c, 0x04)\n                }\n\n                /*------------------- 512 by 256 division --------------------*/\n\n                // Make division exact by subtracting the remainder from `[p1 p0]`.\n                // Compute remainder using mulmod.\n                let r := mulmod(x, y, d)\n                // `t` is the least significant bit of `d`.\n                // Always greater or equal to 1.\n                let t := and(d, sub(0, d))\n                // Divide `d` by `t`, which is a power of two.\n                d := div(d, t)\n                // Invert `d mod 2**256`\n                // Now that `d` is an odd number, it has an inverse\n                // modulo `2**256` such that `d * inv = 1 mod 2**256`.\n                // Compute the inverse by starting with a seed that is correct\n                // correct for four bits. That is, `d * inv = 1 mod 2**4`.\n                let inv := xor(2, mul(3, d))\n                // Now use Newton-Raphson iteration to improve the precision.\n                // Thanks to Hensel's lifting lemma, this also works in modular\n                // arithmetic, doubling the correct bits in each step.\n                inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**8\n                inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**16\n                inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**32\n                inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**64\n                inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**128\n                result :=\n                    mul(\n                        // Divide [p1 p0] by the factors of two.\n                        // Shift in bits from `p1` into `p0`. For this we need\n                        // to flip `t` such that it is `2**256 / t`.\n                        or(\n                            mul(sub(p1, gt(r, result)), add(div(sub(0, t), t), 1)),\n                            div(sub(result, r), t)\n                        ),\n                        // inverse mod 2**256\n                        mul(inv, sub(2, mul(d, inv)))\n                    )\n                break\n            }\n        }\n    }\n\n    /// @dev Calculates `floor(x * y / d)` with full precision, rounded up.\n    /// Throws if result overflows a uint256 or when `d` is zero.\n    /// Credit to Uniswap-v3-core under MIT license:\n    /// https://github.com/Uniswap/v3-core/blob/contracts/libraries/FullMath.sol\n    function fullMulDivUp(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 result) {\n        result = fullMulDiv(x, y, d);\n        /// @solidity memory-safe-assembly\n        assembly {\n            if mulmod(x, y, d) {\n                result := add(result, 1)\n                if iszero(result) {\n                    mstore(0x00, 0xae47f702) // `FullMulDivFailed()`.\n                    revert(0x1c, 0x04)\n                }\n            }\n        }\n    }\n\n    /// @dev Returns `floor(x * y / d)`.\n    /// Reverts if `x * y` overflows, or `d` is zero.\n    function mulDiv(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Equivalent to require(d != 0 && (y == 0 || x <= type(uint256).max / y))\n            if iszero(mul(d, iszero(mul(y, gt(x, div(not(0), y)))))) {\n                mstore(0x00, 0xad251c27) // `MulDivFailed()`.\n                revert(0x1c, 0x04)\n            }\n            z := div(mul(x, y), d)\n        }\n    }\n\n    /// @dev Returns `ceil(x * y / d)`.\n    /// Reverts if `x * y` overflows, or `d` is zero.\n    function mulDivUp(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Equivalent to require(d != 0 && (y == 0 || x <= type(uint256).max / y))\n            if iszero(mul(d, iszero(mul(y, gt(x, div(not(0), y)))))) {\n                mstore(0x00, 0xad251c27) // `MulDivFailed()`.\n                revert(0x1c, 0x04)\n            }\n            z := add(iszero(iszero(mod(mul(x, y), d))), div(mul(x, y), d))\n        }\n    }\n\n    /// @dev Returns `ceil(x / d)`.\n    /// Reverts if `d` is zero.\n    function divUp(uint256 x, uint256 d) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            if iszero(d) {\n                mstore(0x00, 0x65244e4e) // `DivFailed()`.\n                revert(0x1c, 0x04)\n            }\n            z := add(iszero(iszero(mod(x, d))), div(x, d))\n        }\n    }\n\n    /// @dev Returns `max(0, x - y)`.\n    function zeroFloorSub(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := mul(gt(x, y), sub(x, y))\n        }\n    }\n\n    /// @dev Exponentiate `x` to `y` by squaring, denominated in base `b`.\n    /// Reverts if the computation overflows.\n    function rpow(uint256 x, uint256 y, uint256 b) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := mul(b, iszero(y)) // `0 ** 0 = 1`. Otherwise, `0 ** n = 0`.\n            if x {\n                z := xor(b, mul(xor(b, x), and(y, 1))) // `z = isEven(y) ? scale : x`\n                let half := shr(1, b) // Divide `b` by 2.\n                // Divide `y` by 2 every iteration.\n                for { y := shr(1, y) } y { y := shr(1, y) } {\n                    let xx := mul(x, x) // Store x squared.\n                    let xxRound := add(xx, half) // Round to the nearest number.\n                    // Revert if `xx + half` overflowed, or if `x ** 2` overflows.\n                    if or(lt(xxRound, xx), shr(128, x)) {\n                        mstore(0x00, 0x49f7642b) // `RPowOverflow()`.\n                        revert(0x1c, 0x04)\n                    }\n                    x := div(xxRound, b) // Set `x` to scaled `xxRound`.\n                    // If `y` is odd:\n                    if and(y, 1) {\n                        let zx := mul(z, x) // Compute `z * x`.\n                        let zxRound := add(zx, half) // Round to the nearest number.\n                        // If `z * x` overflowed or `zx + half` overflowed:\n                        if or(xor(div(zx, x), z), lt(zxRound, zx)) {\n                            // Revert if `x` is non-zero.\n                            if iszero(iszero(x)) {\n                                mstore(0x00, 0x49f7642b) // `RPowOverflow()`.\n                                revert(0x1c, 0x04)\n                            }\n                        }\n                        z := div(zxRound, b) // Return properly scaled `zxRound`.\n                    }\n                }\n            }\n        }\n    }\n\n    /// @dev Returns the square root of `x`.\n    function sqrt(uint256 x) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // `floor(sqrt(2**15)) = 181`. `sqrt(2**15) - 181 = 2.84`.\n            z := 181 // The \"correct\" value is 1, but this saves a multiplication later.\n\n            // This segment is to get a reasonable initial estimate for the Babylonian method. With a bad\n            // start, the correct # of bits increases ~linearly each iteration instead of ~quadratically.\n\n            // Let `y = x / 2**r`. We check `y >= 2**(k + 8)`\n            // but shift right by `k` bits to ensure that if `x >= 256`, then `y >= 256`.\n            let r := shl(7, lt(0xffffffffffffffffffffffffffffffffff, x))\n            r := or(r, shl(6, lt(0xffffffffffffffffff, shr(r, x))))\n            r := or(r, shl(5, lt(0xffffffffff, shr(r, x))))\n            r := or(r, shl(4, lt(0xffffff, shr(r, x))))\n            z := shl(shr(1, r), z)\n\n            // Goal was to get `z*z*y` within a small factor of `x`. More iterations could\n            // get y in a tighter range. Currently, we will have y in `[256, 256*(2**16))`.\n            // We ensured `y >= 256` so that the relative difference between `y` and `y+1` is small.\n            // That's not possible if `x < 256` but we can just verify those cases exhaustively.\n\n            // Now, `z*z*y <= x < z*z*(y+1)`, and `y <= 2**(16+8)`, and either `y >= 256`, or `x < 256`.\n            // Correctness can be checked exhaustively for `x < 256`, so we assume `y >= 256`.\n            // Then `z*sqrt(y)` is within `sqrt(257)/sqrt(256)` of `sqrt(x)`, or about 20bps.\n\n            // For `s` in the range `[1/256, 256]`, the estimate `f(s) = (181/1024) * (s+1)`\n            // is in the range `(1/2.84 * sqrt(s), 2.84 * sqrt(s))`,\n            // with largest error when `s = 1` and when `s = 256` or `1/256`.\n\n            // Since `y` is in `[256, 256*(2**16))`, let `a = y/65536`, so that `a` is in `[1/256, 256)`.\n            // Then we can estimate `sqrt(y)` using\n            // `sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2**18`.\n\n            // There is no overflow risk here since `y < 2**136` after the first branch above.\n            z := shr(18, mul(z, add(shr(r, x), 65536))) // A `mul()` is saved from starting `z` at 181.\n\n            // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough.\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n\n            // If `x+1` is a perfect square, the Babylonian method cycles between\n            // `floor(sqrt(x))` and `ceil(sqrt(x))`. This statement ensures we return floor.\n            // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division\n            z := sub(z, lt(div(x, z), z))\n        }\n    }\n\n    /// @dev Returns the cube root of `x`.\n    /// Credit to bout3fiddy and pcaversaccio under AGPLv3 license:\n    /// https://github.com/pcaversaccio/snekmate/blob/main/src/utils/Math.vy\n    function cbrt(uint256 x) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))\n            r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))\n            r := or(r, shl(5, lt(0xffffffff, shr(r, x))))\n            r := or(r, shl(4, lt(0xffff, shr(r, x))))\n            r := or(r, shl(3, lt(0xff, shr(r, x))))\n\n            z := div(shl(div(r, 3), shl(lt(0xf, shr(r, x)), 0xf)), xor(7, mod(r, 3)))\n\n            z := div(add(add(div(x, mul(z, z)), z), z), 3)\n            z := div(add(add(div(x, mul(z, z)), z), z), 3)\n            z := div(add(add(div(x, mul(z, z)), z), z), 3)\n            z := div(add(add(div(x, mul(z, z)), z), z), 3)\n            z := div(add(add(div(x, mul(z, z)), z), z), 3)\n            z := div(add(add(div(x, mul(z, z)), z), z), 3)\n            z := div(add(add(div(x, mul(z, z)), z), z), 3)\n\n            z := sub(z, lt(div(x, mul(z, z)), z))\n        }\n    }\n\n    /// @dev Returns the square root of `x`, denominated in `WAD`.\n    function sqrtWad(uint256 x) internal pure returns (uint256 z) {\n        unchecked {\n            z = 10 ** 9;\n            if (x <= type(uint256).max / 10 ** 36 - 1) {\n                x *= 10 ** 18;\n                z = 1;\n            }\n            z *= sqrt(x);\n        }\n    }\n\n    /// @dev Returns the cube root of `x`, denominated in `WAD`.\n    function cbrtWad(uint256 x) internal pure returns (uint256 z) {\n        unchecked {\n            z = 10 ** 12;\n            if (x <= (type(uint256).max / 10 ** 36) * 10 ** 18 - 1) {\n                if (x >= type(uint256).max / 10 ** 36) {\n                    x *= 10 ** 18;\n                    z = 10 ** 6;\n                } else {\n                    x *= 10 ** 36;\n                    z = 1;\n                }\n            }\n            z *= cbrt(x);\n        }\n    }\n\n    /// @dev Returns the factorial of `x`.\n    function factorial(uint256 x) internal pure returns (uint256 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            if iszero(lt(x, 58)) {\n                mstore(0x00, 0xaba0f2a2) // `FactorialOverflow()`.\n                revert(0x1c, 0x04)\n            }\n            for { result := 1 } x { x := sub(x, 1) } { result := mul(result, x) }\n        }\n    }\n\n    /// @dev Returns the log2 of `x`.\n    /// Equivalent to computing the index of the most significant bit (MSB) of `x`.\n    /// Returns 0 if `x` is zero.\n    function log2(uint256 x) internal pure returns (uint256 r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))\n            r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))\n            r := or(r, shl(5, lt(0xffffffff, shr(r, x))))\n            r := or(r, shl(4, lt(0xffff, shr(r, x))))\n            r := or(r, shl(3, lt(0xff, shr(r, x))))\n            // forgefmt: disable-next-item\n            r := or(r, byte(and(0x1f, shr(shr(r, x), 0x8421084210842108cc6318c6db6d54be)),\n                0x0706060506020504060203020504030106050205030304010505030400000000))\n        }\n    }\n\n    /// @dev Returns the log2 of `x`, rounded up.\n    /// Returns 0 if `x` is zero.\n    function log2Up(uint256 x) internal pure returns (uint256 r) {\n        r = log2(x);\n        /// @solidity memory-safe-assembly\n        assembly {\n            r := add(r, lt(shl(r, 1), x))\n        }\n    }\n\n    /// @dev Returns the log10 of `x`.\n    /// Returns 0 if `x` is zero.\n    function log10(uint256 x) internal pure returns (uint256 r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            if iszero(lt(x, 100000000000000000000000000000000000000)) {\n                x := div(x, 100000000000000000000000000000000000000)\n                r := 38\n            }\n            if iszero(lt(x, 100000000000000000000)) {\n                x := div(x, 100000000000000000000)\n                r := add(r, 20)\n            }\n            if iszero(lt(x, 10000000000)) {\n                x := div(x, 10000000000)\n                r := add(r, 10)\n            }\n            if iszero(lt(x, 100000)) {\n                x := div(x, 100000)\n                r := add(r, 5)\n            }\n            r := add(r, add(gt(x, 9), add(gt(x, 99), add(gt(x, 999), gt(x, 9999)))))\n        }\n    }\n\n    /// @dev Returns the log10 of `x`, rounded up.\n    /// Returns 0 if `x` is zero.\n    function log10Up(uint256 x) internal pure returns (uint256 r) {\n        r = log10(x);\n        /// @solidity memory-safe-assembly\n        assembly {\n            r := add(r, lt(exp(10, r), x))\n        }\n    }\n\n    /// @dev Returns the log256 of `x`.\n    /// Returns 0 if `x` is zero.\n    function log256(uint256 x) internal pure returns (uint256 r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))\n            r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))\n            r := or(r, shl(5, lt(0xffffffff, shr(r, x))))\n            r := or(r, shl(4, lt(0xffff, shr(r, x))))\n            r := or(shr(3, r), lt(0xff, shr(r, x)))\n        }\n    }\n\n    /// @dev Returns the log256 of `x`, rounded up.\n    /// Returns 0 if `x` is zero.\n    function log256Up(uint256 x) internal pure returns (uint256 r) {\n        r = log256(x);\n        /// @solidity memory-safe-assembly\n        assembly {\n            r := add(r, lt(shl(shl(3, r), 1), x))\n        }\n    }\n\n    /// @dev Returns the scientific notation format `mantissa * 10 ** exponent` of `x`.\n    /// Useful for compressing prices (e.g. using 25 bit mantissa and 7 bit exponent).\n    function sci(uint256 x) internal pure returns (uint256 mantissa, uint256 exponent) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mantissa := x\n            if mantissa {\n                if iszero(mod(mantissa, 1000000000000000000000000000000000)) {\n                    mantissa := div(mantissa, 1000000000000000000000000000000000)\n                    exponent := 33\n                }\n                if iszero(mod(mantissa, 10000000000000000000)) {\n                    mantissa := div(mantissa, 10000000000000000000)\n                    exponent := add(exponent, 19)\n                }\n                if iszero(mod(mantissa, 1000000000000)) {\n                    mantissa := div(mantissa, 1000000000000)\n                    exponent := add(exponent, 12)\n                }\n                if iszero(mod(mantissa, 1000000)) {\n                    mantissa := div(mantissa, 1000000)\n                    exponent := add(exponent, 6)\n                }\n                if iszero(mod(mantissa, 10000)) {\n                    mantissa := div(mantissa, 10000)\n                    exponent := add(exponent, 4)\n                }\n                if iszero(mod(mantissa, 100)) {\n                    mantissa := div(mantissa, 100)\n                    exponent := add(exponent, 2)\n                }\n                if iszero(mod(mantissa, 10)) {\n                    mantissa := div(mantissa, 10)\n                    exponent := add(exponent, 1)\n                }\n            }\n        }\n    }\n\n    /// @dev Convenience function for packing `x` into a smaller number using `sci`.\n    /// The `mantissa` will be in bits [7..255] (the upper 249 bits).\n    /// The `exponent` will be in bits [0..6] (the lower 7 bits).\n    /// Use `SafeCastLib` to safely ensure that the `packed` number is small\n    /// enough to fit in the desired unsigned integer type:\n    /// ```\n    ///     uint32 packed = SafeCastLib.toUint32(FixedPointMathLib.packSci(777 ether));\n    /// ```\n    function packSci(uint256 x) internal pure returns (uint256 packed) {\n        (x, packed) = sci(x); // Reuse for `mantissa` and `exponent`.\n        /// @solidity memory-safe-assembly\n        assembly {\n            if shr(249, x) {\n                mstore(0x00, 0xce30380c) // `MantissaOverflow()`.\n                revert(0x1c, 0x04)\n            }\n            packed := or(shl(7, x), packed)\n        }\n    }\n\n    /// @dev Convenience function for unpacking a packed number from `packSci`.\n    function unpackSci(uint256 packed) internal pure returns (uint256 unpacked) {\n        unchecked {\n            unpacked = (packed >> 7) * 10 ** (packed & 0x7f);\n        }\n    }\n\n    /// @dev Returns the average of `x` and `y`.\n    function avg(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        unchecked {\n            z = (x & y) + ((x ^ y) >> 1);\n        }\n    }\n\n    /// @dev Returns the average of `x` and `y`.\n    function avg(int256 x, int256 y) internal pure returns (int256 z) {\n        unchecked {\n            z = (x >> 1) + (y >> 1) + (((x & 1) + (y & 1)) >> 1);\n        }\n    }\n\n    /// @dev Returns the absolute value of `x`.\n    function abs(int256 x) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := xor(sub(0, shr(255, x)), add(sub(0, shr(255, x)), x))\n        }\n    }\n\n    /// @dev Returns the absolute distance between `x` and `y`.\n    function dist(int256 x, int256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := xor(mul(xor(sub(y, x), sub(x, y)), sgt(x, y)), sub(y, x))\n        }\n    }\n\n    /// @dev Returns the minimum of `x` and `y`.\n    function min(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := xor(x, mul(xor(x, y), lt(y, x)))\n        }\n    }\n\n    /// @dev Returns the minimum of `x` and `y`.\n    function min(int256 x, int256 y) internal pure returns (int256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := xor(x, mul(xor(x, y), slt(y, x)))\n        }\n    }\n\n    /// @dev Returns the maximum of `x` and `y`.\n    function max(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := xor(x, mul(xor(x, y), gt(y, x)))\n        }\n    }\n\n    /// @dev Returns the maximum of `x` and `y`.\n    function max(int256 x, int256 y) internal pure returns (int256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := xor(x, mul(xor(x, y), sgt(y, x)))\n        }\n    }\n\n    /// @dev Returns `x`, bounded to `minValue` and `maxValue`.\n    function clamp(uint256 x, uint256 minValue, uint256 maxValue)\n        internal\n        pure\n        returns (uint256 z)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := xor(x, mul(xor(x, minValue), gt(minValue, x)))\n            z := xor(z, mul(xor(z, maxValue), lt(maxValue, z)))\n        }\n    }\n\n    /// @dev Returns `x`, bounded to `minValue` and `maxValue`.\n    function clamp(int256 x, int256 minValue, int256 maxValue) internal pure returns (int256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := xor(x, mul(xor(x, minValue), sgt(minValue, x)))\n            z := xor(z, mul(xor(z, maxValue), slt(maxValue, z)))\n        }\n    }\n\n    /// @dev Returns greatest common divisor of `x` and `y`.\n    function gcd(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            for { z := x } y {} {\n                let t := y\n                y := mod(z, y)\n                z := t\n            }\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                   RAW NUMBER OPERATIONS                    */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns `x + y`, without checking for overflow.\n    function rawAdd(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        unchecked {\n            z = x + y;\n        }\n    }\n\n    /// @dev Returns `x + y`, without checking for overflow.\n    function rawAdd(int256 x, int256 y) internal pure returns (int256 z) {\n        unchecked {\n            z = x + y;\n        }\n    }\n\n    /// @dev Returns `x - y`, without checking for underflow.\n    function rawSub(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        unchecked {\n            z = x - y;\n        }\n    }\n\n    /// @dev Returns `x - y`, without checking for underflow.\n    function rawSub(int256 x, int256 y) internal pure returns (int256 z) {\n        unchecked {\n            z = x - y;\n        }\n    }\n\n    /// @dev Returns `x * y`, without checking for overflow.\n    function rawMul(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        unchecked {\n            z = x * y;\n        }\n    }\n\n    /// @dev Returns `x * y`, without checking for overflow.\n    function rawMul(int256 x, int256 y) internal pure returns (int256 z) {\n        unchecked {\n            z = x * y;\n        }\n    }\n\n    /// @dev Returns `x / y`, returning 0 if `y` is zero.\n    function rawDiv(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := div(x, y)\n        }\n    }\n\n    /// @dev Returns `x / y`, returning 0 if `y` is zero.\n    function rawSDiv(int256 x, int256 y) internal pure returns (int256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := sdiv(x, y)\n        }\n    }\n\n    /// @dev Returns `x % y`, returning 0 if `y` is zero.\n    function rawMod(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := mod(x, y)\n        }\n    }\n\n    /// @dev Returns `x % y`, returning 0 if `y` is zero.\n    function rawSMod(int256 x, int256 y) internal pure returns (int256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := smod(x, y)\n        }\n    }\n\n    /// @dev Returns `(x + y) % d`, return 0 if `d` if zero.\n    function rawAddMod(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := addmod(x, y, d)\n        }\n    }\n\n    /// @dev Returns `(x * y) % d`, return 0 if `d` if zero.\n    function rawMulMod(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := mulmod(x, y, d)\n        }\n    }\n}\n"
      },
      "src/dispute/interfaces/IDisputeGame.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\nimport { IInitializable } from \"src/dispute/interfaces/IInitializable.sol\";\n\nimport \"src/libraries/DisputeTypes.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 root claim.\n    /// @dev `clones-with-immutable-args` argument #1\n    /// @return rootClaim_ The root claim of the DisputeGame.\n    function rootClaim() external pure returns (Claim rootClaim_);\n\n    /// @notice Getter for the extra data.\n    /// @dev `clones-with-immutable-args` argument #2\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"
      },
      "src/dispute/interfaces/IFaultDisputeGame.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\nimport { IDisputeGame } from \"./IDisputeGame.sol\";\n\nimport \"src/libraries/DisputeTypes.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 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 _parentIndex Index of the `Claim` to attack in the `claimData` array.\n    /// @param _claim The `Claim` at the relative attack position.\n    function attack(uint256 _parentIndex, Claim _claim) external payable;\n\n    /// @notice Defend an agreed upon `Claim`.\n    /// @param _parentIndex Index of the claim to defend in the `claimData` array.\n    /// @param _claim The `Claim` at the relative defense position.\n    function defend(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.\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    function resolveClaim(uint256 _claimIndex) external payable;\n\n    /// @notice A block hash on the L1 that contains the disputed output root.\n    function l1Head() external view returns (Hash l1Head_);\n\n    /// @notice The l2BlockNumber of the disputed output root in the `L2OutputOracle`.\n    function l2BlockNumber() external view returns (uint256 l2BlockNumber_);\n}\n"
      },
      "src/dispute/interfaces/IInitializable.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\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"
      },
      "src/dispute/interfaces/IBigStepper.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\nimport { IPreimageOracle } from \"src/cannon/interfaces/IPreimageOracle.sol\";\n\n/// @title IBigStepper\n/// @notice Describes a state machine that can perform a single instruction step, provided a prestate and an optional\n///         proof.\n/// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n/// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣼⠶⢅⠒⢄⢔⣶⡦⣤⡤⠄⣀⠀⠀⠀⠀⠀⠀⠀\n/// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠨⡏⠀⠀⠈⠢⣙⢯⣄⠀⢨⠯⡺⡘⢄⠀⠀⠀⠀⠀\n/// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣶⡆⠀⠀⠀⠀⠈⠓⠬⡒⠡⣀⢙⡜⡀⠓⠄⠀⠀⠀\n/// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡷⠿⣧⣀⡀⠀⠀⠀⠀⠀⠀⠉⠣⣞⠩⠥⠀⠼⢄⠀⠀\n/// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡇⠀⠀⠀⠉⢹⣶⠒⠒⠂⠈⠉⠁⠘⡆⠀⣿⣿⠫⡄⠀\n/// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⢶⣤⣀⡀⠀⠀⢸⡿⠀⠀⠀⠀⠀⢀⠞⠀⠀⢡⢨⢀⡄⠀\n/// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⡒⣿⢿⡤⠝⡣⠉⠁⠚⠛⠀⠤⠤⣄⡰⠁⠀⠀⠀⠉⠙⢸⠀⠀\n/// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡤⢯⡌⡿⡇⠘⡷⠀⠁⠀⠀⢀⣰⠢⠲⠛⣈⣸⠦⠤⠶⠴⢬⣐⣊⡂⠀\n/// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣤⡪⡗⢫⠞⠀⠆⣀⠻⠤⠴⠐⠚⣉⢀⠦⠂⠋⠁⠀⠁⠀⠀⠀⠀⢋⠉⠇⠀\n/// ⠀⠀⠀⠀⣀⡤⠐⠒⠘⡹⠉⢸⠇⠸⠀⠀⠀⠀⣀⣤⠴⠚⠉⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠼⠀⣾⠀\n/// ⠀⠀⠀⡰⠀⠉⠉⠀⠁⠀⠀⠈⢇⠈⠒⠒⠘⠈⢀⢡⡂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⠀⢸⡄\n/// ⠀⠀⠸⣿⣆⠤⢀⡀⠀⠀⠀⠀⢘⡌⠀⠀⣀⣀⣀⡈⣤⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⢸⡇\n/// ⠀⠀⢸⣀⠀⠉⠒⠐⠛⠋⠭⠭⠍⠉⠛⠒⠒⠒⠀⠒⠚⠛⠛⠛⠩⠭⠭⠭⠭⠤⠤⠤⠤⠤⠭⠭⠉⠓⡆\n/// ⠀⠀⠘⠿⣷⣶⣤⣤⣀⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣤⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇\n/// ⠀⠀⠀⠀⠀⠉⠙⠛⠛⠻⠿⢿⣿⣿⣷⣶⣶⣶⣤⣤⣀⣁⣛⣃⣒⠿⠿⠿⠤⠠⠄⠤⠤⢤⣛⣓⣂⣻⡇\n/// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠉⠉⠙⠛⠻⠿⠿⠿⢿⣿⣿⣿⣷⣶⣶⣾⣿⣿⣿⣿⠿⠟⠁\n/// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠈⠉⠉⠉⠉⠁⠀⠀⠀⠀⠀\ninterface IBigStepper {\n    /// @notice Performs the state transition from a given prestate and returns the hash of the post state witness.\n    /// @param _stateData The raw opaque prestate data.\n    /// @param _proof Opaque proof data, can be used to prove things about the prestate in relation to the state of the\n    ///               interface's implementation.\n    /// @param _localContext The local key context for the preimage oracle. Optional, can be set as a constant if the\n    ///                      implementation only requires one set of local keys.\n    /// @return postState_ The hash of the post state witness after the state transition.\n    function step(\n        bytes calldata _stateData,\n        bytes calldata _proof,\n        bytes32 _localContext\n    )\n        external\n        returns (bytes32 postState_);\n\n    /// @notice Returns the preimage oracle used by the state machine.\n    function oracle() external view returns (IPreimageOracle oracle_);\n}\n"
      },
      "src/libraries/Clone.sol": {
        "content": "// SPDX-License-Identifier: BSD\npragma solidity ^0.8.15;\n\n/// @title Clone\n/// @author zefram.eth, Saw-mon & Natalie, clabby\n/// @notice Provides helper functions for reading immutable args from calldata\n/// @dev Original:\n///      https://github.com/Saw-mon-and-Natalie/clones-with-immutable-args/\n///      blob/105efee1b9127ed7f6fedf139e1fc796ce8791f2/src/Clone.sol\n/// @dev MODIFICATIONS:\n///      - Added `_getArgDynBytes` function.\ncontract Clone {\n    uint256 private constant ONE_WORD = 0x20;\n\n    /// @notice Reads an immutable arg with type address\n    /// @param argOffset The offset of the arg in the packed data\n    /// @return arg The arg value\n    function _getArgAddress(uint256 argOffset) internal pure returns (address arg) {\n        uint256 offset = _getImmutableArgsOffset();\n        assembly {\n            arg := shr(0x60, calldataload(add(offset, argOffset)))\n        }\n    }\n\n    /// @notice Reads an immutable arg with type uint256\n    /// @param argOffset The offset of the arg in the packed data\n    /// @return arg The arg value\n    function _getArgUint256(uint256 argOffset) internal pure returns (uint256 arg) {\n        uint256 offset = _getImmutableArgsOffset();\n        assembly {\n            arg := calldataload(add(offset, argOffset))\n        }\n    }\n\n    /// @notice Reads an immutable arg with type bytes32\n    /// @param argOffset The offset of the arg in the packed data\n    /// @return arg The arg value\n    function _getArgFixedBytes(uint256 argOffset) internal pure returns (bytes32 arg) {\n        uint256 offset = _getImmutableArgsOffset();\n        assembly {\n            arg := calldataload(add(offset, argOffset))\n        }\n    }\n\n    /// @notice Reads a uint256 array stored in the immutable args.\n    /// @param argOffset The offset of the arg in the packed data\n    /// @param arrLen Number of elements in the array\n    /// @return arr The array\n    function _getArgUint256Array(uint256 argOffset, uint64 arrLen) internal pure returns (uint256[] memory arr) {\n        uint256 offset = _getImmutableArgsOffset() + argOffset;\n        arr = new uint256[](arrLen);\n\n        assembly {\n            calldatacopy(add(arr, ONE_WORD), offset, shl(5, arrLen))\n        }\n    }\n\n    /// @notice Reads a dynamic bytes array stored in the immutable args.\n    /// @param argOffset The offset of the arg in the packed data\n    /// @param arrLen Number of elements in the array\n    /// @return arr The array\n    function _getArgDynBytes(uint256 argOffset, uint64 arrLen) internal pure returns (bytes memory arr) {\n        uint256 offset = _getImmutableArgsOffset() + argOffset;\n        arr = new bytes(arrLen);\n\n        assembly {\n            calldatacopy(add(arr, ONE_WORD), offset, arrLen)\n        }\n    }\n\n    /// @notice Reads an immutable arg with type uint64\n    /// @param argOffset The offset of the arg in the packed data\n    /// @return arg The arg value\n    function _getArgUint64(uint256 argOffset) internal pure returns (uint64 arg) {\n        uint256 offset = _getImmutableArgsOffset();\n        assembly {\n            arg := shr(0xc0, calldataload(add(offset, argOffset)))\n        }\n    }\n\n    /// @notice Reads an immutable arg with type uint8\n    /// @param argOffset The offset of the arg in the packed data\n    /// @return arg The arg value\n    function _getArgUint8(uint256 argOffset) internal pure returns (uint8 arg) {\n        uint256 offset = _getImmutableArgsOffset();\n        assembly {\n            arg := shr(0xf8, calldataload(add(offset, argOffset)))\n        }\n    }\n\n    /// @return offset The offset of the packed immutable args in calldata\n    function _getImmutableArgsOffset() internal pure returns (uint256 offset) {\n        assembly {\n            offset := sub(calldatasize(), shr(0xf0, calldataload(sub(calldatasize(), 2))))\n        }\n    }\n}\n"
      },
      "src/libraries/Types.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @title Types\n/// @notice Contains various types used throughout the Optimism contract system.\nlibrary Types {\n    /// @notice OutputProposal represents a commitment to the L2 state. The timestamp is the L1\n    ///         timestamp that the output root is posted. This timestamp is used to verify that the\n    ///         finalization period has passed since the output root was submitted.\n    /// @custom:field outputRoot    Hash of the L2 output.\n    /// @custom:field timestamp     Timestamp of the L1 block that the output root was submitted in.\n    /// @custom:field l2BlockNumber L2 block number that the output corresponds to.\n    struct OutputProposal {\n        bytes32 outputRoot;\n        uint128 timestamp;\n        uint128 l2BlockNumber;\n    }\n\n    /// @notice Struct representing the elements that are hashed together to generate an output root\n    ///         which itself represents a snapshot of the L2 state.\n    /// @custom:field version                  Version of the output root.\n    /// @custom:field stateRoot                Root of the state trie at the block of this output.\n    /// @custom:field messagePasserStorageRoot Root of the message passer storage trie.\n    /// @custom:field latestBlockhash          Hash of the block this output was generated from.\n    struct OutputRootProof {\n        bytes32 version;\n        bytes32 stateRoot;\n        bytes32 messagePasserStorageRoot;\n        bytes32 latestBlockhash;\n    }\n\n    /// @notice Struct representing a deposit transaction (L1 => L2 transaction) created by an end\n    ///         user (as opposed to a system deposit transaction generated by the system).\n    /// @custom:field from        Address of the sender of the transaction.\n    /// @custom:field to          Address of the recipient of the transaction.\n    /// @custom:field isCreation  True if the transaction is a contract creation.\n    /// @custom:field value       Value to send to the recipient.\n    /// @custom:field mint        Amount of ETH to mint.\n    /// @custom:field gasLimit    Gas limit of the transaction.\n    /// @custom:field data        Data of the transaction.\n    /// @custom:field l1BlockHash Hash of the block the transaction was submitted in.\n    /// @custom:field logIndex    Index of the log in the block the transaction was submitted in.\n    struct UserDepositTransaction {\n        address from;\n        address to;\n        bool isCreation;\n        uint256 value;\n        uint256 mint;\n        uint64 gasLimit;\n        bytes data;\n        bytes32 l1BlockHash;\n        uint256 logIndex;\n    }\n\n    /// @notice Struct representing a withdrawal transaction.\n    /// @custom:field nonce    Nonce of the withdrawal transaction\n    /// @custom:field sender   Address of the sender of the transaction.\n    /// @custom:field target   Address of the recipient of the transaction.\n    /// @custom:field value    Value to send to the recipient.\n    /// @custom:field gasLimit Gas limit of the transaction.\n    /// @custom:field data     Data of the transaction.\n    struct WithdrawalTransaction {\n        uint256 nonce;\n        address sender;\n        address target;\n        uint256 value;\n        uint256 gasLimit;\n        bytes data;\n    }\n}\n"
      },
      "src/universal/ISemver.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @title ISemver\n/// @notice ISemver is a simple contract for ensuring that contracts are\n///         versioned using semantic versioning.\ninterface ISemver {\n    /// @notice Getter for the semantic version of the contract. This is not\n    ///         meant to be used onchain but instead meant to be used by offchain\n    ///         tooling.\n    /// @return Semver contract version as a string.\n    function version() external view returns (string memory);\n}\n"
      },
      "src/dispute/lib/LibUDT.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\nimport \"src/libraries/DisputeTypes.sol\";\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/// @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\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/// @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/// @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/// @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/// @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 uint8.\n    /// @param _gametype The `GameType` type to get the value of.\n    /// @return gametype_ The value of the `GameType` type as a uint8 type.\n    function raw(GameType _gametype) internal pure returns (uint8 gametype_) {\n        assembly {\n            gametype_ := _gametype\n        }\n    }\n}\n"
      },
      "src/dispute/lib/LibHashing.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\nimport \"src/libraries/DisputeTypes.sol\";\n\n/// @title Hashing\n/// @notice This library contains all of the hashing utilities used in the Cannon contracts.\nlibrary LibHashing {\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 (ClaimHash 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"
      },
      "src/dispute/lib/LibPosition.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\nimport \"src/libraries/DisputeTypes.sol\";\nimport \"src/libraries/DisputeErrors.sol\";\n\n/// @title LibPosition\n/// @notice This library contains helper functions for working with the `Position` type.\nlibrary LibPosition {\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(uint64 _depth, uint64 _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 (uint64 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 (uint64 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) revert ClaimAboveSplit();\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"
      },
      "src/dispute/lib/LibGameId.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\nimport \"src/libraries/DisputeTypes.sol\";\nimport \"src/dispute/interfaces/IDisputeGame.sol\";\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        IDisputeGame _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_, IDisputeGame 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"
      },
      "src/cannon/interfaces/IPreimageOracle.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/// @title IPreimageOracle\n/// @notice Interface for a preimage oracle.\ninterface IPreimageOracle {\n    /// @notice Reads a preimage from the oracle.\n    /// @param _key The key of the preimage to read.\n    /// @param _offset The offset of the preimage to read.\n    /// @return dat_ The preimage data.\n    /// @return datLen_ The length of the preimage data.\n    function readPreimage(bytes32 _key, uint256 _offset) external view returns (bytes32 dat_, uint256 datLen_);\n\n    /// @notice Loads of local data part into the preimage oracle.\n    /// @param _ident The identifier of the local data.\n    /// @param _localContext The local key context for the preimage oracle. Optionally, can be set as a constant\n    ///                      if the caller only requires one set of local keys.\n    /// @param _word The local data word.\n    /// @param _size The number of bytes in `_word` to load.\n    /// @param _partOffset The offset of the local data part to write to the oracle.\n    /// @dev The local data parts are loaded into the preimage oracle under the context\n    ///      of the caller - no other account can write to the caller's context\n    ///      specific data.\n    ///\n    ///      There are 5 local data identifiers:\n    ///      ┌────────────┬────────────────────────┐\n    ///      │ Identifier │      Data              │\n    ///      ├────────────┼────────────────────────┤\n    ///      │          1 │ L1 Head Hash (bytes32) │\n    ///      │          2 │ Output Root (bytes32)  │\n    ///      │          3 │ Root Claim (bytes32)   │\n    ///      │          4 │ L2 Block Number (u64)  │\n    ///      │          5 │ Chain ID (u64)         │\n    ///      └────────────┴────────────────────────┘\n    function loadLocalData(\n        uint256 _ident,\n        bytes32 _localContext,\n        bytes32 _word,\n        uint256 _size,\n        uint256 _partOffset\n    )\n        external\n        returns (bytes32 key_);\n\n    /// @notice Prepares a preimage to be read by keccak256 key, starting at the given offset and up to 32 bytes\n    ///         (clipped at preimage length, if out of data).\n    /// @param _partOffset The offset of the preimage to read.\n    /// @param _preimage The preimage data.\n    function loadKeccak256PreimagePart(uint256 _partOffset, bytes calldata _preimage) external;\n\n    /// @notice Prepares a preimage to be read by sha256 key, starting at the given offset and up to 32 bytes\n    ///         (clipped at preimage length, if out of data).\n    /// @param _partOffset The offset of the preimage to read.\n    /// @param _preimage The preimage data.\n    function loadSha256PreimagePart(uint256 _partOffset, bytes calldata _preimage) external;\n\n    /// @notice Verifies that `p(_z) = _y` given `_commitment` that corresponds to the polynomial `p(x)` and a KZG\n    //          proof. The value `y` is the pre-image, and the preimage key is `5 ++ keccak256(_commitment ++ z)[1:]`.\n    /// @param _z Big endian point value. Part of the preimage key.\n    /// @param _y Big endian point value. The preimage for the key.\n    /// @param _commitment The commitment to the polynomial. 48 bytes, part of the preimage key.\n    /// @param _proof The KZG proof, part of the preimage key.\n    /// @param _partOffset The offset of the preimage to store.\n    function loadBlobPreimagePart(\n        uint256 _z,\n        uint256 _y,\n        bytes calldata _commitment,\n        bytes calldata _proof,\n        uint256 _partOffset\n    )\n        external;\n\n    /// @notice Prepares a precompile result to be read by a precompile key for the specified offset.\n    ///         The precompile result data is a concatenation of the precompile call status byte and its return data.\n    ///         The preimage key is `6 ++ keccak256(precompile ++ input)[1:]`.\n    /// @param _partOffset The offset of the precompile result being loaded.\n    /// @param _precompile The precompile address\n    /// @param _input The input to the precompile call.\n    function loadPrecompilePreimagePart(uint256 _partOffset, address _precompile, bytes calldata _input) external;\n}\n"
      }
    },
    "settings": {
      "remappings": [
        "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
        "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
        "@rari-capital/solmate/=lib/solmate/",
        "@cwia/=lib/clones-with-immutable-args/src/",
        "@lib-keccak/=lib/lib-keccak/contracts/lib/",
        "forge-std/=lib/forge-std/src/",
        "ds-test/=lib/forge-std/lib/ds-test/src/",
        "safe-contracts/=lib/safe-contracts/contracts/",
        "kontrol-cheatcodes/=lib/kontrol-cheatcodes/src/",
        "solady/=lib/solady/src/",
        "@solady-test/=lib/lib-keccak/lib/solady/test/",
        "@solady/=lib/lib-keccak/lib/solady/src/",
        "clones-with-immutable-args/=lib/clones-with-immutable-args/src/",
        "lib-keccak/=lib/lib-keccak/contracts/",
        "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
        "openzeppelin-contracts/=lib/openzeppelin-contracts/",
        "solmate/=lib/solmate/src/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 999999
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "none"
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "evmVersion": "london",
      "viaIR": false,
      "libraries": {}
    }
  }}