creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "src/bridge/IBridge.sol": {
        "content": "// Copyright 2021-2022, Offchain Labs, Inc.\n// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE\n// SPDX-License-Identifier: BUSL-1.1\n\n// solhint-disable-next-line compiler-version\npragma solidity >=0.6.9 <0.9.0;\n\nimport \"./IOwnable.sol\";\n\ninterface IBridge {\n    /// @dev This is an instruction to offchain readers to inform them where to look\n    ///      for sequencer inbox batch data. This is not the type of data (eg. das, brotli encoded, or blob versioned hash)\n    ///      and this enum is not used in the state transition function, rather it informs an offchain\n    ///      reader where to find the data so that they can supply it to the replay binary\n    enum BatchDataLocation {\n        /// @notice The data can be found in the transaction call data\n        TxInput,\n        /// @notice The data can be found in an event emitted during the transaction\n        SeparateBatchEvent,\n        /// @notice This batch contains no data\n        NoData,\n        /// @notice The data can be found in the 4844 data blobs on this transaction\n        Blob\n    }\n\n    struct TimeBounds {\n        uint64 minTimestamp;\n        uint64 maxTimestamp;\n        uint64 minBlockNumber;\n        uint64 maxBlockNumber;\n    }\n\n    event MessageDelivered(\n        uint256 indexed messageIndex,\n        bytes32 indexed beforeInboxAcc,\n        address inbox,\n        uint8 kind,\n        address sender,\n        bytes32 messageDataHash,\n        uint256 baseFeeL1,\n        uint64 timestamp\n    );\n\n    event BridgeCallTriggered(\n        address indexed outbox,\n        address indexed to,\n        uint256 value,\n        bytes data\n    );\n\n    event InboxToggle(address indexed inbox, bool enabled);\n\n    event OutboxToggle(address indexed outbox, bool enabled);\n\n    event SequencerInboxUpdated(address newSequencerInbox);\n\n    event RollupUpdated(address rollup);\n\n    function allowedDelayedInboxList(uint256) external returns (address);\n\n    function allowedOutboxList(uint256) external returns (address);\n\n    /// @dev Accumulator for delayed inbox messages; tail represents hash of the current state; each element represents the inclusion of a new message.\n    function delayedInboxAccs(uint256) external view returns (bytes32);\n\n    /// @dev Accumulator for sequencer inbox messages; tail represents hash of the current state; each element represents the inclusion of a new message.\n    function sequencerInboxAccs(uint256) external view returns (bytes32);\n\n    function rollup() external view returns (IOwnable);\n\n    function sequencerInbox() external view returns (address);\n\n    function activeOutbox() external view returns (address);\n\n    function allowedDelayedInboxes(address inbox) external view returns (bool);\n\n    function allowedOutboxes(address outbox) external view returns (bool);\n\n    function sequencerReportedSubMessageCount() external view returns (uint256);\n\n    function executeCall(\n        address to,\n        uint256 value,\n        bytes calldata data\n    ) external returns (bool success, bytes memory returnData);\n\n    function delayedMessageCount() external view returns (uint256);\n\n    function sequencerMessageCount() external view returns (uint256);\n\n    // ---------- onlySequencerInbox functions ----------\n\n    function enqueueSequencerMessage(\n        bytes32 dataHash,\n        uint256 afterDelayedMessagesRead,\n        uint256 prevMessageCount,\n        uint256 newMessageCount\n    )\n        external\n        returns (\n            uint256 seqMessageIndex,\n            bytes32 beforeAcc,\n            bytes32 delayedAcc,\n            bytes32 acc\n        );\n\n    /**\n     * @dev Allows the sequencer inbox to submit a delayed message of the batchPostingReport type\n     *      This is done through a separate function entrypoint instead of allowing the sequencer inbox\n     *      to call `enqueueDelayedMessage` to avoid the gas overhead of an extra SLOAD in either\n     *      every delayed inbox or every sequencer inbox call.\n     */\n    function submitBatchSpendingReport(address batchPoster, bytes32 dataHash)\n        external\n        returns (uint256 msgNum);\n\n    // ---------- onlyRollupOrOwner functions ----------\n\n    function setSequencerInbox(address _sequencerInbox) external;\n\n    function setDelayedInbox(address inbox, bool enabled) external;\n\n    function setOutbox(address inbox, bool enabled) external;\n\n    function updateRollupAddress(IOwnable _rollup) external;\n}\n"
      },
      "src/bridge/IDelayedMessageProvider.sol": {
        "content": "// Copyright 2021-2022, Offchain Labs, Inc.\n// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE\n// SPDX-License-Identifier: BUSL-1.1\n\n// solhint-disable-next-line compiler-version\npragma solidity >=0.6.9 <0.9.0;\n\ninterface IDelayedMessageProvider {\n    /// @dev event emitted when a inbox message is added to the Bridge's delayed accumulator\n    event InboxMessageDelivered(uint256 indexed messageNum, bytes data);\n\n    /// @dev event emitted when a inbox message is added to the Bridge's delayed accumulator\n    /// same as InboxMessageDelivered but the batch data is available in tx.input\n    event InboxMessageDeliveredFromOrigin(uint256 indexed messageNum);\n}\n"
      },
      "src/bridge/IOwnable.sol": {
        "content": "// Copyright 2021-2022, Offchain Labs, Inc.\n// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE\n// SPDX-License-Identifier: BUSL-1.1\n\n// solhint-disable-next-line compiler-version\npragma solidity >=0.4.21 <0.9.0;\n\ninterface IOwnable {\n    function owner() external view returns (address);\n}\n"
      },
      "src/bridge/ISequencerInbox.sol": {
        "content": "// Copyright 2021-2022, Offchain Labs, Inc.\n// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE\n// SPDX-License-Identifier: BUSL-1.1\n\n// solhint-disable-next-line compiler-version\npragma solidity >=0.6.9 <0.9.0;\npragma experimental ABIEncoderV2;\n\nimport \"../libraries/IGasRefunder.sol\";\nimport \"./IDelayedMessageProvider.sol\";\nimport \"./IBridge.sol\";\n\ninterface ISequencerInbox is IDelayedMessageProvider {\n    struct MaxTimeVariation {\n        uint256 delayBlocks;\n        uint256 futureBlocks;\n        uint256 delaySeconds;\n        uint256 futureSeconds;\n    }\n\n    event SequencerBatchDelivered(\n        uint256 indexed batchSequenceNumber,\n        bytes32 indexed beforeAcc,\n        bytes32 indexed afterAcc,\n        bytes32 delayedAcc,\n        uint256 afterDelayedMessagesRead,\n        IBridge.TimeBounds timeBounds,\n        IBridge.BatchDataLocation dataLocation\n    );\n\n    event OwnerFunctionCalled(uint256 indexed id);\n\n    /// @dev a separate event that emits batch data when this isn't easily accessible in the tx.input\n    event SequencerBatchData(uint256 indexed batchSequenceNumber, bytes data);\n\n    /// @dev a valid keyset was added\n    event SetValidKeyset(bytes32 indexed keysetHash, bytes keysetBytes);\n\n    /// @dev a keyset was invalidated\n    event InvalidateKeyset(bytes32 indexed keysetHash);\n\n    function totalDelayedMessagesRead() external view returns (uint256);\n\n    function bridge() external view returns (IBridge);\n\n    /// @dev The size of the batch header\n    // solhint-disable-next-line func-name-mixedcase\n    function HEADER_LENGTH() external view returns (uint256);\n\n    /// @dev If the first batch data byte after the header has this bit set,\n    ///      the sequencer inbox has authenticated the data. Currently only used for 4844 blob support.\n    ///      See: https://github.com/OffchainLabs/nitro/blob/69de0603abf6f900a4128cab7933df60cad54ded/arbstate/das_reader.go\n    // solhint-disable-next-line func-name-mixedcase\n    function DATA_AUTHENTICATED_FLAG() external view returns (bytes1);\n\n    /// @dev If the first data byte after the header has this bit set,\n    ///      then the batch data is to be found in 4844 data blobs\n    ///      See: https://github.com/OffchainLabs/nitro/blob/69de0603abf6f900a4128cab7933df60cad54ded/arbstate/das_reader.go\n    // solhint-disable-next-line func-name-mixedcase\n    function DATA_BLOB_HEADER_FLAG() external view returns (bytes1);\n\n    /// @dev If the first data byte after the header has this bit set,\n    ///      then the batch data is a das message\n    ///      See: https://github.com/OffchainLabs/nitro/blob/69de0603abf6f900a4128cab7933df60cad54ded/arbstate/das_reader.go\n    // solhint-disable-next-line func-name-mixedcase\n    function DAS_MESSAGE_HEADER_FLAG() external view returns (bytes1);\n\n    /// @dev If the first data byte after the header has this bit set,\n    ///      then the batch data is a das message that employs a merklesization strategy\n    ///      See: https://github.com/OffchainLabs/nitro/blob/69de0603abf6f900a4128cab7933df60cad54ded/arbstate/das_reader.go\n    // solhint-disable-next-line func-name-mixedcase\n    function TREE_DAS_MESSAGE_HEADER_FLAG() external view returns (bytes1);\n\n    /// @dev If the first data byte after the header has this bit set,\n    ///      then the batch data has been brotli compressed\n    ///      See: https://github.com/OffchainLabs/nitro/blob/69de0603abf6f900a4128cab7933df60cad54ded/arbstate/das_reader.go\n    // solhint-disable-next-line func-name-mixedcase\n    function BROTLI_MESSAGE_HEADER_FLAG() external view returns (bytes1);\n\n    /// @dev If the first data byte after the header has this bit set,\n    ///      then the batch data uses a zero heavy encoding\n    ///      See: https://github.com/OffchainLabs/nitro/blob/69de0603abf6f900a4128cab7933df60cad54ded/arbstate/das_reader.go\n    // solhint-disable-next-line func-name-mixedcase\n    function ZERO_HEAVY_MESSAGE_HEADER_FLAG() external view returns (bytes1);\n\n    function rollup() external view returns (IOwnable);\n\n    function isBatchPoster(address) external view returns (bool);\n\n    function isSequencer(address) external view returns (bool);\n\n    function maxDataSize() external view returns (uint256);\n\n    /// @notice The batch poster manager has the ability to change the batch poster addresses\n    ///         This enables the batch poster to do key rotation\n    function batchPosterManager() external view returns (address);\n\n    struct DasKeySetInfo {\n        bool isValidKeyset;\n        uint64 creationBlock;\n    }\n\n    /// @dev returns 4 uint256 to be compatible with older version\n    function maxTimeVariation()\n        external\n        view\n        returns (\n            uint256 delayBlocks,\n            uint256 futureBlocks,\n            uint256 delaySeconds,\n            uint256 futureSeconds\n        );\n\n    function dasKeySetInfo(bytes32) external view returns (bool, uint64);\n\n    /// @notice Remove force inclusion delay after a L1 chainId fork\n    function removeDelayAfterFork() external;\n\n    /// @notice Force messages from the delayed inbox to be included in the chain\n    ///         Callable by any address, but message can only be force-included after maxTimeVariation.delayBlocks and\n    ///         maxTimeVariation.delaySeconds has elapsed. As part of normal behaviour the sequencer will include these\n    ///         messages so it's only necessary to call this if the sequencer is down, or not including any delayed messages.\n    /// @param _totalDelayedMessagesRead The total number of messages to read up to\n    /// @param kind The kind of the last message to be included\n    /// @param l1BlockAndTime The l1 block and the l1 timestamp of the last message to be included\n    /// @param baseFeeL1 The l1 gas price of the last message to be included\n    /// @param sender The sender of the last message to be included\n    /// @param messageDataHash The messageDataHash of the last message to be included\n    function forceInclusion(\n        uint256 _totalDelayedMessagesRead,\n        uint8 kind,\n        uint64[2] calldata l1BlockAndTime,\n        uint256 baseFeeL1,\n        address sender,\n        bytes32 messageDataHash\n    ) external;\n\n    function inboxAccs(uint256 index) external view returns (bytes32);\n\n    function batchCount() external view returns (uint256);\n\n    function isValidKeysetHash(bytes32 ksHash) external view returns (bool);\n\n    /// @notice the creation block is intended to still be available after a keyset is deleted\n    function getKeysetCreationBlock(bytes32 ksHash) external view returns (uint256);\n\n    // ---------- BatchPoster functions ----------\n\n    function addSequencerL2BatchFromOrigin(\n        uint256 sequenceNumber,\n        bytes calldata data,\n        uint256 afterDelayedMessagesRead,\n        IGasRefunder gasRefunder\n    ) external;\n\n    function addSequencerL2BatchFromOrigin(\n        uint256 sequenceNumber,\n        bytes calldata data,\n        uint256 afterDelayedMessagesRead,\n        IGasRefunder gasRefunder,\n        uint256 prevMessageCount,\n        uint256 newMessageCount\n    ) external;\n\n    function addSequencerL2Batch(\n        uint256 sequenceNumber,\n        bytes calldata data,\n        uint256 afterDelayedMessagesRead,\n        IGasRefunder gasRefunder,\n        uint256 prevMessageCount,\n        uint256 newMessageCount\n    ) external;\n\n    function addSequencerL2BatchFromBlobs(\n        uint256 sequenceNumber,\n        uint256 afterDelayedMessagesRead,\n        IGasRefunder gasRefunder,\n        uint256 prevMessageCount,\n        uint256 newMessageCount\n    ) external;\n\n    // ---------- onlyRollupOrOwner functions ----------\n\n    /**\n     * @notice Set max delay for sequencer inbox\n     * @param maxTimeVariation_ the maximum time variation parameters\n     */\n    function setMaxTimeVariation(MaxTimeVariation memory maxTimeVariation_) external;\n\n    /**\n     * @notice Updates whether an address is authorized to be a batch poster at the sequencer inbox\n     * @param addr the address\n     * @param isBatchPoster_ if the specified address should be authorized as a batch poster\n     */\n    function setIsBatchPoster(address addr, bool isBatchPoster_) external;\n\n    /**\n     * @notice Makes Data Availability Service keyset valid\n     * @param keysetBytes bytes of the serialized keyset\n     */\n    function setValidKeyset(bytes calldata keysetBytes) external;\n\n    /**\n     * @notice Invalidates a Data Availability Service keyset\n     * @param ksHash hash of the keyset\n     */\n    function invalidateKeysetHash(bytes32 ksHash) external;\n\n    /**\n     * @notice Updates whether an address is authorized to be a sequencer.\n     * @dev The IsSequencer information is used only off-chain by the nitro node to validate sequencer feed signer.\n     * @param addr the address\n     * @param isSequencer_ if the specified address should be authorized as a sequencer\n     */\n    function setIsSequencer(address addr, bool isSequencer_) external;\n\n    /**\n     * @notice Updates the batch poster manager, the address which has the ability to rotate batch poster keys\n     * @param newBatchPosterManager The new batch poster manager to be set\n     */\n    function setBatchPosterManager(address newBatchPosterManager) external;\n\n    /// @notice Allows the rollup owner to sync the rollup address\n    function updateRollupAddress() external;\n\n    // ---------- initializer ----------\n\n    function initialize(IBridge bridge_, MaxTimeVariation calldata maxTimeVariation_) external;\n}\n"
      },
      "src/libraries/IGasRefunder.sol": {
        "content": "// Copyright 2021-2022, Offchain Labs, Inc.\n// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE\n// SPDX-License-Identifier: BUSL-1.1\n\n// solhint-disable-next-line compiler-version\npragma solidity >=0.6.9 <0.9.0;\n\ninterface IGasRefunder {\n    function onGasSpent(\n        address payable spender,\n        uint256 gasUsed,\n        uint256 calldataSize\n    ) external returns (bool success);\n}\n"
      },
      "src/osp/IOneStepProver.sol": {
        "content": "// Copyright 2021-2022, Offchain Labs, Inc.\n// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE\n// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.0;\n\nimport \"../state/Machine.sol\";\nimport \"../state/Module.sol\";\nimport \"../state/Instructions.sol\";\nimport \"../state/GlobalState.sol\";\nimport \"../bridge/ISequencerInbox.sol\";\nimport \"../bridge/IBridge.sol\";\n\nstruct ExecutionContext {\n    uint256 maxInboxMessagesRead;\n    IBridge bridge;\n}\n\nabstract contract IOneStepProver {\n    function executeOneStep(\n        ExecutionContext memory execCtx,\n        Machine calldata mach,\n        Module calldata mod,\n        Instruction calldata instruction,\n        bytes calldata proof\n    ) external view virtual returns (Machine memory result, Module memory resultMod);\n}\n"
      },
      "src/osp/OneStepProverMemory.sol": {
        "content": "// Copyright 2021-2022, Offchain Labs, Inc.\n// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE\n// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.0;\n\nimport \"../state/Value.sol\";\nimport \"../state/Machine.sol\";\nimport \"../state/Deserialize.sol\";\nimport \"../state/ModuleMemory.sol\";\nimport \"./IOneStepProver.sol\";\n\ncontract OneStepProverMemory is IOneStepProver {\n    using MerkleProofLib for MerkleProof;\n    using ModuleMemoryLib for ModuleMemory;\n    using ValueLib for Value;\n    using ValueStackLib for ValueStack;\n\n    uint256 private constant LEAF_SIZE = 32;\n    uint64 private constant PAGE_SIZE = 65536;\n\n    function setLeafByte(\n        bytes32 oldLeaf,\n        uint256 idx,\n        uint8 val\n    ) internal pure returns (bytes32) {\n        require(idx < LEAF_SIZE, \"BAD_SET_LEAF_BYTE_IDX\");\n        // Take into account that we are casting the leaf to a big-endian integer\n        uint256 leafShift = (LEAF_SIZE - 1 - idx) * 8;\n        uint256 newLeaf = uint256(oldLeaf);\n        newLeaf &= ~(0xFF << leafShift);\n        newLeaf |= uint256(val) << leafShift;\n        return bytes32(newLeaf);\n    }\n\n    function executeMemoryLoad(\n        Machine memory mach,\n        Module memory mod,\n        Instruction calldata inst,\n        bytes calldata proof\n    ) internal pure {\n        ValueType ty;\n        uint256 readBytes;\n        bool signed;\n        if (inst.opcode == Instructions.I32_LOAD) {\n            ty = ValueType.I32;\n            readBytes = 4;\n            signed = false;\n        } else if (inst.opcode == Instructions.I64_LOAD) {\n            ty = ValueType.I64;\n            readBytes = 8;\n            signed = false;\n        } else if (inst.opcode == Instructions.F32_LOAD) {\n            ty = ValueType.F32;\n            readBytes = 4;\n            signed = false;\n        } else if (inst.opcode == Instructions.F64_LOAD) {\n            ty = ValueType.F64;\n            readBytes = 8;\n            signed = false;\n        } else if (inst.opcode == Instructions.I32_LOAD8_S) {\n            ty = ValueType.I32;\n            readBytes = 1;\n            signed = true;\n        } else if (inst.opcode == Instructions.I32_LOAD8_U) {\n            ty = ValueType.I32;\n            readBytes = 1;\n            signed = false;\n        } else if (inst.opcode == Instructions.I32_LOAD16_S) {\n            ty = ValueType.I32;\n            readBytes = 2;\n            signed = true;\n        } else if (inst.opcode == Instructions.I32_LOAD16_U) {\n            ty = ValueType.I32;\n            readBytes = 2;\n            signed = false;\n        } else if (inst.opcode == Instructions.I64_LOAD8_S) {\n            ty = ValueType.I64;\n            readBytes = 1;\n            signed = true;\n        } else if (inst.opcode == Instructions.I64_LOAD8_U) {\n            ty = ValueType.I64;\n            readBytes = 1;\n            signed = false;\n        } else if (inst.opcode == Instructions.I64_LOAD16_S) {\n            ty = ValueType.I64;\n            readBytes = 2;\n            signed = true;\n        } else if (inst.opcode == Instructions.I64_LOAD16_U) {\n            ty = ValueType.I64;\n            readBytes = 2;\n            signed = false;\n        } else if (inst.opcode == Instructions.I64_LOAD32_S) {\n            ty = ValueType.I64;\n            readBytes = 4;\n            signed = true;\n        } else if (inst.opcode == Instructions.I64_LOAD32_U) {\n            ty = ValueType.I64;\n            readBytes = 4;\n            signed = false;\n        } else {\n            revert(\"INVALID_MEMORY_LOAD_OPCODE\");\n        }\n\n        uint256 index = inst.argumentData + mach.valueStack.pop().assumeI32();\n        (bool err, uint256 value, ) = mod.moduleMemory.load(index, readBytes, proof, 0);\n        if (err) {\n            mach.status = MachineStatus.ERRORED;\n            return;\n        }\n        uint64 readValue = uint64(value);\n\n        if (signed) {\n            // Go down to the original uint size, change to signed, go up to correct size, convert back to unsigned\n            if (readBytes == 1 && ty == ValueType.I32) {\n                readValue = uint32(int32(int8(uint8(readValue))));\n            } else if (readBytes == 1 && ty == ValueType.I64) {\n                readValue = uint64(int64(int8(uint8(readValue))));\n            } else if (readBytes == 2 && ty == ValueType.I32) {\n                readValue = uint32(int32(int16(uint16(readValue))));\n            } else if (readBytes == 2 && ty == ValueType.I64) {\n                readValue = uint64(int64(int16(uint16(readValue))));\n            } else if (readBytes == 4 && ty == ValueType.I64) {\n                readValue = uint64(int64(int32(uint32(readValue))));\n            } else {\n                revert(\"BAD_READ_BYTES_SIGNED\");\n            }\n        }\n\n        mach.valueStack.push(Value({valueType: ty, contents: readValue}));\n    }\n\n    function executeMemoryStore(\n        Machine memory mach,\n        Module memory mod,\n        Instruction calldata inst,\n        bytes calldata proof\n    ) internal pure {\n        uint64 writeBytes;\n        uint64 toWrite;\n        {\n            ValueType ty;\n            if (inst.opcode == Instructions.I32_STORE) {\n                ty = ValueType.I32;\n                writeBytes = 4;\n            } else if (inst.opcode == Instructions.I64_STORE) {\n                ty = ValueType.I64;\n                writeBytes = 8;\n            } else if (inst.opcode == Instructions.F32_STORE) {\n                ty = ValueType.F32;\n                writeBytes = 4;\n            } else if (inst.opcode == Instructions.F64_STORE) {\n                ty = ValueType.F64;\n                writeBytes = 8;\n            } else if (inst.opcode == Instructions.I32_STORE8) {\n                ty = ValueType.I32;\n                writeBytes = 1;\n            } else if (inst.opcode == Instructions.I32_STORE16) {\n                ty = ValueType.I32;\n                writeBytes = 2;\n            } else if (inst.opcode == Instructions.I64_STORE8) {\n                ty = ValueType.I64;\n                writeBytes = 1;\n            } else if (inst.opcode == Instructions.I64_STORE16) {\n                ty = ValueType.I64;\n                writeBytes = 2;\n            } else if (inst.opcode == Instructions.I64_STORE32) {\n                ty = ValueType.I64;\n                writeBytes = 4;\n            } else {\n                revert(\"INVALID_MEMORY_STORE_OPCODE\");\n            }\n\n            Value memory writingVal = mach.valueStack.pop();\n            require(writingVal.valueType == ty, \"BAD_STORE_TYPE\");\n            toWrite = uint64(writingVal.contents);\n            if (writeBytes < 8) {\n                toWrite &= (uint64(1) << (writeBytes * 8)) - 1;\n            }\n        }\n\n        // Neither of these can overflow as they're computed with much less than 256 bit integers.\n        uint256 startIdx = inst.argumentData + mach.valueStack.pop().assumeI32();\n        if (startIdx + writeBytes > mod.moduleMemory.size) {\n            mach.status = MachineStatus.ERRORED;\n            return;\n        }\n\n        uint256 proofOffset = 0;\n        uint256 lastProvedLeafIdx = ~uint256(0);\n        MerkleProof memory lastProvedMerkle;\n        bytes32 lastProvedLeafContents;\n        for (uint256 i = 0; i < writeBytes; i++) {\n            uint256 idx = startIdx + i;\n            uint256 leafIdx = idx / LEAF_SIZE;\n            if (leafIdx != lastProvedLeafIdx) {\n                if (lastProvedLeafIdx != ~uint256(0)) {\n                    // Apply the last leaf update\n                    mod.moduleMemory.merkleRoot = lastProvedMerkle.computeRootFromMemory(\n                        lastProvedLeafIdx,\n                        lastProvedLeafContents\n                    );\n                }\n                // This hits the stack size if we phrase it as mod.moduleMemory.proveLeaf(...)\n                (lastProvedLeafContents, proofOffset, lastProvedMerkle) = ModuleMemoryLib.proveLeaf(\n                    mod.moduleMemory,\n                    leafIdx,\n                    proof,\n                    proofOffset\n                );\n                lastProvedLeafIdx = leafIdx;\n            }\n            uint256 indexWithinLeaf = idx % LEAF_SIZE;\n            lastProvedLeafContents = setLeafByte(\n                lastProvedLeafContents,\n                indexWithinLeaf,\n                uint8(toWrite)\n            );\n            toWrite >>= 8;\n        }\n        mod.moduleMemory.merkleRoot = lastProvedMerkle.computeRootFromMemory(\n            lastProvedLeafIdx,\n            lastProvedLeafContents\n        );\n    }\n\n    function executeMemorySize(\n        Machine memory mach,\n        Module memory mod,\n        Instruction calldata,\n        bytes calldata\n    ) internal pure {\n        uint32 pages = uint32(mod.moduleMemory.size / PAGE_SIZE);\n        mach.valueStack.push(ValueLib.newI32(pages));\n    }\n\n    function executeMemoryGrow(\n        Machine memory mach,\n        Module memory mod,\n        Instruction calldata,\n        bytes calldata\n    ) internal pure {\n        uint32 oldPages = uint32(mod.moduleMemory.size / PAGE_SIZE);\n        uint32 growingPages = mach.valueStack.pop().assumeI32();\n        // Safe as the input integers are too small to overflow a uint256\n        uint256 newSize = uint256(oldPages) + uint256(growingPages);\n        if (newSize <= mod.moduleMemory.maxSize) {\n            mod.moduleMemory.size = uint64(newSize * PAGE_SIZE);\n            mach.valueStack.push(ValueLib.newI32(oldPages));\n        } else {\n            mach.valueStack.push(ValueLib.newI32(~uint32(0)));\n        }\n    }\n\n    function executeOneStep(\n        ExecutionContext calldata,\n        Machine calldata startMach,\n        Module calldata startMod,\n        Instruction calldata inst,\n        bytes calldata proof\n    ) external pure override returns (Machine memory mach, Module memory mod) {\n        mach = startMach;\n        mod = startMod;\n\n        uint16 opcode = inst.opcode;\n\n        function(Machine memory, Module memory, Instruction calldata, bytes calldata)\n            internal\n            pure impl;\n        if (opcode >= Instructions.I32_LOAD && opcode <= Instructions.I64_LOAD32_U) {\n            impl = executeMemoryLoad;\n        } else if (opcode >= Instructions.I32_STORE && opcode <= Instructions.I64_STORE32) {\n            impl = executeMemoryStore;\n        } else if (opcode == Instructions.MEMORY_SIZE) {\n            impl = executeMemorySize;\n        } else if (opcode == Instructions.MEMORY_GROW) {\n            impl = executeMemoryGrow;\n        } else {\n            revert(\"INVALID_MEMORY_OPCODE\");\n        }\n\n        impl(mach, mod, inst, proof);\n    }\n}\n"
      },
      "src/state/Deserialize.sol": {
        "content": "// Copyright 2021-2022, Offchain Labs, Inc.\n// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE\n// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.0;\n\nimport \"./Value.sol\";\nimport \"./ValueStack.sol\";\nimport \"./Machine.sol\";\nimport \"./MultiStack.sol\";\nimport \"./Instructions.sol\";\nimport \"./StackFrame.sol\";\nimport \"./MerkleProof.sol\";\nimport \"./ModuleMemoryCompact.sol\";\nimport \"./Module.sol\";\nimport \"./GlobalState.sol\";\n\nlibrary Deserialize {\n    function u8(bytes calldata proof, uint256 startOffset)\n        internal\n        pure\n        returns (uint8 ret, uint256 offset)\n    {\n        offset = startOffset;\n        ret = uint8(proof[offset]);\n        offset++;\n    }\n\n    function u16(bytes calldata proof, uint256 startOffset)\n        internal\n        pure\n        returns (uint16 ret, uint256 offset)\n    {\n        offset = startOffset;\n        for (uint256 i = 0; i < 16 / 8; i++) {\n            ret <<= 8;\n            ret |= uint8(proof[offset]);\n            offset++;\n        }\n    }\n\n    function u32(bytes calldata proof, uint256 startOffset)\n        internal\n        pure\n        returns (uint32 ret, uint256 offset)\n    {\n        offset = startOffset;\n        for (uint256 i = 0; i < 32 / 8; i++) {\n            ret <<= 8;\n            ret |= uint8(proof[offset]);\n            offset++;\n        }\n    }\n\n    function u64(bytes calldata proof, uint256 startOffset)\n        internal\n        pure\n        returns (uint64 ret, uint256 offset)\n    {\n        offset = startOffset;\n        for (uint256 i = 0; i < 64 / 8; i++) {\n            ret <<= 8;\n            ret |= uint8(proof[offset]);\n            offset++;\n        }\n    }\n\n    function u256(bytes calldata proof, uint256 startOffset)\n        internal\n        pure\n        returns (uint256 ret, uint256 offset)\n    {\n        offset = startOffset;\n        for (uint256 i = 0; i < 256 / 8; i++) {\n            ret <<= 8;\n            ret |= uint8(proof[offset]);\n            offset++;\n        }\n    }\n\n    function b32(bytes calldata proof, uint256 startOffset)\n        internal\n        pure\n        returns (bytes32 ret, uint256 offset)\n    {\n        offset = startOffset;\n        uint256 retInt;\n        (retInt, offset) = u256(proof, offset);\n        ret = bytes32(retInt);\n    }\n\n    function boolean(bytes calldata proof, uint256 startOffset)\n        internal\n        pure\n        returns (bool ret, uint256 offset)\n    {\n        offset = startOffset;\n        ret = uint8(proof[offset]) != 0;\n        offset++;\n    }\n\n    function value(bytes calldata proof, uint256 startOffset)\n        internal\n        pure\n        returns (Value memory val, uint256 offset)\n    {\n        offset = startOffset;\n        uint8 typeInt = uint8(proof[offset]);\n        offset++;\n        require(typeInt <= uint8(ValueLib.maxValueType()), \"BAD_VALUE_TYPE\");\n        uint256 contents;\n        (contents, offset) = u256(proof, offset);\n        val = Value({valueType: ValueType(typeInt), contents: contents});\n    }\n\n    function valueStack(bytes calldata proof, uint256 startOffset)\n        internal\n        pure\n        returns (ValueStack memory stack, uint256 offset)\n    {\n        offset = startOffset;\n        bytes32 remainingHash;\n        (remainingHash, offset) = b32(proof, offset);\n        uint256 provedLength;\n        (provedLength, offset) = u256(proof, offset);\n        Value[] memory proved = new Value[](provedLength);\n        for (uint256 i = 0; i < proved.length; i++) {\n            (proved[i], offset) = value(proof, offset);\n        }\n        stack = ValueStack({proved: ValueArray(proved), remainingHash: remainingHash});\n    }\n\n    function multiStack(bytes calldata proof, uint256 startOffset)\n        internal\n        pure\n        returns (MultiStack memory multistack, uint256 offset)\n    {\n        offset = startOffset;\n        bytes32 inactiveStackHash;\n        (inactiveStackHash, offset) = b32(proof, offset);\n        bytes32 remainingHash;\n        (remainingHash, offset) = b32(proof, offset);\n        multistack = MultiStack({\n            inactiveStackHash: inactiveStackHash,\n            remainingHash: remainingHash\n        });\n    }\n\n    function instructions(bytes calldata proof, uint256 startOffset)\n        internal\n        pure\n        returns (Instruction[] memory code, uint256 offset)\n    {\n        offset = startOffset;\n        uint8 count;\n        (count, offset) = u8(proof, offset);\n        code = new Instruction[](count);\n\n        for (uint256 i = 0; i < uint256(count); i++) {\n            uint16 opcode;\n            uint256 data;\n            (opcode, offset) = u16(proof, offset);\n            (data, offset) = u256(proof, offset);\n            code[i] = Instruction({opcode: opcode, argumentData: data});\n        }\n    }\n\n    function stackFrame(bytes calldata proof, uint256 startOffset)\n        internal\n        pure\n        returns (StackFrame memory window, uint256 offset)\n    {\n        offset = startOffset;\n        Value memory returnPc;\n        bytes32 localsMerkleRoot;\n        uint32 callerModule;\n        uint32 callerModuleInternals;\n        (returnPc, offset) = value(proof, offset);\n        (localsMerkleRoot, offset) = b32(proof, offset);\n        (callerModule, offset) = u32(proof, offset);\n        (callerModuleInternals, offset) = u32(proof, offset);\n        window = StackFrame({\n            returnPc: returnPc,\n            localsMerkleRoot: localsMerkleRoot,\n            callerModule: callerModule,\n            callerModuleInternals: callerModuleInternals\n        });\n    }\n\n    function stackFrameWindow(bytes calldata proof, uint256 startOffset)\n        internal\n        pure\n        returns (StackFrameWindow memory window, uint256 offset)\n    {\n        offset = startOffset;\n        bytes32 remainingHash;\n        (remainingHash, offset) = b32(proof, offset);\n        StackFrame[] memory proved;\n        if (proof[offset] != 0) {\n            offset++;\n            proved = new StackFrame[](1);\n            (proved[0], offset) = stackFrame(proof, offset);\n        } else {\n            offset++;\n            proved = new StackFrame[](0);\n        }\n        window = StackFrameWindow({proved: proved, remainingHash: remainingHash});\n    }\n\n    function moduleMemory(bytes calldata proof, uint256 startOffset)\n        internal\n        pure\n        returns (ModuleMemory memory mem, uint256 offset)\n    {\n        offset = startOffset;\n        uint64 size;\n        uint64 maxSize;\n        bytes32 root;\n        (size, offset) = u64(proof, offset);\n        (maxSize, offset) = u64(proof, offset);\n        (root, offset) = b32(proof, offset);\n        mem = ModuleMemory({size: size, maxSize: maxSize, merkleRoot: root});\n    }\n\n    function module(bytes calldata proof, uint256 startOffset)\n        internal\n        pure\n        returns (Module memory mod, uint256 offset)\n    {\n        offset = startOffset;\n        bytes32 globalsMerkleRoot;\n        ModuleMemory memory mem;\n        bytes32 tablesMerkleRoot;\n        bytes32 functionsMerkleRoot;\n        bytes32 extraHash;\n        uint32 internalsOffset;\n        (globalsMerkleRoot, offset) = b32(proof, offset);\n        (mem, offset) = moduleMemory(proof, offset);\n        (tablesMerkleRoot, offset) = b32(proof, offset);\n        (functionsMerkleRoot, offset) = b32(proof, offset);\n        (extraHash, offset) = b32(proof, offset);\n        (internalsOffset, offset) = u32(proof, offset);\n        mod = Module({\n            globalsMerkleRoot: globalsMerkleRoot,\n            moduleMemory: mem,\n            tablesMerkleRoot: tablesMerkleRoot,\n            functionsMerkleRoot: functionsMerkleRoot,\n            extraHash: extraHash,\n            internalsOffset: internalsOffset\n        });\n    }\n\n    function globalState(bytes calldata proof, uint256 startOffset)\n        internal\n        pure\n        returns (GlobalState memory state, uint256 offset)\n    {\n        offset = startOffset;\n\n        // using constant ints for array size requires newer solidity\n        bytes32[2] memory bytes32Vals;\n        uint64[2] memory u64Vals;\n\n        for (uint8 i = 0; i < GlobalStateLib.BYTES32_VALS_NUM; i++) {\n            (bytes32Vals[i], offset) = b32(proof, offset);\n        }\n        for (uint8 i = 0; i < GlobalStateLib.U64_VALS_NUM; i++) {\n            (u64Vals[i], offset) = u64(proof, offset);\n        }\n        state = GlobalState({bytes32Vals: bytes32Vals, u64Vals: u64Vals});\n    }\n\n    function machine(bytes calldata proof, uint256 startOffset)\n        internal\n        pure\n        returns (Machine memory mach, uint256 offset)\n    {\n        offset = startOffset;\n        {\n            MachineStatus status;\n            {\n                uint8 statusU8;\n                (statusU8, offset) = u8(proof, offset);\n                if (statusU8 == 0) {\n                    status = MachineStatus.RUNNING;\n                } else if (statusU8 == 1) {\n                    status = MachineStatus.FINISHED;\n                } else if (statusU8 == 2) {\n                    status = MachineStatus.ERRORED;\n                } else if (statusU8 == 3) {\n                    status = MachineStatus.TOO_FAR;\n                } else {\n                    revert(\"UNKNOWN_MACH_STATUS\");\n                }\n            }\n            ValueStack memory values;\n            ValueStack memory internalStack;\n            MultiStack memory valuesMulti;\n            StackFrameWindow memory frameStack;\n            MultiStack memory framesMulti;\n            (values, offset) = valueStack(proof, offset);\n            (valuesMulti, offset) = multiStack(proof, offset);\n            (internalStack, offset) = valueStack(proof, offset);\n            (frameStack, offset) = stackFrameWindow(proof, offset);\n            (framesMulti, offset) = multiStack(proof, offset);\n            mach = Machine({\n                status: status,\n                valueStack: values,\n                valueMultiStack: valuesMulti,\n                internalStack: internalStack,\n                frameStack: frameStack,\n                frameMultiStack: framesMulti,\n                globalStateHash: bytes32(0), // filled later\n                moduleIdx: 0, // filled later\n                functionIdx: 0, // filled later\n                functionPc: 0, // filled later\n                recoveryPc: bytes32(0), // filled later\n                modulesRoot: bytes32(0) // filled later\n            });\n        }\n        (mach.globalStateHash, offset) = b32(proof, offset);\n        (mach.moduleIdx, offset) = u32(proof, offset);\n        (mach.functionIdx, offset) = u32(proof, offset);\n        (mach.functionPc, offset) = u32(proof, offset);\n        (mach.recoveryPc, offset) = b32(proof, offset);\n        (mach.modulesRoot, offset) = b32(proof, offset);\n    }\n\n    function merkleProof(bytes calldata proof, uint256 startOffset)\n        internal\n        pure\n        returns (MerkleProof memory merkle, uint256 offset)\n    {\n        offset = startOffset;\n        uint8 length;\n        (length, offset) = u8(proof, offset);\n        bytes32[] memory counterparts = new bytes32[](length);\n        for (uint8 i = 0; i < length; i++) {\n            (counterparts[i], offset) = b32(proof, offset);\n        }\n        merkle = MerkleProof(counterparts);\n    }\n}\n"
      },
      "src/state/GlobalState.sol": {
        "content": "// Copyright 2021-2022, Offchain Labs, Inc.\n// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE\n// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.0;\n\nstruct GlobalState {\n    bytes32[2] bytes32Vals;\n    uint64[2] u64Vals;\n}\n\nlibrary GlobalStateLib {\n    uint16 internal constant BYTES32_VALS_NUM = 2;\n    uint16 internal constant U64_VALS_NUM = 2;\n\n    function hash(GlobalState memory state) internal pure returns (bytes32) {\n        return\n            keccak256(\n                abi.encodePacked(\n                    \"Global state:\",\n                    state.bytes32Vals[0],\n                    state.bytes32Vals[1],\n                    state.u64Vals[0],\n                    state.u64Vals[1]\n                )\n            );\n    }\n\n    function getBlockHash(GlobalState memory state) internal pure returns (bytes32) {\n        return state.bytes32Vals[0];\n    }\n\n    function getSendRoot(GlobalState memory state) internal pure returns (bytes32) {\n        return state.bytes32Vals[1];\n    }\n\n    function getInboxPosition(GlobalState memory state) internal pure returns (uint64) {\n        return state.u64Vals[0];\n    }\n\n    function getPositionInMessage(GlobalState memory state) internal pure returns (uint64) {\n        return state.u64Vals[1];\n    }\n\n    function isEmpty(GlobalState calldata state) internal pure returns (bool) {\n        return (state.bytes32Vals[0] == bytes32(0) &&\n            state.bytes32Vals[1] == bytes32(0) &&\n            state.u64Vals[0] == 0 &&\n            state.u64Vals[1] == 0);\n    }\n}\n"
      },
      "src/state/Instructions.sol": {
        "content": "// Copyright 2021-2023, Offchain Labs, Inc.\n// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE\n// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.0;\n\nstruct Instruction {\n    uint16 opcode;\n    uint256 argumentData;\n}\n\nlibrary Instructions {\n    uint16 internal constant UNREACHABLE = 0x00;\n    uint16 internal constant NOP = 0x01;\n    uint16 internal constant RETURN = 0x0F;\n    uint16 internal constant CALL = 0x10;\n    uint16 internal constant CALL_INDIRECT = 0x11;\n    uint16 internal constant LOCAL_GET = 0x20;\n    uint16 internal constant LOCAL_SET = 0x21;\n    uint16 internal constant GLOBAL_GET = 0x23;\n    uint16 internal constant GLOBAL_SET = 0x24;\n\n    uint16 internal constant I32_LOAD = 0x28;\n    uint16 internal constant I64_LOAD = 0x29;\n    uint16 internal constant F32_LOAD = 0x2A;\n    uint16 internal constant F64_LOAD = 0x2B;\n    uint16 internal constant I32_LOAD8_S = 0x2C;\n    uint16 internal constant I32_LOAD8_U = 0x2D;\n    uint16 internal constant I32_LOAD16_S = 0x2E;\n    uint16 internal constant I32_LOAD16_U = 0x2F;\n    uint16 internal constant I64_LOAD8_S = 0x30;\n    uint16 internal constant I64_LOAD8_U = 0x31;\n    uint16 internal constant I64_LOAD16_S = 0x32;\n    uint16 internal constant I64_LOAD16_U = 0x33;\n    uint16 internal constant I64_LOAD32_S = 0x34;\n    uint16 internal constant I64_LOAD32_U = 0x35;\n\n    uint16 internal constant I32_STORE = 0x36;\n    uint16 internal constant I64_STORE = 0x37;\n    uint16 internal constant F32_STORE = 0x38;\n    uint16 internal constant F64_STORE = 0x39;\n    uint16 internal constant I32_STORE8 = 0x3A;\n    uint16 internal constant I32_STORE16 = 0x3B;\n    uint16 internal constant I64_STORE8 = 0x3C;\n    uint16 internal constant I64_STORE16 = 0x3D;\n    uint16 internal constant I64_STORE32 = 0x3E;\n\n    uint16 internal constant MEMORY_SIZE = 0x3F;\n    uint16 internal constant MEMORY_GROW = 0x40;\n\n    uint16 internal constant DROP = 0x1A;\n    uint16 internal constant SELECT = 0x1B;\n    uint16 internal constant I32_CONST = 0x41;\n    uint16 internal constant I64_CONST = 0x42;\n    uint16 internal constant F32_CONST = 0x43;\n    uint16 internal constant F64_CONST = 0x44;\n    uint16 internal constant I32_EQZ = 0x45;\n    uint16 internal constant I32_RELOP_BASE = 0x46;\n    uint16 internal constant IRELOP_EQ = 0;\n    uint16 internal constant IRELOP_NE = 1;\n    uint16 internal constant IRELOP_LT_S = 2;\n    uint16 internal constant IRELOP_LT_U = 3;\n    uint16 internal constant IRELOP_GT_S = 4;\n    uint16 internal constant IRELOP_GT_U = 5;\n    uint16 internal constant IRELOP_LE_S = 6;\n    uint16 internal constant IRELOP_LE_U = 7;\n    uint16 internal constant IRELOP_GE_S = 8;\n    uint16 internal constant IRELOP_GE_U = 9;\n    uint16 internal constant IRELOP_LAST = IRELOP_GE_U;\n\n    uint16 internal constant I64_EQZ = 0x50;\n    uint16 internal constant I64_RELOP_BASE = 0x51;\n\n    uint16 internal constant I32_UNOP_BASE = 0x67;\n    uint16 internal constant IUNOP_CLZ = 0;\n    uint16 internal constant IUNOP_CTZ = 1;\n    uint16 internal constant IUNOP_POPCNT = 2;\n    uint16 internal constant IUNOP_LAST = IUNOP_POPCNT;\n\n    uint16 internal constant I32_ADD = 0x6A;\n    uint16 internal constant I32_SUB = 0x6B;\n    uint16 internal constant I32_MUL = 0x6C;\n    uint16 internal constant I32_DIV_S = 0x6D;\n    uint16 internal constant I32_DIV_U = 0x6E;\n    uint16 internal constant I32_REM_S = 0x6F;\n    uint16 internal constant I32_REM_U = 0x70;\n    uint16 internal constant I32_AND = 0x71;\n    uint16 internal constant I32_OR = 0x72;\n    uint16 internal constant I32_XOR = 0x73;\n    uint16 internal constant I32_SHL = 0x74;\n    uint16 internal constant I32_SHR_S = 0x75;\n    uint16 internal constant I32_SHR_U = 0x76;\n    uint16 internal constant I32_ROTL = 0x77;\n    uint16 internal constant I32_ROTR = 0x78;\n\n    uint16 internal constant I64_UNOP_BASE = 0x79;\n\n    uint16 internal constant I64_ADD = 0x7C;\n    uint16 internal constant I64_SUB = 0x7D;\n    uint16 internal constant I64_MUL = 0x7E;\n    uint16 internal constant I64_DIV_S = 0x7F;\n    uint16 internal constant I64_DIV_U = 0x80;\n    uint16 internal constant I64_REM_S = 0x81;\n    uint16 internal constant I64_REM_U = 0x82;\n    uint16 internal constant I64_AND = 0x83;\n    uint16 internal constant I64_OR = 0x84;\n    uint16 internal constant I64_XOR = 0x85;\n    uint16 internal constant I64_SHL = 0x86;\n    uint16 internal constant I64_SHR_S = 0x87;\n    uint16 internal constant I64_SHR_U = 0x88;\n    uint16 internal constant I64_ROTL = 0x89;\n    uint16 internal constant I64_ROTR = 0x8A;\n\n    uint16 internal constant I32_WRAP_I64 = 0xA7;\n    uint16 internal constant I64_EXTEND_I32_S = 0xAC;\n    uint16 internal constant I64_EXTEND_I32_U = 0xAD;\n\n    uint16 internal constant I32_REINTERPRET_F32 = 0xBC;\n    uint16 internal constant I64_REINTERPRET_F64 = 0xBD;\n    uint16 internal constant F32_REINTERPRET_I32 = 0xBE;\n    uint16 internal constant F64_REINTERPRET_I64 = 0xBF;\n\n    uint16 internal constant I32_EXTEND_8S = 0xC0;\n    uint16 internal constant I32_EXTEND_16S = 0xC1;\n    uint16 internal constant I64_EXTEND_8S = 0xC2;\n    uint16 internal constant I64_EXTEND_16S = 0xC3;\n    uint16 internal constant I64_EXTEND_32S = 0xC4;\n\n    uint16 internal constant INIT_FRAME = 0x8002;\n    uint16 internal constant ARBITRARY_JUMP = 0x8003;\n    uint16 internal constant ARBITRARY_JUMP_IF = 0x8004;\n    uint16 internal constant MOVE_FROM_STACK_TO_INTERNAL = 0x8005;\n    uint16 internal constant MOVE_FROM_INTERNAL_TO_STACK = 0x8006;\n    uint16 internal constant DUP = 0x8008;\n    uint16 internal constant CROSS_MODULE_CALL = 0x8009;\n    uint16 internal constant CALLER_MODULE_INTERNAL_CALL = 0x800A;\n    uint16 internal constant CROSS_MODULE_FORWARD = 0x800B;\n    uint16 internal constant CROSS_MODULE_INTERNAL_CALL = 0x800C;\n\n    uint16 internal constant GET_GLOBAL_STATE_BYTES32 = 0x8010;\n    uint16 internal constant SET_GLOBAL_STATE_BYTES32 = 0x8011;\n    uint16 internal constant GET_GLOBAL_STATE_U64 = 0x8012;\n    uint16 internal constant SET_GLOBAL_STATE_U64 = 0x8013;\n\n    uint16 internal constant READ_PRE_IMAGE = 0x8020;\n    uint16 internal constant READ_INBOX_MESSAGE = 0x8021;\n    uint16 internal constant HALT_AND_SET_FINISHED = 0x8022;\n    uint16 internal constant LINK_MODULE = 0x8023;\n    uint16 internal constant UNLINK_MODULE = 0x8024;\n\n    uint16 internal constant NEW_COTHREAD = 0x8030;\n    uint16 internal constant POP_COTHREAD = 0x8031;\n    uint16 internal constant SWITCH_COTHREAD = 0x8032;\n\n    uint256 internal constant INBOX_INDEX_SEQUENCER = 0;\n    uint256 internal constant INBOX_INDEX_DELAYED = 1;\n\n    function hash(Instruction[] memory code) internal pure returns (bytes32) {\n        // To avoid quadratic expense, we declare a `bytes` early and populate its contents.\n        bytes memory data = new bytes(13 + 1 + 34 * code.length);\n        assembly {\n            // Represents the string \"Instructions:\", which we place after the length word.\n            mstore(\n                add(data, 32),\n                0x496e737472756374696f6e733a00000000000000000000000000000000000000\n            )\n        }\n\n        // write the instruction count\n        uint256 offset = 13;\n        data[offset] = bytes1(uint8(code.length));\n        offset++;\n\n        // write each instruction\n        for (uint256 i = 0; i < code.length; i++) {\n            Instruction memory inst = code[i];\n            data[offset] = bytes1(uint8(inst.opcode >> 8));\n            data[offset + 1] = bytes1(uint8(inst.opcode));\n            offset += 2;\n            uint256 argumentData = inst.argumentData;\n            assembly {\n                mstore(add(add(data, 32), offset), argumentData)\n            }\n            offset += 32;\n        }\n        return keccak256(data);\n    }\n}\n"
      },
      "src/state/Machine.sol": {
        "content": "// Copyright 2021-2023, Offchain Labs, Inc.\n// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE\n// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.0;\n\nimport \"./ValueStack.sol\";\nimport \"./Instructions.sol\";\nimport \"./MultiStack.sol\";\nimport \"./StackFrame.sol\";\n\nenum MachineStatus {\n    RUNNING,\n    FINISHED,\n    ERRORED,\n    TOO_FAR\n}\n\nstruct Machine {\n    MachineStatus status;\n    ValueStack valueStack;\n    MultiStack valueMultiStack;\n    ValueStack internalStack;\n    StackFrameWindow frameStack;\n    MultiStack frameMultiStack;\n    bytes32 globalStateHash;\n    uint32 moduleIdx;\n    uint32 functionIdx;\n    uint32 functionPc;\n    bytes32 recoveryPc;\n    bytes32 modulesRoot;\n}\n\nlibrary MachineLib {\n    using StackFrameLib for StackFrameWindow;\n    using ValueStackLib for ValueStack;\n    using MultiStackLib for MultiStack;\n\n    bytes32 internal constant NO_RECOVERY_PC = ~bytes32(0);\n\n    function hash(Machine memory mach) internal pure returns (bytes32) {\n        // Warning: the non-running hashes are replicated in Challenge\n        if (mach.status == MachineStatus.RUNNING) {\n            bytes32 valueMultiHash = mach.valueMultiStack.hash(\n                mach.valueStack.hash(),\n                mach.recoveryPc != NO_RECOVERY_PC\n            );\n            bytes32 frameMultiHash = mach.frameMultiStack.hash(\n                mach.frameStack.hash(),\n                mach.recoveryPc != NO_RECOVERY_PC\n            );\n            bytes memory preimage = abi.encodePacked(\n                \"Machine running:\",\n                valueMultiHash,\n                mach.internalStack.hash(),\n                frameMultiHash,\n                mach.globalStateHash,\n                mach.moduleIdx,\n                mach.functionIdx,\n                mach.functionPc,\n                mach.recoveryPc,\n                mach.modulesRoot\n            );\n            return keccak256(preimage);\n        } else if (mach.status == MachineStatus.FINISHED) {\n            return keccak256(abi.encodePacked(\"Machine finished:\", mach.globalStateHash));\n        } else if (mach.status == MachineStatus.ERRORED) {\n            return keccak256(abi.encodePacked(\"Machine errored:\"));\n        } else if (mach.status == MachineStatus.TOO_FAR) {\n            return keccak256(abi.encodePacked(\"Machine too far:\"));\n        } else {\n            revert(\"BAD_MACH_STATUS\");\n        }\n    }\n\n    function switchCoThreadStacks(Machine memory mach) internal pure {\n        bytes32 newActiveValue = mach.valueMultiStack.inactiveStackHash;\n        bytes32 newActiveFrame = mach.frameMultiStack.inactiveStackHash;\n        if (\n            newActiveFrame == MultiStackLib.NO_STACK_HASH ||\n            newActiveValue == MultiStackLib.NO_STACK_HASH\n        ) {\n            mach.status = MachineStatus.ERRORED;\n            return;\n        }\n        mach.frameMultiStack.inactiveStackHash = mach.frameStack.hash();\n        mach.valueMultiStack.inactiveStackHash = mach.valueStack.hash();\n        mach.frameStack.overwrite(newActiveFrame);\n        mach.valueStack.overwrite(newActiveValue);\n    }\n\n    function setPcFromData(Machine memory mach, uint256 data) internal pure returns (bool) {\n        if (data >> 96 != 0) {\n            return false;\n        }\n\n        mach.functionPc = uint32(data);\n        mach.functionIdx = uint32(data >> 32);\n        mach.moduleIdx = uint32(data >> 64);\n        return true;\n    }\n\n    function setPcFromRecovery(Machine memory mach) internal pure returns (bool) {\n        if (!setPcFromData(mach, uint256(mach.recoveryPc))) {\n            return false;\n        }\n        mach.recoveryPc = NO_RECOVERY_PC;\n        return true;\n    }\n\n    function setRecoveryFromPc(Machine memory mach, uint32 offset) internal pure returns (bool) {\n        if (mach.recoveryPc != NO_RECOVERY_PC) {\n            return false;\n        }\n\n        uint256 result;\n        result = uint256(mach.moduleIdx) << 64;\n        result = result | (uint256(mach.functionIdx) << 32);\n        result = result | uint256(mach.functionPc + offset - 1);\n        mach.recoveryPc = bytes32(result);\n        return true;\n    }\n\n    function setPc(Machine memory mach, Value memory pc) internal pure {\n        if (pc.valueType == ValueType.REF_NULL) {\n            mach.status = MachineStatus.ERRORED;\n            return;\n        }\n        if (pc.valueType != ValueType.INTERNAL_REF) {\n            mach.status = MachineStatus.ERRORED;\n            return;\n        }\n        if (!setPcFromData(mach, pc.contents)) {\n            mach.status = MachineStatus.ERRORED;\n            return;\n        }\n    }\n}\n"
      },
      "src/state/MerkleProof.sol": {
        "content": "// Copyright 2021-2023, Offchain Labs, Inc.\n// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE\n// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.0;\n\nimport \"./Value.sol\";\nimport \"./Instructions.sol\";\nimport \"./Module.sol\";\n\nstruct MerkleProof {\n    bytes32[] counterparts;\n}\n\nlibrary MerkleProofLib {\n    using ModuleLib for Module;\n    using ValueLib for Value;\n\n    function computeRootFromValue(\n        MerkleProof memory proof,\n        uint256 index,\n        Value memory leaf\n    ) internal pure returns (bytes32) {\n        return computeRootUnsafe(proof, index, leaf.hash(), \"Value merkle tree:\");\n    }\n\n    function computeRootFromInstructions(\n        MerkleProof memory proof,\n        uint256 index,\n        Instruction[] memory code\n    ) internal pure returns (bytes32) {\n        return computeRootUnsafe(proof, index, Instructions.hash(code), \"Instruction merkle tree:\");\n    }\n\n    function computeRootFromFunction(\n        MerkleProof memory proof,\n        uint256 index,\n        bytes32 codeRoot\n    ) internal pure returns (bytes32) {\n        bytes32 h = keccak256(abi.encodePacked(\"Function:\", codeRoot));\n        return computeRootUnsafe(proof, index, h, \"Function merkle tree:\");\n    }\n\n    function computeRootFromMemory(\n        MerkleProof memory proof,\n        uint256 index,\n        bytes32 contents\n    ) internal pure returns (bytes32) {\n        bytes32 h = keccak256(abi.encodePacked(\"Memory leaf:\", contents));\n        return computeRootUnsafe(proof, index, h, \"Memory merkle tree:\");\n    }\n\n    function computeRootFromElement(\n        MerkleProof memory proof,\n        uint256 index,\n        bytes32 funcTypeHash,\n        Value memory val\n    ) internal pure returns (bytes32) {\n        bytes32 h = keccak256(abi.encodePacked(\"Table element:\", funcTypeHash, val.hash()));\n        return computeRootUnsafe(proof, index, h, \"Table element merkle tree:\");\n    }\n\n    function computeRootFromTable(\n        MerkleProof memory proof,\n        uint256 index,\n        uint8 tableType,\n        uint64 tableSize,\n        bytes32 elementsRoot\n    ) internal pure returns (bytes32) {\n        bytes32 h = keccak256(abi.encodePacked(\"Table:\", tableType, tableSize, elementsRoot));\n        return computeRootUnsafe(proof, index, h, \"Table merkle tree:\");\n    }\n\n    function computeRootFromModule(\n        MerkleProof memory proof,\n        uint256 index,\n        Module memory mod\n    ) internal pure returns (bytes32) {\n        return computeRootUnsafe(proof, index, mod.hash(), \"Module merkle tree:\");\n    }\n\n    // WARNING: leafHash must be computed in such a way that it cannot be a non-leaf hash.\n    function computeRootUnsafe(\n        MerkleProof memory proof,\n        uint256 index,\n        bytes32 leafHash,\n        string memory prefix\n    ) internal pure returns (bytes32 h) {\n        h = leafHash;\n        for (uint256 layer = 0; layer < proof.counterparts.length; layer++) {\n            if (index & 1 == 0) {\n                h = keccak256(abi.encodePacked(prefix, h, proof.counterparts[layer]));\n            } else {\n                h = keccak256(abi.encodePacked(prefix, proof.counterparts[layer], h));\n            }\n            index >>= 1;\n        }\n        require(index == 0, \"PROOF_TOO_SHORT\");\n    }\n\n    function growToNewRoot(\n        bytes32 root,\n        uint256 leaf,\n        bytes32 hash,\n        bytes32 zero,\n        string memory prefix\n    ) internal pure returns (bytes32) {\n        bytes32 h = hash;\n        uint256 node = leaf;\n        while (node > 1) {\n            h = keccak256(abi.encodePacked(prefix, h, zero));\n            zero = keccak256(abi.encodePacked(prefix, zero, zero));\n            node >>= 1;\n        }\n        return keccak256(abi.encodePacked(prefix, root, h));\n    }\n}\n"
      },
      "src/state/Module.sol": {
        "content": "// Copyright 2021-2023, Offchain Labs, Inc.\n// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE\n// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.0;\n\nimport \"./ModuleMemoryCompact.sol\";\n\nstruct Module {\n    bytes32 globalsMerkleRoot;\n    ModuleMemory moduleMemory;\n    bytes32 tablesMerkleRoot;\n    bytes32 functionsMerkleRoot;\n    bytes32 extraHash;\n    uint32 internalsOffset;\n}\n\nlibrary ModuleLib {\n    using ModuleMemoryCompactLib for ModuleMemory;\n\n    function hash(Module memory mod) internal pure returns (bytes32) {\n        return\n            keccak256(\n                abi.encodePacked(\n                    \"Module:\",\n                    mod.globalsMerkleRoot,\n                    mod.moduleMemory.hash(),\n                    mod.tablesMerkleRoot,\n                    mod.functionsMerkleRoot,\n                    mod.extraHash,\n                    mod.internalsOffset\n                )\n            );\n    }\n}\n"
      },
      "src/state/ModuleMemory.sol": {
        "content": "// Copyright 2021-2022, Offchain Labs, Inc.\n// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE\n// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.0;\n\nimport \"./MerkleProof.sol\";\nimport \"./Deserialize.sol\";\nimport \"./ModuleMemoryCompact.sol\";\n\nlibrary ModuleMemoryLib {\n    using MerkleProofLib for MerkleProof;\n\n    uint256 private constant LEAF_SIZE = 32;\n\n    function hash(ModuleMemory memory mem) internal pure returns (bytes32) {\n        return ModuleMemoryCompactLib.hash(mem);\n    }\n\n    function proveLeaf(\n        ModuleMemory memory mem,\n        uint256 leafIdx,\n        bytes calldata proof,\n        uint256 startOffset\n    )\n        internal\n        pure\n        returns (\n            bytes32 contents,\n            uint256 offset,\n            MerkleProof memory merkle\n        )\n    {\n        offset = startOffset;\n        (contents, offset) = Deserialize.b32(proof, offset);\n        (merkle, offset) = Deserialize.merkleProof(proof, offset);\n        bytes32 recomputedRoot = merkle.computeRootFromMemory(leafIdx, contents);\n        require(recomputedRoot == mem.merkleRoot, \"WRONG_MEM_ROOT\");\n    }\n\n    function isValidLeaf(ModuleMemory memory mem, uint256 pointer) internal pure returns (bool) {\n        return pointer + 32 <= mem.size && pointer % LEAF_SIZE == 0;\n    }\n\n    function pullLeafByte(bytes32 leaf, uint256 idx) internal pure returns (uint8) {\n        require(idx < LEAF_SIZE, \"BAD_PULL_LEAF_BYTE_IDX\");\n        // Take into account that we are casting the leaf to a big-endian integer\n        uint256 leafShift = (LEAF_SIZE - 1 - idx) * 8;\n        return uint8(uint256(leaf) >> leafShift);\n    }\n\n    // loads a big-endian value from memory\n    function load(\n        ModuleMemory memory mem,\n        uint256 start,\n        uint256 width,\n        bytes calldata proof,\n        uint256 proofOffset\n    )\n        internal\n        pure\n        returns (\n            bool err,\n            uint256 value,\n            uint256 offset\n        )\n    {\n        if (start + width > mem.size) {\n            return (true, 0, proofOffset);\n        }\n\n        uint256 lastProvedLeafIdx = ~uint256(0);\n        bytes32 lastProvedLeafContents;\n        uint256 readValue;\n        for (uint256 i = 0; i < width; i++) {\n            uint256 idx = start + i;\n            uint256 leafIdx = idx / LEAF_SIZE;\n            if (leafIdx != lastProvedLeafIdx) {\n                (lastProvedLeafContents, proofOffset, ) = proveLeaf(\n                    mem,\n                    leafIdx,\n                    proof,\n                    proofOffset\n                );\n                lastProvedLeafIdx = leafIdx;\n            }\n            uint256 indexWithinLeaf = idx % LEAF_SIZE;\n            readValue |= uint256(pullLeafByte(lastProvedLeafContents, indexWithinLeaf)) << (i * 8);\n        }\n        return (false, readValue, proofOffset);\n    }\n}\n"
      },
      "src/state/ModuleMemoryCompact.sol": {
        "content": "// Copyright 2021-2022, Offchain Labs, Inc.\n// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE\n// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.0;\n\nstruct ModuleMemory {\n    uint64 size;\n    uint64 maxSize;\n    bytes32 merkleRoot;\n}\n\nlibrary ModuleMemoryCompactLib {\n    function hash(ModuleMemory memory mem) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(\"Memory:\", mem.size, mem.maxSize, mem.merkleRoot));\n    }\n}\n"
      },
      "src/state/MultiStack.sol": {
        "content": "// Copyright 2021-2024, Offchain Labs, Inc.\n// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE\n// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.0;\n\nstruct MultiStack {\n    bytes32 inactiveStackHash; // NO_STACK_HASH if no stack, 0 if empty stack\n    bytes32 remainingHash; // 0 if less than 2 cothreads exist\n}\n\nlibrary MultiStackLib {\n    bytes32 internal constant NO_STACK_HASH = ~bytes32(0);\n\n    function hash(\n        MultiStack memory multi,\n        bytes32 activeStackHash,\n        bool cothread\n    ) internal pure returns (bytes32) {\n        require(activeStackHash != NO_STACK_HASH, \"MULTISTACK_NOSTACK_ACTIVE\");\n        if (cothread) {\n            require(multi.inactiveStackHash != NO_STACK_HASH, \"MULTISTACK_NOSTACK_MAIN\");\n            return\n                keccak256(\n                    abi.encodePacked(\n                        \"multistack:\",\n                        multi.inactiveStackHash,\n                        activeStackHash,\n                        multi.remainingHash\n                    )\n                );\n        } else {\n            return\n                keccak256(\n                    abi.encodePacked(\n                        \"multistack:\",\n                        activeStackHash,\n                        multi.inactiveStackHash,\n                        multi.remainingHash\n                    )\n                );\n        }\n    }\n\n    function setEmpty(MultiStack memory multi) internal pure {\n        multi.inactiveStackHash = NO_STACK_HASH;\n        multi.remainingHash = 0;\n    }\n\n    function pushNew(MultiStack memory multi) internal pure {\n        if (multi.inactiveStackHash != NO_STACK_HASH) {\n            multi.remainingHash = keccak256(\n                abi.encodePacked(\"cothread:\", multi.inactiveStackHash, multi.remainingHash)\n            );\n        }\n        multi.inactiveStackHash = 0;\n    }\n}\n"
      },
      "src/state/StackFrame.sol": {
        "content": "// Copyright 2021-2023, Offchain Labs, Inc.\n// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE\n// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.0;\n\nimport \"./Value.sol\";\n\nstruct StackFrame {\n    Value returnPc;\n    bytes32 localsMerkleRoot;\n    uint32 callerModule;\n    uint32 callerModuleInternals;\n}\n\nstruct StackFrameWindow {\n    StackFrame[] proved;\n    bytes32 remainingHash;\n}\n\nlibrary StackFrameLib {\n    using ValueLib for Value;\n\n    function hash(StackFrame memory frame) internal pure returns (bytes32) {\n        return\n            keccak256(\n                abi.encodePacked(\n                    \"Stack frame:\",\n                    frame.returnPc.hash(),\n                    frame.localsMerkleRoot,\n                    frame.callerModule,\n                    frame.callerModuleInternals\n                )\n            );\n    }\n\n    function hash(StackFrameWindow memory window) internal pure returns (bytes32 h) {\n        h = window.remainingHash;\n        for (uint256 i = 0; i < window.proved.length; i++) {\n            h = keccak256(abi.encodePacked(\"Stack frame stack:\", hash(window.proved[i]), h));\n        }\n    }\n\n    function peek(StackFrameWindow memory window) internal pure returns (StackFrame memory) {\n        require(window.proved.length == 1, \"BAD_WINDOW_LENGTH\");\n        return window.proved[0];\n    }\n\n    function pop(StackFrameWindow memory window) internal pure returns (StackFrame memory frame) {\n        require(window.proved.length == 1, \"BAD_WINDOW_LENGTH\");\n        frame = window.proved[0];\n        window.proved = new StackFrame[](0);\n    }\n\n    function push(StackFrameWindow memory window, StackFrame memory frame) internal pure {\n        StackFrame[] memory newProved = new StackFrame[](window.proved.length + 1);\n        for (uint256 i = 0; i < window.proved.length; i++) {\n            newProved[i] = window.proved[i];\n        }\n        newProved[window.proved.length] = frame;\n        window.proved = newProved;\n    }\n\n    function overwrite(StackFrameWindow memory window, bytes32 root) internal pure {\n        window.remainingHash = root;\n        delete window.proved;\n    }\n}\n"
      },
      "src/state/Value.sol": {
        "content": "// Copyright 2021-2023, Offchain Labs, Inc.\n// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE\n// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.0;\n\nenum ValueType {\n    I32,\n    I64,\n    F32,\n    F64,\n    REF_NULL,\n    FUNC_REF,\n    INTERNAL_REF\n}\n\nstruct Value {\n    ValueType valueType;\n    uint256 contents;\n}\n\nlibrary ValueLib {\n    function hash(Value memory val) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(\"Value:\", val.valueType, val.contents));\n    }\n\n    function maxValueType() internal pure returns (ValueType) {\n        return ValueType.INTERNAL_REF;\n    }\n\n    function assumeI32(Value memory val) internal pure returns (uint32) {\n        uint256 uintval = uint256(val.contents);\n        require(val.valueType == ValueType.I32, \"NOT_I32\");\n        require(uintval < (1 << 32), \"BAD_I32\");\n        return uint32(uintval);\n    }\n\n    function assumeI64(Value memory val) internal pure returns (uint64) {\n        uint256 uintval = uint256(val.contents);\n        require(val.valueType == ValueType.I64, \"NOT_I64\");\n        require(uintval < (1 << 64), \"BAD_I64\");\n        return uint64(uintval);\n    }\n\n    function newRefNull() internal pure returns (Value memory) {\n        return Value({valueType: ValueType.REF_NULL, contents: 0});\n    }\n\n    function newI32(uint32 x) internal pure returns (Value memory) {\n        return Value({valueType: ValueType.I32, contents: uint256(x)});\n    }\n\n    function newI64(uint64 x) internal pure returns (Value memory) {\n        return Value({valueType: ValueType.I64, contents: uint256(x)});\n    }\n\n    function newBoolean(bool x) internal pure returns (Value memory) {\n        if (x) {\n            return newI32(uint32(1));\n        } else {\n            return newI32(uint32(0));\n        }\n    }\n\n    function newPc(\n        uint32 funcPc,\n        uint32 func,\n        uint32 module\n    ) internal pure returns (Value memory) {\n        uint256 data = 0;\n        data |= funcPc;\n        data |= uint256(func) << 32;\n        data |= uint256(module) << 64;\n        return Value({valueType: ValueType.INTERNAL_REF, contents: data});\n    }\n}\n"
      },
      "src/state/ValueArray.sol": {
        "content": "// Copyright 2021-2022, Offchain Labs, Inc.\n// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE\n// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.0;\n\nimport \"./Value.sol\";\n\nstruct ValueArray {\n    Value[] inner;\n}\n\nlibrary ValueArrayLib {\n    function get(ValueArray memory arr, uint256 index) internal pure returns (Value memory) {\n        return arr.inner[index];\n    }\n\n    function set(\n        ValueArray memory arr,\n        uint256 index,\n        Value memory val\n    ) internal pure {\n        arr.inner[index] = val;\n    }\n\n    function length(ValueArray memory arr) internal pure returns (uint256) {\n        return arr.inner.length;\n    }\n\n    function push(ValueArray memory arr, Value memory val) internal pure {\n        Value[] memory newInner = new Value[](arr.inner.length + 1);\n        for (uint256 i = 0; i < arr.inner.length; i++) {\n            newInner[i] = arr.inner[i];\n        }\n        newInner[arr.inner.length] = val;\n        arr.inner = newInner;\n    }\n\n    function pop(ValueArray memory arr) internal pure returns (Value memory popped) {\n        popped = arr.inner[arr.inner.length - 1];\n        Value[] memory newInner = new Value[](arr.inner.length - 1);\n        for (uint256 i = 0; i < newInner.length; i++) {\n            newInner[i] = arr.inner[i];\n        }\n        arr.inner = newInner;\n    }\n}\n"
      },
      "src/state/ValueStack.sol": {
        "content": "// Copyright 2021-2023, Offchain Labs, Inc.\n// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE\n// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.0;\n\nimport \"./Value.sol\";\nimport \"./ValueArray.sol\";\n\nstruct ValueStack {\n    ValueArray proved;\n    bytes32 remainingHash;\n}\n\nlibrary ValueStackLib {\n    using ValueLib for Value;\n    using ValueArrayLib for ValueArray;\n\n    function hash(ValueStack memory stack) internal pure returns (bytes32 h) {\n        h = stack.remainingHash;\n        uint256 len = stack.proved.length();\n        for (uint256 i = 0; i < len; i++) {\n            h = keccak256(abi.encodePacked(\"Value stack:\", stack.proved.get(i).hash(), h));\n        }\n    }\n\n    function peek(ValueStack memory stack) internal pure returns (Value memory) {\n        uint256 len = stack.proved.length();\n        return stack.proved.get(len - 1);\n    }\n\n    function pop(ValueStack memory stack) internal pure returns (Value memory) {\n        return stack.proved.pop();\n    }\n\n    function push(ValueStack memory stack, Value memory val) internal pure {\n        return stack.proved.push(val);\n    }\n\n    function overwrite(ValueStack memory stack, bytes32 root) internal pure {\n        stack.remainingHash = root;\n        delete stack.proved;\n    }\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 100
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "metadata": {
        "useLiteralContent": true
      },
      "libraries": {}
    }
  }}