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/OneStepProverMath.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/Module.sol\";\nimport \"../state/Deserialize.sol\";\nimport \"./IOneStepProver.sol\";\n\ncontract OneStepProverMath is IOneStepProver {\n    using ValueLib for Value;\n    using ValueStackLib for ValueStack;\n\n    function executeEqz(\n        Machine memory mach,\n        Module memory,\n        Instruction calldata inst,\n        bytes calldata\n    ) internal pure {\n        Value memory v = mach.valueStack.pop();\n        if (inst.opcode == Instructions.I32_EQZ) {\n            require(v.valueType == ValueType.I32, \"NOT_I32\");\n        } else if (inst.opcode == Instructions.I64_EQZ) {\n            require(v.valueType == ValueType.I64, \"NOT_I64\");\n        } else {\n            revert(\"BAD_EQZ\");\n        }\n\n        uint32 output;\n        if (v.contents == 0) {\n            output = 1;\n        } else {\n            output = 0;\n        }\n\n        mach.valueStack.push(ValueLib.newI32(output));\n    }\n\n    function signExtend(uint32 a) internal pure returns (uint64) {\n        if (a & (1 << 31) != 0) {\n            return uint64(a) | uint64(0xffffffff00000000);\n        }\n        return uint64(a);\n    }\n\n    function i64RelOp(\n        uint64 a,\n        uint64 b,\n        uint16 relop\n    ) internal pure returns (bool) {\n        if (relop == Instructions.IRELOP_EQ) {\n            return (a == b);\n        } else if (relop == Instructions.IRELOP_NE) {\n            return (a != b);\n        } else if (relop == Instructions.IRELOP_LT_S) {\n            return (int64(a) < int64(b));\n        } else if (relop == Instructions.IRELOP_LT_U) {\n            return (a < b);\n        } else if (relop == Instructions.IRELOP_GT_S) {\n            return (int64(a) > int64(b));\n        } else if (relop == Instructions.IRELOP_GT_U) {\n            return (a > b);\n        } else if (relop == Instructions.IRELOP_LE_S) {\n            return (int64(a) <= int64(b));\n        } else if (relop == Instructions.IRELOP_LE_U) {\n            return (a <= b);\n        } else if (relop == Instructions.IRELOP_GE_S) {\n            return (int64(a) >= int64(b));\n        } else if (relop == Instructions.IRELOP_GE_U) {\n            return (a >= b);\n        } else {\n            revert(\"BAD IRELOP\");\n        }\n    }\n\n    function executeI32RelOp(\n        Machine memory mach,\n        Module memory,\n        Instruction calldata inst,\n        bytes calldata\n    ) internal pure {\n        uint32 b = mach.valueStack.pop().assumeI32();\n        uint32 a = mach.valueStack.pop().assumeI32();\n\n        uint16 relop = inst.opcode - Instructions.I32_RELOP_BASE;\n        uint64 a64;\n        uint64 b64;\n\n        if (\n            relop == Instructions.IRELOP_LT_S ||\n            relop == Instructions.IRELOP_GT_S ||\n            relop == Instructions.IRELOP_LE_S ||\n            relop == Instructions.IRELOP_GE_S\n        ) {\n            a64 = signExtend(a);\n            b64 = signExtend(b);\n        } else {\n            a64 = uint64(a);\n            b64 = uint64(b);\n        }\n\n        bool res = i64RelOp(a64, b64, relop);\n\n        mach.valueStack.push(ValueLib.newBoolean(res));\n    }\n\n    function executeI64RelOp(\n        Machine memory mach,\n        Module memory,\n        Instruction calldata inst,\n        bytes calldata\n    ) internal pure {\n        uint64 b = mach.valueStack.pop().assumeI64();\n        uint64 a = mach.valueStack.pop().assumeI64();\n\n        uint16 relop = inst.opcode - Instructions.I64_RELOP_BASE;\n\n        bool res = i64RelOp(a, b, relop);\n\n        mach.valueStack.push(ValueLib.newBoolean(res));\n    }\n\n    function genericIUnOp(\n        uint64 a,\n        uint16 unop,\n        uint16 bits\n    ) internal pure returns (uint32) {\n        require(bits == 32 || bits == 64, \"WRONG USE OF genericUnOp\");\n        if (unop == Instructions.IUNOP_CLZ) {\n            /* curbits is one-based to keep with unsigned mathematics */\n            uint32 curbit = bits;\n            while (curbit > 0 && (a & (1 << (curbit - 1)) == 0)) {\n                curbit -= 1;\n            }\n            return (bits - curbit);\n        } else if (unop == Instructions.IUNOP_CTZ) {\n            uint32 curbit = 0;\n            while (curbit < bits && ((a & (1 << curbit)) == 0)) {\n                curbit += 1;\n            }\n            return curbit;\n        } else if (unop == Instructions.IUNOP_POPCNT) {\n            uint32 curbit = 0;\n            uint32 res = 0;\n            while (curbit < bits) {\n                if ((a & (1 << curbit)) != 0) {\n                    res += 1;\n                }\n                curbit++;\n            }\n            return res;\n        }\n        revert(\"BAD IUnOp\");\n    }\n\n    function executeI32UnOp(\n        Machine memory mach,\n        Module memory,\n        Instruction calldata inst,\n        bytes calldata\n    ) internal pure {\n        uint32 a = mach.valueStack.pop().assumeI32();\n\n        uint16 unop = inst.opcode - Instructions.I32_UNOP_BASE;\n\n        uint32 res = genericIUnOp(a, unop, 32);\n\n        mach.valueStack.push(ValueLib.newI32(res));\n    }\n\n    function executeI64UnOp(\n        Machine memory mach,\n        Module memory,\n        Instruction calldata inst,\n        bytes calldata\n    ) internal pure {\n        uint64 a = mach.valueStack.pop().assumeI64();\n\n        uint16 unop = inst.opcode - Instructions.I64_UNOP_BASE;\n\n        uint64 res = uint64(genericIUnOp(a, unop, 64));\n\n        mach.valueStack.push(ValueLib.newI64(res));\n    }\n\n    function rotl32(uint32 a, uint32 b) internal pure returns (uint32) {\n        b %= 32;\n        return (a << b) | (a >> (32 - b));\n    }\n\n    function rotl64(uint64 a, uint64 b) internal pure returns (uint64) {\n        b %= 64;\n        return (a << b) | (a >> (64 - b));\n    }\n\n    function rotr32(uint32 a, uint32 b) internal pure returns (uint32) {\n        b %= 32;\n        return (a >> b) | (a << (32 - b));\n    }\n\n    function rotr64(uint64 a, uint64 b) internal pure returns (uint64) {\n        b %= 64;\n        return (a >> b) | (a << (64 - b));\n    }\n\n    function genericBinOp(\n        uint64 a,\n        uint64 b,\n        uint16 opcodeOffset\n    ) internal pure returns (uint64, bool) {\n        unchecked {\n            if (opcodeOffset == 0) {\n                // add\n                return (a + b, false);\n            } else if (opcodeOffset == 1) {\n                // sub\n                return (a - b, false);\n            } else if (opcodeOffset == 2) {\n                // mul\n                return (a * b, false);\n            } else if (opcodeOffset == 4) {\n                // div_u\n                if (b == 0) {\n                    return (0, true);\n                }\n                return (a / b, false);\n            } else if (opcodeOffset == 6) {\n                // rem_u\n                if (b == 0) {\n                    return (0, true);\n                }\n                return (a % b, false);\n            } else if (opcodeOffset == 7) {\n                // and\n                return (a & b, false);\n            } else if (opcodeOffset == 8) {\n                // or\n                return (a | b, false);\n            } else if (opcodeOffset == 9) {\n                // xor\n                return (a ^ b, false);\n            } else {\n                revert(\"INVALID_GENERIC_BIN_OP\");\n            }\n        }\n    }\n\n    function executeI32BinOp(\n        Machine memory mach,\n        Module memory,\n        Instruction calldata inst,\n        bytes calldata\n    ) internal pure {\n        uint32 b = mach.valueStack.pop().assumeI32();\n        uint32 a = mach.valueStack.pop().assumeI32();\n        uint32 res;\n\n        uint16 opcodeOffset = inst.opcode - Instructions.I32_ADD;\n\n        unchecked {\n            if (opcodeOffset == 3) {\n                // div_s\n                if (b == 0 || (int32(a) == -2147483648 && int32(b) == -1)) {\n                    mach.status = MachineStatus.ERRORED;\n                    return;\n                }\n                res = uint32(int32(a) / int32(b));\n            } else if (opcodeOffset == 5) {\n                // rem_s\n                if (b == 0) {\n                    mach.status = MachineStatus.ERRORED;\n                    return;\n                }\n                res = uint32(int32(a) % int32(b));\n            } else if (opcodeOffset == 10) {\n                // shl\n                res = a << (b % 32);\n            } else if (opcodeOffset == 12) {\n                // shr_u\n                res = a >> (b % 32);\n            } else if (opcodeOffset == 11) {\n                // shr_s\n                res = uint32(int32(a) >> (b % 32));\n            } else if (opcodeOffset == 13) {\n                // rotl\n                res = rotl32(a, b);\n            } else if (opcodeOffset == 14) {\n                // rotr\n                res = rotr32(a, b);\n            } else {\n                (uint64 computed, bool err) = genericBinOp(a, b, opcodeOffset);\n                if (err) {\n                    mach.status = MachineStatus.ERRORED;\n                    return;\n                }\n                res = uint32(computed);\n            }\n        }\n\n        mach.valueStack.push(ValueLib.newI32(res));\n    }\n\n    function executeI64BinOp(\n        Machine memory mach,\n        Module memory,\n        Instruction calldata inst,\n        bytes calldata\n    ) internal pure {\n        uint64 b = mach.valueStack.pop().assumeI64();\n        uint64 a = mach.valueStack.pop().assumeI64();\n        uint64 res;\n\n        uint16 opcodeOffset = inst.opcode - Instructions.I64_ADD;\n\n        unchecked {\n            if (opcodeOffset == 3) {\n                // div_s\n                if (b == 0 || (int64(a) == -9223372036854775808 && int64(b) == -1)) {\n                    mach.status = MachineStatus.ERRORED;\n                    return;\n                }\n                res = uint64(int64(a) / int64(b));\n            } else if (opcodeOffset == 5) {\n                // rem_s\n                if (b == 0) {\n                    mach.status = MachineStatus.ERRORED;\n                    return;\n                }\n                res = uint64(int64(a) % int64(b));\n            } else if (opcodeOffset == 10) {\n                // shl\n                res = a << (b % 64);\n            } else if (opcodeOffset == 12) {\n                // shr_u\n                res = a >> (b % 64);\n            } else if (opcodeOffset == 11) {\n                // shr_s\n                res = uint64(int64(a) >> (b % 64));\n            } else if (opcodeOffset == 13) {\n                // rotl\n                res = rotl64(a, b);\n            } else if (opcodeOffset == 14) {\n                // rotr\n                res = rotr64(a, b);\n            } else {\n                bool err;\n                (res, err) = genericBinOp(a, b, opcodeOffset);\n                if (err) {\n                    mach.status = MachineStatus.ERRORED;\n                    return;\n                }\n            }\n        }\n\n        mach.valueStack.push(ValueLib.newI64(res));\n    }\n\n    function executeI32WrapI64(\n        Machine memory mach,\n        Module memory,\n        Instruction calldata,\n        bytes calldata\n    ) internal pure {\n        uint64 a = mach.valueStack.pop().assumeI64();\n\n        uint32 a32 = uint32(a);\n\n        mach.valueStack.push(ValueLib.newI32(a32));\n    }\n\n    function executeI64ExtendI32(\n        Machine memory mach,\n        Module memory,\n        Instruction calldata inst,\n        bytes calldata\n    ) internal pure {\n        uint32 a = mach.valueStack.pop().assumeI32();\n\n        uint64 a64;\n\n        if (inst.opcode == Instructions.I64_EXTEND_I32_S) {\n            a64 = signExtend(a);\n        } else {\n            a64 = uint64(a);\n        }\n\n        mach.valueStack.push(ValueLib.newI64(a64));\n    }\n\n    function executeExtendSameType(\n        Machine memory mach,\n        Module memory,\n        Instruction calldata inst,\n        bytes calldata\n    ) internal pure {\n        ValueType ty;\n        uint8 sourceBits;\n        if (inst.opcode == Instructions.I32_EXTEND_8S) {\n            ty = ValueType.I32;\n            sourceBits = 8;\n        } else if (inst.opcode == Instructions.I32_EXTEND_16S) {\n            ty = ValueType.I32;\n            sourceBits = 16;\n        } else if (inst.opcode == Instructions.I64_EXTEND_8S) {\n            ty = ValueType.I64;\n            sourceBits = 8;\n        } else if (inst.opcode == Instructions.I64_EXTEND_16S) {\n            ty = ValueType.I64;\n            sourceBits = 16;\n        } else if (inst.opcode == Instructions.I64_EXTEND_32S) {\n            ty = ValueType.I64;\n            sourceBits = 32;\n        } else {\n            revert(\"INVALID_EXTEND_SAME_TYPE\");\n        }\n        uint256 resultMask;\n        if (ty == ValueType.I32) {\n            resultMask = (1 << 32) - 1;\n        } else {\n            resultMask = (1 << 64) - 1;\n        }\n        Value memory val = mach.valueStack.pop();\n        require(val.valueType == ty, \"BAD_EXTEND_SAME_TYPE_TYPE\");\n        uint256 sourceMask = (1 << sourceBits) - 1;\n        val.contents &= sourceMask;\n        if (val.contents & (1 << (sourceBits - 1)) != 0) {\n            // Extend sign flag\n            val.contents |= resultMask & ~sourceMask;\n        }\n        mach.valueStack.push(val);\n    }\n\n    function executeReinterpret(\n        Machine memory mach,\n        Module memory,\n        Instruction calldata inst,\n        bytes calldata\n    ) internal pure {\n        ValueType destTy;\n        ValueType sourceTy;\n        if (inst.opcode == Instructions.I32_REINTERPRET_F32) {\n            destTy = ValueType.I32;\n            sourceTy = ValueType.F32;\n        } else if (inst.opcode == Instructions.I64_REINTERPRET_F64) {\n            destTy = ValueType.I64;\n            sourceTy = ValueType.F64;\n        } else if (inst.opcode == Instructions.F32_REINTERPRET_I32) {\n            destTy = ValueType.F32;\n            sourceTy = ValueType.I32;\n        } else if (inst.opcode == Instructions.F64_REINTERPRET_I64) {\n            destTy = ValueType.F64;\n            sourceTy = ValueType.I64;\n        } else {\n            revert(\"INVALID_REINTERPRET\");\n        }\n        Value memory val = mach.valueStack.pop();\n        require(val.valueType == sourceTy, \"INVALID_REINTERPRET_TYPE\");\n        val.valueType = destTy;\n        mach.valueStack.push(val);\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_EQZ || opcode == Instructions.I64_EQZ) {\n            impl = executeEqz;\n        } else if (\n            opcode >= Instructions.I32_RELOP_BASE &&\n            opcode <= Instructions.I32_RELOP_BASE + Instructions.IRELOP_LAST\n        ) {\n            impl = executeI32RelOp;\n        } else if (\n            opcode >= Instructions.I32_UNOP_BASE &&\n            opcode <= Instructions.I32_UNOP_BASE + Instructions.IUNOP_LAST\n        ) {\n            impl = executeI32UnOp;\n        } else if (opcode >= Instructions.I32_ADD && opcode <= Instructions.I32_ROTR) {\n            impl = executeI32BinOp;\n        } else if (\n            opcode >= Instructions.I64_RELOP_BASE &&\n            opcode <= Instructions.I64_RELOP_BASE + Instructions.IRELOP_LAST\n        ) {\n            impl = executeI64RelOp;\n        } else if (\n            opcode >= Instructions.I64_UNOP_BASE &&\n            opcode <= Instructions.I64_UNOP_BASE + Instructions.IUNOP_LAST\n        ) {\n            impl = executeI64UnOp;\n        } else if (opcode >= Instructions.I64_ADD && opcode <= Instructions.I64_ROTR) {\n            impl = executeI64BinOp;\n        } else if (opcode == Instructions.I32_WRAP_I64) {\n            impl = executeI32WrapI64;\n        } else if (\n            opcode == Instructions.I64_EXTEND_I32_S || opcode == Instructions.I64_EXTEND_I32_U\n        ) {\n            impl = executeI64ExtendI32;\n        } else if (opcode >= Instructions.I32_EXTEND_8S && opcode <= Instructions.I64_EXTEND_32S) {\n            impl = executeExtendSameType;\n        } else if (\n            opcode >= Instructions.I32_REINTERPRET_F32 && opcode <= Instructions.F64_REINTERPRET_I64\n        ) {\n            impl = executeReinterpret;\n        } else {\n            revert(\"INVALID_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 \"./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 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 instruction(bytes calldata proof, uint256 startOffset)\n        internal\n        pure\n        returns (Instruction memory inst, uint256 offset)\n    {\n        offset = startOffset;\n        uint16 opcode;\n        uint256 data;\n        (opcode, offset) = u16(proof, offset);\n        (data, offset) = u256(proof, offset);\n        inst = Instruction({opcode: opcode, argumentData: data});\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        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        (internalsOffset, offset) = u32(proof, offset);\n        mod = Module({\n            globalsMerkleRoot: globalsMerkleRoot,\n            moduleMemory: mem,\n            tablesMerkleRoot: tablesMerkleRoot,\n            functionsMerkleRoot: functionsMerkleRoot,\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        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        bytes32 globalStateHash;\n        uint32 moduleIdx;\n        uint32 functionIdx;\n        uint32 functionPc;\n        StackFrameWindow memory frameStack;\n        bytes32 modulesRoot;\n        (values, offset) = valueStack(proof, offset);\n        (internalStack, offset) = valueStack(proof, offset);\n        (frameStack, offset) = stackFrameWindow(proof, offset);\n        (globalStateHash, offset) = b32(proof, offset);\n        (moduleIdx, offset) = u32(proof, offset);\n        (functionIdx, offset) = u32(proof, offset);\n        (functionPc, offset) = u32(proof, offset);\n        (modulesRoot, offset) = b32(proof, offset);\n        mach = Machine({\n            status: status,\n            valueStack: values,\n            internalStack: internalStack,\n            frameStack: frameStack,\n            globalStateHash: globalStateHash,\n            moduleIdx: moduleIdx,\n            functionIdx: functionIdx,\n            functionPc: functionPc,\n            modulesRoot: modulesRoot\n        });\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-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 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\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\n    uint256 internal constant INBOX_INDEX_SEQUENCER = 0;\n    uint256 internal constant INBOX_INDEX_DELAYED = 1;\n\n    function hash(Instruction memory inst) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(\"Instruction:\", inst.opcode, inst.argumentData));\n    }\n}\n"
      },
      "src/state/Machine.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 \"./ValueStack.sol\";\nimport \"./Instructions.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    ValueStack internalStack;\n    StackFrameWindow frameStack;\n    bytes32 globalStateHash;\n    uint32 moduleIdx;\n    uint32 functionIdx;\n    uint32 functionPc;\n    bytes32 modulesRoot;\n}\n\nlibrary MachineLib {\n    using StackFrameLib for StackFrameWindow;\n    using ValueStackLib for ValueStack;\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            return\n                keccak256(\n                    abi.encodePacked(\n                        \"Machine running:\",\n                        mach.valueStack.hash(),\n                        mach.internalStack.hash(),\n                        mach.frameStack.hash(),\n                        mach.globalStateHash,\n                        mach.moduleIdx,\n                        mach.functionIdx,\n                        mach.functionPc,\n                        mach.modulesRoot\n                    )\n                );\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"
      },
      "src/state/MerkleProof.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 \"./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 computeRootFromInstruction(\n        MerkleProof memory proof,\n        uint256 index,\n        Instruction memory inst\n    ) internal pure returns (bytes32) {\n        return computeRootUnsafe(proof, index, Instructions.hash(inst), \"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    }\n}\n"
      },
      "src/state/Module.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 \"./ModuleMemoryCompact.sol\";\n\nstruct Module {\n    bytes32 globalsMerkleRoot;\n    ModuleMemory moduleMemory;\n    bytes32 tablesMerkleRoot;\n    bytes32 functionsMerkleRoot;\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.internalsOffset\n                )\n            );\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/StackFrame.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 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"
      },
      "src/state/Value.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\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"
      },
      "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-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 \"./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"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 100
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "metadata": {
        "useLiteralContent": true
      },
      "libraries": {}
    }
  }}