Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Name:
OneStepProverHostIo
Compiler Version
v0.8.9+commit.e5eed63a
Optimization Enabled:
Yes with 100 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// Copyright 2021-2024, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "../state/Value.sol"; import "../state/Machine.sol"; import "../state/MerkleProof.sol"; import "../state/MultiStack.sol"; import "../state/Deserialize.sol"; import "../state/ModuleMemory.sol"; import "./IOneStepProver.sol"; import "../bridge/Messages.sol"; import "../bridge/IBridge.sol"; contract OneStepProverHostIo is IOneStepProver { using GlobalStateLib for GlobalState; using MachineLib for Machine; using MerkleProofLib for MerkleProof; using ModuleMemoryLib for ModuleMemory; using MultiStackLib for MultiStack; using ValueLib for Value; using ValueStackLib for ValueStack; using StackFrameLib for StackFrameWindow; uint256 private constant LEAF_SIZE = 32; uint256 private constant INBOX_NUM = 2; uint64 private constant INBOX_HEADER_LEN = 40; uint64 private constant DELAYED_HEADER_LEN = 112 + 1; function setLeafByte( bytes32 oldLeaf, uint256 idx, uint8 val ) internal pure returns (bytes32) { require(idx < LEAF_SIZE, "BAD_SET_LEAF_BYTE_IDX"); // Take into account that we are casting the leaf to a big-endian integer uint256 leafShift = (LEAF_SIZE - 1 - idx) * 8; uint256 newLeaf = uint256(oldLeaf); newLeaf &= ~(0xFF << leafShift); newLeaf |= uint256(val) << leafShift; return bytes32(newLeaf); } function executeGetOrSetBytes32( Machine memory mach, Module memory mod, GlobalState memory state, Instruction calldata inst, bytes calldata proof ) internal pure { uint256 ptr = mach.valueStack.pop().assumeI32(); uint32 idx = mach.valueStack.pop().assumeI32(); if (idx >= GlobalStateLib.BYTES32_VALS_NUM) { mach.status = MachineStatus.ERRORED; return; } if (!mod.moduleMemory.isValidLeaf(ptr)) { mach.status = MachineStatus.ERRORED; return; } uint256 leafIdx = ptr / LEAF_SIZE; uint256 proofOffset = 0; bytes32 startLeafContents; MerkleProof memory merkleProof; (startLeafContents, proofOffset, merkleProof) = mod.moduleMemory.proveLeaf( leafIdx, proof, proofOffset ); if (inst.opcode == Instructions.GET_GLOBAL_STATE_BYTES32) { mod.moduleMemory.merkleRoot = merkleProof.computeRootFromMemory( leafIdx, state.bytes32Vals[idx] ); } else if (inst.opcode == Instructions.SET_GLOBAL_STATE_BYTES32) { state.bytes32Vals[idx] = startLeafContents; } else { revert("BAD_GLOBAL_STATE_OPCODE"); } } function executeGetU64(Machine memory mach, GlobalState memory state) internal pure { uint32 idx = mach.valueStack.pop().assumeI32(); if (idx >= GlobalStateLib.U64_VALS_NUM) { mach.status = MachineStatus.ERRORED; return; } mach.valueStack.push(ValueLib.newI64(state.u64Vals[idx])); } function executeSetU64(Machine memory mach, GlobalState memory state) internal pure { uint64 val = mach.valueStack.pop().assumeI64(); uint32 idx = mach.valueStack.pop().assumeI32(); if (idx >= GlobalStateLib.U64_VALS_NUM) { mach.status = MachineStatus.ERRORED; return; } state.u64Vals[idx] = val; } uint256 internal constant BLS_MODULUS = 52435875175126190479447740508185965837690552500527637822603658699938581184513; uint256 internal constant PRIMITIVE_ROOT_OF_UNITY = 10238227357739495823651030575849232062558860180284477541189508159991286009131; // Computes b**e % m // Really pure but the Solidity compiler sees the staticcall and requires view function modExp256( uint256 b, uint256 e, uint256 m ) internal view returns (uint256) { bytes memory modExpInput = abi.encode(32, 32, 32, b, e, m); (bool modexpSuccess, bytes memory modExpOutput) = address(0x05).staticcall(modExpInput); require(modexpSuccess, "MODEXP_FAILED"); require(modExpOutput.length == 32, "MODEXP_WRONG_LENGTH"); return uint256(bytes32(modExpOutput)); } function executeReadPreImage( ExecutionContext calldata, Machine memory mach, Module memory mod, Instruction calldata inst, bytes calldata proof ) internal view { uint256 preimageOffset = mach.valueStack.pop().assumeI32(); uint256 ptr = mach.valueStack.pop().assumeI32(); if (preimageOffset % 32 != 0 || ptr + 32 > mod.moduleMemory.size || ptr % LEAF_SIZE != 0) { mach.status = MachineStatus.ERRORED; return; } uint256 leafIdx = ptr / LEAF_SIZE; uint256 proofOffset = 0; bytes32 leafContents; MerkleProof memory merkleProof; (leafContents, proofOffset, merkleProof) = mod.moduleMemory.proveLeaf( leafIdx, proof, proofOffset ); bytes memory extracted; uint8 proofType = uint8(proof[proofOffset]); proofOffset++; // These values must be kept in sync with `arbitrator/arbutil/src/types.rs` // and `arbutil/preimage_type.go` (both in the nitro repo). if (inst.argumentData == 0) { // The machine is asking for a keccak256 preimage if (proofType == 0) { bytes calldata preimage = proof[proofOffset:]; require(keccak256(preimage) == leafContents, "BAD_PREIMAGE"); uint256 preimageEnd = preimageOffset + 32; if (preimageEnd > preimage.length) { preimageEnd = preimage.length; } extracted = preimage[preimageOffset:preimageEnd]; } else { // TODO: support proving via an authenticated contract revert("UNKNOWN_PREIMAGE_PROOF"); } } else if (inst.argumentData == 1) { // The machine is asking for a sha2-256 preimage require(proofType == 0, "UNKNOWN_PREIMAGE_PROOF"); bytes calldata preimage = proof[proofOffset:]; require(sha256(preimage) == leafContents, "BAD_PREIMAGE"); uint256 preimageEnd = preimageOffset + 32; if (preimageEnd > preimage.length) { preimageEnd = preimage.length; } extracted = preimage[preimageOffset:preimageEnd]; } else if (inst.argumentData == 2) { // The machine is asking for an Ethereum versioned hash preimage require(proofType == 0, "UNKNOWN_PREIMAGE_PROOF"); // kzgProof should be a valid input to the EIP-4844 point evaluation precompile at address 0x0A. // It should prove the preimageOffset/32'th word of the machine's requested KZG commitment. bytes calldata kzgProof = proof[proofOffset:]; require(bytes32(kzgProof[:32]) == leafContents, "KZG_PROOF_WRONG_HASH"); uint256 fieldElementsPerBlob; uint256 blsModulus; { (bool success, bytes memory kzgParams) = address(0x0A).staticcall(kzgProof); require(success, "INVALID_KZG_PROOF"); require(kzgParams.length > 0, "KZG_PRECOMPILE_MISSING"); (fieldElementsPerBlob, blsModulus) = abi.decode(kzgParams, (uint256, uint256)); } // With a hardcoded PRIMITIVE_ROOT_OF_UNITY, we can only support this BLS modulus. // It may be worth in the future supporting arbitrary BLS moduli, but we would likely need to // validate a user-supplied root of unity. require(blsModulus == BLS_MODULUS, "UNKNOWN_BLS_MODULUS"); // If preimageOffset is greater than or equal to the blob size, leave extracted empty and call it here. if (preimageOffset < fieldElementsPerBlob * 32) { // We need to compute what point the polynomial should be evaluated at to get the right part of the preimage. // KZG commitments use a bit reversal permutation to order the roots of unity. // To account for that, we reverse the bit order of the index. uint256 bitReversedIndex = 0; // preimageOffset was required to be 32 byte aligned above uint256 tmp = preimageOffset / 32; for (uint256 i = 1; i < fieldElementsPerBlob; i <<= 1) { bitReversedIndex <<= 1; if (tmp & 1 == 1) { bitReversedIndex |= 1; } tmp >>= 1; } // First, we get the root of unity of order 2**fieldElementsPerBlob. // We start with a root of unity of order 2**32 and then raise it to // the power of (2**32)/fieldElementsPerBlob to get root of unity we need. uint256 rootOfUnityPower = (1 << 32) / fieldElementsPerBlob; // Then, we raise the root of unity to the power of bitReversedIndex, // to retrieve this word of the KZG commitment. rootOfUnityPower *= bitReversedIndex; // z is the point the polynomial is evaluated at to retrieve this word of data uint256 z = modExp256(PRIMITIVE_ROOT_OF_UNITY, rootOfUnityPower, blsModulus); require(bytes32(kzgProof[32:64]) == bytes32(z), "KZG_PROOF_WRONG_Z"); extracted = kzgProof[64:96]; } } else { revert("UNKNOWN_PREIMAGE_TYPE"); } for (uint256 i = 0; i < extracted.length; i++) { leafContents = setLeafByte(leafContents, i, uint8(extracted[i])); } mod.moduleMemory.merkleRoot = merkleProof.computeRootFromMemory(leafIdx, leafContents); mach.valueStack.push(ValueLib.newI32(uint32(extracted.length))); } function validateSequencerInbox( ExecutionContext calldata execCtx, uint64 msgIndex, bytes calldata message ) internal view returns (bool) { require(message.length >= INBOX_HEADER_LEN, "BAD_SEQINBOX_PROOF"); uint64 afterDelayedMsg; (afterDelayedMsg, ) = Deserialize.u64(message, 32); bytes32 messageHash = keccak256(message); bytes32 beforeAcc; bytes32 delayedAcc; if (msgIndex > 0) { beforeAcc = execCtx.bridge.sequencerInboxAccs(msgIndex - 1); } if (afterDelayedMsg > 0) { delayedAcc = execCtx.bridge.delayedInboxAccs(afterDelayedMsg - 1); } bytes32 acc = keccak256(abi.encodePacked(beforeAcc, messageHash, delayedAcc)); require(acc == execCtx.bridge.sequencerInboxAccs(msgIndex), "BAD_SEQINBOX_MESSAGE"); return true; } function validateDelayedInbox( ExecutionContext calldata execCtx, uint64 msgIndex, bytes calldata message ) internal view returns (bool) { require(message.length >= DELAYED_HEADER_LEN, "BAD_DELAYED_PROOF"); bytes32 beforeAcc; if (msgIndex > 0) { beforeAcc = execCtx.bridge.delayedInboxAccs(msgIndex - 1); } bytes32 messageDataHash = keccak256(message[DELAYED_HEADER_LEN:]); bytes1 kind = message[0]; uint256 sender; (sender, ) = Deserialize.u256(message, 1); bytes32 messageHash = keccak256( abi.encodePacked(kind, uint160(sender), message[33:DELAYED_HEADER_LEN], messageDataHash) ); bytes32 acc = Messages.accumulateInboxMessage(beforeAcc, messageHash); require(acc == execCtx.bridge.delayedInboxAccs(msgIndex), "BAD_DELAYED_MESSAGE"); return true; } function executeReadInboxMessage( ExecutionContext calldata execCtx, Machine memory mach, Module memory mod, Instruction calldata inst, bytes calldata proof ) internal view { uint256 messageOffset = mach.valueStack.pop().assumeI32(); uint256 ptr = mach.valueStack.pop().assumeI32(); uint256 msgIndex = mach.valueStack.pop().assumeI64(); if ( inst.argumentData == Instructions.INBOX_INDEX_SEQUENCER && msgIndex >= execCtx.maxInboxMessagesRead ) { mach.status = MachineStatus.TOO_FAR; return; } if (ptr + 32 > mod.moduleMemory.size || ptr % LEAF_SIZE != 0) { mach.status = MachineStatus.ERRORED; return; } uint256 leafIdx = ptr / LEAF_SIZE; uint256 proofOffset = 0; bytes32 leafContents; MerkleProof memory merkleProof; (leafContents, proofOffset, merkleProof) = mod.moduleMemory.proveLeaf( leafIdx, proof, proofOffset ); { // TODO: support proving via an authenticated contract require(proof[proofOffset] == 0, "UNKNOWN_INBOX_PROOF"); proofOffset++; function(ExecutionContext calldata, uint64, bytes calldata) internal view returns (bool) inboxValidate; bool success; if (inst.argumentData == Instructions.INBOX_INDEX_SEQUENCER) { inboxValidate = validateSequencerInbox; } else if (inst.argumentData == Instructions.INBOX_INDEX_DELAYED) { inboxValidate = validateDelayedInbox; } else { mach.status = MachineStatus.ERRORED; return; } success = inboxValidate(execCtx, uint64(msgIndex), proof[proofOffset:]); if (!success) { mach.status = MachineStatus.ERRORED; return; } } require(proof.length >= proofOffset, "BAD_MESSAGE_PROOF"); uint256 messageLength = proof.length - proofOffset; uint32 i = 0; for (; i < 32 && messageOffset + i < messageLength; i++) { leafContents = setLeafByte( leafContents, i, uint8(proof[proofOffset + messageOffset + i]) ); } mod.moduleMemory.merkleRoot = merkleProof.computeRootFromMemory(leafIdx, leafContents); mach.valueStack.push(ValueLib.newI32(i)); } function executeHaltAndSetFinished( ExecutionContext calldata, Machine memory mach, Module memory, Instruction calldata, bytes calldata ) internal pure { mach.status = MachineStatus.FINISHED; } function isPowerOfTwo(uint256 value) internal pure returns (bool) { return value != 0 && (value & (value - 1) == 0); } function proveLastLeaf( Machine memory mach, uint256 offset, bytes calldata proof ) internal pure returns ( uint256 leaf, MerkleProof memory leafProof, MerkleProof memory zeroProof ) { string memory prefix = "Module merkle tree:"; bytes32 root = mach.modulesRoot; { Module memory leafModule; uint32 leaf32; (leafModule, offset) = Deserialize.module(proof, offset); (leaf32, offset) = Deserialize.u32(proof, offset); (leafProof, offset) = Deserialize.merkleProof(proof, offset); leaf = uint256(leaf32); bytes32 compRoot = leafProof.computeRootFromModule(leaf, leafModule); require(compRoot == root, "WRONG_ROOT_FOR_LEAF"); } // if tree is unbalanced, check that the next leaf is 0 bool balanced = isPowerOfTwo(leaf + 1); if (balanced) { require(1 << leafProof.counterparts.length == leaf + 1, "WRONG_LEAF"); } else { (zeroProof, offset) = Deserialize.merkleProof(proof, offset); bytes32 compRoot = zeroProof.computeRootUnsafe(leaf + 1, 0, prefix); require(compRoot == root, "WRONG_ROOT_FOR_ZERO"); } return (leaf, leafProof, zeroProof); } function executeLinkModule( ExecutionContext calldata, Machine memory mach, Module memory mod, Instruction calldata, bytes calldata proof ) internal pure { string memory prefix = "Module merkle tree:"; bytes32 root = mach.modulesRoot; uint256 pointer = mach.valueStack.pop().assumeI32(); if (!mod.moduleMemory.isValidLeaf(pointer)) { mach.status = MachineStatus.ERRORED; return; } (bytes32 userMod, uint256 offset, ) = mod.moduleMemory.proveLeaf( pointer / LEAF_SIZE, proof, 0 ); (uint256 leaf, , MerkleProof memory zeroProof) = proveLastLeaf(mach, offset, proof); bool balanced = isPowerOfTwo(leaf + 1); if (balanced) { mach.modulesRoot = MerkleProofLib.growToNewRoot(root, leaf + 1, userMod, 0, prefix); } else { mach.modulesRoot = zeroProof.computeRootUnsafe(leaf + 1, userMod, prefix); } mach.valueStack.push(ValueLib.newI32(uint32(leaf + 1))); } function executeUnlinkModule( ExecutionContext calldata, Machine memory mach, Module memory, Instruction calldata, bytes calldata proof ) internal pure { string memory prefix = "Module merkle tree:"; (uint256 leaf, MerkleProof memory leafProof, ) = proveLastLeaf(mach, 0, proof); bool shrink = isPowerOfTwo(leaf); if (shrink) { mach.modulesRoot = leafProof.counterparts[leafProof.counterparts.length - 1]; } else { mach.modulesRoot = leafProof.computeRootUnsafe(leaf, 0, prefix); } } function executeGlobalStateAccess( ExecutionContext calldata, Machine memory mach, Module memory mod, Instruction calldata inst, bytes calldata proof ) internal pure { uint16 opcode = inst.opcode; GlobalState memory state; uint256 proofOffset = 0; (state, proofOffset) = Deserialize.globalState(proof, proofOffset); require(state.hash() == mach.globalStateHash, "BAD_GLOBAL_STATE"); if ( opcode == Instructions.GET_GLOBAL_STATE_BYTES32 || opcode == Instructions.SET_GLOBAL_STATE_BYTES32 ) { executeGetOrSetBytes32(mach, mod, state, inst, proof[proofOffset:]); } else if (opcode == Instructions.GET_GLOBAL_STATE_U64) { executeGetU64(mach, state); } else if (opcode == Instructions.SET_GLOBAL_STATE_U64) { executeSetU64(mach, state); } else { revert("INVALID_GLOBALSTATE_OPCODE"); } mach.globalStateHash = state.hash(); } function executeNewCoThread( ExecutionContext calldata, Machine memory mach, Module memory, Instruction calldata, bytes calldata ) internal pure { if (mach.recoveryPc != MachineLib.NO_RECOVERY_PC) { // cannot create new cothread from inside cothread mach.status = MachineStatus.ERRORED; return; } mach.frameMultiStack.pushNew(); mach.valueMultiStack.pushNew(); } function provePopCothread(MultiStack memory multi, bytes calldata proof) internal pure { uint256 proofOffset = 0; bytes32 newInactiveCoThread; bytes32 newRemaining; (newInactiveCoThread, proofOffset) = Deserialize.b32(proof, proofOffset); (newRemaining, proofOffset) = Deserialize.b32(proof, proofOffset); if (newInactiveCoThread == MultiStackLib.NO_STACK_HASH) { require(newRemaining == bytes32(0), "WRONG_COTHREAD_EMPTY"); require(multi.remainingHash == bytes32(0), "WRONG_COTHREAD_EMPTY"); } else { require( keccak256(abi.encodePacked("cothread:", newInactiveCoThread, newRemaining)) == multi.remainingHash, "WRONG_COTHREAD_POP" ); } multi.remainingHash = newRemaining; multi.inactiveStackHash = newInactiveCoThread; } function executePopCoThread( ExecutionContext calldata, Machine memory mach, Module memory, Instruction calldata, bytes calldata proof ) internal pure { if (mach.recoveryPc != MachineLib.NO_RECOVERY_PC) { // cannot pop cothread from inside cothread mach.status = MachineStatus.ERRORED; return; } if (mach.frameMultiStack.inactiveStackHash == MultiStackLib.NO_STACK_HASH) { // cannot pop cothread if there isn't one mach.status = MachineStatus.ERRORED; return; } provePopCothread(mach.valueMultiStack, proof); provePopCothread(mach.frameMultiStack, proof[64:]); } function executeSwitchCoThread( ExecutionContext calldata, Machine memory mach, Module memory, Instruction calldata inst, bytes calldata ) internal pure { if (mach.frameMultiStack.inactiveStackHash == MultiStackLib.NO_STACK_HASH) { // cannot switch cothread if there isn't one mach.status = MachineStatus.ERRORED; return; } if (inst.argumentData == 0) { if (mach.recoveryPc == MachineLib.NO_RECOVERY_PC) { // switching to main thread, from main thread mach.status = MachineStatus.ERRORED; return; } mach.recoveryPc = MachineLib.NO_RECOVERY_PC; } else { if (mach.recoveryPc != MachineLib.NO_RECOVERY_PC) { // switching from cothread to cothread mach.status = MachineStatus.ERRORED; return; } mach.setRecoveryFromPc(uint32(inst.argumentData)); } mach.switchCoThreadStacks(); } function executeOneStep( ExecutionContext calldata execCtx, Machine calldata startMach, Module calldata startMod, Instruction calldata inst, bytes calldata proof ) external view override returns (Machine memory mach, Module memory mod) { mach = startMach; mod = startMod; uint16 opcode = inst.opcode; function( ExecutionContext calldata, Machine memory, Module memory, Instruction calldata, bytes calldata ) internal view impl; if ( opcode >= Instructions.GET_GLOBAL_STATE_BYTES32 && opcode <= Instructions.SET_GLOBAL_STATE_U64 ) { impl = executeGlobalStateAccess; } else if (opcode == Instructions.READ_PRE_IMAGE) { impl = executeReadPreImage; } else if (opcode == Instructions.READ_INBOX_MESSAGE) { impl = executeReadInboxMessage; } else if (opcode == Instructions.HALT_AND_SET_FINISHED) { impl = executeHaltAndSetFinished; } else if (opcode == Instructions.LINK_MODULE) { impl = executeLinkModule; } else if (opcode == Instructions.UNLINK_MODULE) { impl = executeUnlinkModule; } else if (opcode == Instructions.NEW_COTHREAD) { impl = executeNewCoThread; } else if (opcode == Instructions.POP_COTHREAD) { impl = executePopCoThread; } else if (opcode == Instructions.SWITCH_COTHREAD) { impl = executeSwitchCoThread; } else { revert("INVALID_MEMORY_OPCODE"); } impl(execCtx, mach, mod, inst, proof); } }
// Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 // solhint-disable-next-line compiler-version pragma solidity >=0.6.9 <0.9.0; import "./IOwnable.sol"; interface IBridge { /// @dev This is an instruction to offchain readers to inform them where to look /// for sequencer inbox batch data. This is not the type of data (eg. das, brotli encoded, or blob versioned hash) /// and this enum is not used in the state transition function, rather it informs an offchain /// reader where to find the data so that they can supply it to the replay binary enum BatchDataLocation { /// @notice The data can be found in the transaction call data TxInput, /// @notice The data can be found in an event emitted during the transaction SeparateBatchEvent, /// @notice This batch contains no data NoData, /// @notice The data can be found in the 4844 data blobs on this transaction Blob } struct TimeBounds { uint64 minTimestamp; uint64 maxTimestamp; uint64 minBlockNumber; uint64 maxBlockNumber; } event MessageDelivered( uint256 indexed messageIndex, bytes32 indexed beforeInboxAcc, address inbox, uint8 kind, address sender, bytes32 messageDataHash, uint256 baseFeeL1, uint64 timestamp ); event BridgeCallTriggered( address indexed outbox, address indexed to, uint256 value, bytes data ); event InboxToggle(address indexed inbox, bool enabled); event OutboxToggle(address indexed outbox, bool enabled); event SequencerInboxUpdated(address newSequencerInbox); event RollupUpdated(address rollup); function allowedDelayedInboxList(uint256) external returns (address); function allowedOutboxList(uint256) external returns (address); /// @dev Accumulator for delayed inbox messages; tail represents hash of the current state; each element represents the inclusion of a new message. function delayedInboxAccs(uint256) external view returns (bytes32); /// @dev Accumulator for sequencer inbox messages; tail represents hash of the current state; each element represents the inclusion of a new message. function sequencerInboxAccs(uint256) external view returns (bytes32); function rollup() external view returns (IOwnable); function sequencerInbox() external view returns (address); function activeOutbox() external view returns (address); function allowedDelayedInboxes(address inbox) external view returns (bool); function allowedOutboxes(address outbox) external view returns (bool); function sequencerReportedSubMessageCount() external view returns (uint256); function executeCall( address to, uint256 value, bytes calldata data ) external returns (bool success, bytes memory returnData); function delayedMessageCount() external view returns (uint256); function sequencerMessageCount() external view returns (uint256); // ---------- onlySequencerInbox functions ---------- function enqueueSequencerMessage( bytes32 dataHash, uint256 afterDelayedMessagesRead, uint256 prevMessageCount, uint256 newMessageCount ) external returns ( uint256 seqMessageIndex, bytes32 beforeAcc, bytes32 delayedAcc, bytes32 acc ); /** * @dev Allows the sequencer inbox to submit a delayed message of the batchPostingReport type * This is done through a separate function entrypoint instead of allowing the sequencer inbox * to call `enqueueDelayedMessage` to avoid the gas overhead of an extra SLOAD in either * every delayed inbox or every sequencer inbox call. */ function submitBatchSpendingReport(address batchPoster, bytes32 dataHash) external returns (uint256 msgNum); // ---------- onlyRollupOrOwner functions ---------- function setSequencerInbox(address _sequencerInbox) external; function setDelayedInbox(address inbox, bool enabled) external; function setOutbox(address inbox, bool enabled) external; function updateRollupAddress(IOwnable _rollup) external; }
// Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 // solhint-disable-next-line compiler-version pragma solidity >=0.6.9 <0.9.0; interface IDelayedMessageProvider { /// @dev event emitted when a inbox message is added to the Bridge's delayed accumulator event InboxMessageDelivered(uint256 indexed messageNum, bytes data); /// @dev event emitted when a inbox message is added to the Bridge's delayed accumulator /// same as InboxMessageDelivered but the batch data is available in tx.input event InboxMessageDeliveredFromOrigin(uint256 indexed messageNum); }
// Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 // solhint-disable-next-line compiler-version pragma solidity >=0.4.21 <0.9.0; interface IOwnable { function owner() external view returns (address); }
// Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 // solhint-disable-next-line compiler-version pragma solidity >=0.6.9 <0.9.0; pragma experimental ABIEncoderV2; import "../libraries/IGasRefunder.sol"; import "./IDelayedMessageProvider.sol"; import "./IBridge.sol"; interface ISequencerInbox is IDelayedMessageProvider { struct MaxTimeVariation { uint256 delayBlocks; uint256 futureBlocks; uint256 delaySeconds; uint256 futureSeconds; } event SequencerBatchDelivered( uint256 indexed batchSequenceNumber, bytes32 indexed beforeAcc, bytes32 indexed afterAcc, bytes32 delayedAcc, uint256 afterDelayedMessagesRead, IBridge.TimeBounds timeBounds, IBridge.BatchDataLocation dataLocation ); event OwnerFunctionCalled(uint256 indexed id); /// @dev a separate event that emits batch data when this isn't easily accessible in the tx.input event SequencerBatchData(uint256 indexed batchSequenceNumber, bytes data); /// @dev a valid keyset was added event SetValidKeyset(bytes32 indexed keysetHash, bytes keysetBytes); /// @dev a keyset was invalidated event InvalidateKeyset(bytes32 indexed keysetHash); function totalDelayedMessagesRead() external view returns (uint256); function bridge() external view returns (IBridge); /// @dev The size of the batch header // solhint-disable-next-line func-name-mixedcase function HEADER_LENGTH() external view returns (uint256); /// @dev If the first batch data byte after the header has this bit set, /// the sequencer inbox has authenticated the data. Currently only used for 4844 blob support. /// See: https://github.com/OffchainLabs/nitro/blob/69de0603abf6f900a4128cab7933df60cad54ded/arbstate/das_reader.go // solhint-disable-next-line func-name-mixedcase function DATA_AUTHENTICATED_FLAG() external view returns (bytes1); /// @dev If the first data byte after the header has this bit set, /// then the batch data is to be found in 4844 data blobs /// See: https://github.com/OffchainLabs/nitro/blob/69de0603abf6f900a4128cab7933df60cad54ded/arbstate/das_reader.go // solhint-disable-next-line func-name-mixedcase function DATA_BLOB_HEADER_FLAG() external view returns (bytes1); /// @dev If the first data byte after the header has this bit set, /// then the batch data is a das message /// See: https://github.com/OffchainLabs/nitro/blob/69de0603abf6f900a4128cab7933df60cad54ded/arbstate/das_reader.go // solhint-disable-next-line func-name-mixedcase function DAS_MESSAGE_HEADER_FLAG() external view returns (bytes1); /// @dev If the first data byte after the header has this bit set, /// then the batch data is a das message that employs a merklesization strategy /// See: https://github.com/OffchainLabs/nitro/blob/69de0603abf6f900a4128cab7933df60cad54ded/arbstate/das_reader.go // solhint-disable-next-line func-name-mixedcase function TREE_DAS_MESSAGE_HEADER_FLAG() external view returns (bytes1); /// @dev If the first data byte after the header has this bit set, /// then the batch data has been brotli compressed /// See: https://github.com/OffchainLabs/nitro/blob/69de0603abf6f900a4128cab7933df60cad54ded/arbstate/das_reader.go // solhint-disable-next-line func-name-mixedcase function BROTLI_MESSAGE_HEADER_FLAG() external view returns (bytes1); /// @dev If the first data byte after the header has this bit set, /// then the batch data uses a zero heavy encoding /// See: https://github.com/OffchainLabs/nitro/blob/69de0603abf6f900a4128cab7933df60cad54ded/arbstate/das_reader.go // solhint-disable-next-line func-name-mixedcase function ZERO_HEAVY_MESSAGE_HEADER_FLAG() external view returns (bytes1); function rollup() external view returns (IOwnable); function isBatchPoster(address) external view returns (bool); function isSequencer(address) external view returns (bool); function maxDataSize() external view returns (uint256); /// @notice The batch poster manager has the ability to change the batch poster addresses /// This enables the batch poster to do key rotation function batchPosterManager() external view returns (address); struct DasKeySetInfo { bool isValidKeyset; uint64 creationBlock; } /// @dev returns 4 uint256 to be compatible with older version function maxTimeVariation() external view returns ( uint256 delayBlocks, uint256 futureBlocks, uint256 delaySeconds, uint256 futureSeconds ); function dasKeySetInfo(bytes32) external view returns (bool, uint64); /// @notice Remove force inclusion delay after a L1 chainId fork function removeDelayAfterFork() external; /// @notice Force messages from the delayed inbox to be included in the chain /// Callable by any address, but message can only be force-included after maxTimeVariation.delayBlocks and /// maxTimeVariation.delaySeconds has elapsed. As part of normal behaviour the sequencer will include these /// messages so it's only necessary to call this if the sequencer is down, or not including any delayed messages. /// @param _totalDelayedMessagesRead The total number of messages to read up to /// @param kind The kind of the last message to be included /// @param l1BlockAndTime The l1 block and the l1 timestamp of the last message to be included /// @param baseFeeL1 The l1 gas price of the last message to be included /// @param sender The sender of the last message to be included /// @param messageDataHash The messageDataHash of the last message to be included function forceInclusion( uint256 _totalDelayedMessagesRead, uint8 kind, uint64[2] calldata l1BlockAndTime, uint256 baseFeeL1, address sender, bytes32 messageDataHash ) external; function inboxAccs(uint256 index) external view returns (bytes32); function batchCount() external view returns (uint256); function isValidKeysetHash(bytes32 ksHash) external view returns (bool); /// @notice the creation block is intended to still be available after a keyset is deleted function getKeysetCreationBlock(bytes32 ksHash) external view returns (uint256); // ---------- BatchPoster functions ---------- function addSequencerL2BatchFromOrigin( uint256 sequenceNumber, bytes calldata data, uint256 afterDelayedMessagesRead, IGasRefunder gasRefunder ) external; function addSequencerL2BatchFromOrigin( uint256 sequenceNumber, bytes calldata data, uint256 afterDelayedMessagesRead, IGasRefunder gasRefunder, uint256 prevMessageCount, uint256 newMessageCount ) external; function addSequencerL2Batch( uint256 sequenceNumber, bytes calldata data, uint256 afterDelayedMessagesRead, IGasRefunder gasRefunder, uint256 prevMessageCount, uint256 newMessageCount ) external; function addSequencerL2BatchFromBlobs( uint256 sequenceNumber, uint256 afterDelayedMessagesRead, IGasRefunder gasRefunder, uint256 prevMessageCount, uint256 newMessageCount ) external; // ---------- onlyRollupOrOwner functions ---------- /** * @notice Set max delay for sequencer inbox * @param maxTimeVariation_ the maximum time variation parameters */ function setMaxTimeVariation(MaxTimeVariation memory maxTimeVariation_) external; /** * @notice Updates whether an address is authorized to be a batch poster at the sequencer inbox * @param addr the address * @param isBatchPoster_ if the specified address should be authorized as a batch poster */ function setIsBatchPoster(address addr, bool isBatchPoster_) external; /** * @notice Makes Data Availability Service keyset valid * @param keysetBytes bytes of the serialized keyset */ function setValidKeyset(bytes calldata keysetBytes) external; /** * @notice Invalidates a Data Availability Service keyset * @param ksHash hash of the keyset */ function invalidateKeysetHash(bytes32 ksHash) external; /** * @notice Updates whether an address is authorized to be a sequencer. * @dev The IsSequencer information is used only off-chain by the nitro node to validate sequencer feed signer. * @param addr the address * @param isSequencer_ if the specified address should be authorized as a sequencer */ function setIsSequencer(address addr, bool isSequencer_) external; /** * @notice Updates the batch poster manager, the address which has the ability to rotate batch poster keys * @param newBatchPosterManager The new batch poster manager to be set */ function setBatchPosterManager(address newBatchPosterManager) external; /// @notice Allows the rollup owner to sync the rollup address function updateRollupAddress() external; // ---------- initializer ---------- function initialize(IBridge bridge_, MaxTimeVariation calldata maxTimeVariation_) external; }
// Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; library Messages { function messageHash( uint8 kind, address sender, uint64 blockNumber, uint64 timestamp, uint256 inboxSeqNum, uint256 baseFeeL1, bytes32 messageDataHash ) internal pure returns (bytes32) { return keccak256( abi.encodePacked( kind, sender, blockNumber, timestamp, inboxSeqNum, baseFeeL1, messageDataHash ) ); } function accumulateInboxMessage(bytes32 prevAcc, bytes32 message) internal pure returns (bytes32) { return keccak256(abi.encodePacked(prevAcc, message)); } }
// Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 // solhint-disable-next-line compiler-version pragma solidity >=0.6.9 <0.9.0; interface IGasRefunder { function onGasSpent( address payable spender, uint256 gasUsed, uint256 calldataSize ) external returns (bool success); }
// Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "../state/Machine.sol"; import "../state/Module.sol"; import "../state/Instructions.sol"; import "../state/GlobalState.sol"; import "../bridge/ISequencerInbox.sol"; import "../bridge/IBridge.sol"; struct ExecutionContext { uint256 maxInboxMessagesRead; IBridge bridge; } abstract contract IOneStepProver { function executeOneStep( ExecutionContext memory execCtx, Machine calldata mach, Module calldata mod, Instruction calldata instruction, bytes calldata proof ) external view virtual returns (Machine memory result, Module memory resultMod); }
// Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./Value.sol"; import "./ValueStack.sol"; import "./Machine.sol"; import "./MultiStack.sol"; import "./Instructions.sol"; import "./StackFrame.sol"; import "./MerkleProof.sol"; import "./ModuleMemoryCompact.sol"; import "./Module.sol"; import "./GlobalState.sol"; library Deserialize { function u8(bytes calldata proof, uint256 startOffset) internal pure returns (uint8 ret, uint256 offset) { offset = startOffset; ret = uint8(proof[offset]); offset++; } function u16(bytes calldata proof, uint256 startOffset) internal pure returns (uint16 ret, uint256 offset) { offset = startOffset; for (uint256 i = 0; i < 16 / 8; i++) { ret <<= 8; ret |= uint8(proof[offset]); offset++; } } function u32(bytes calldata proof, uint256 startOffset) internal pure returns (uint32 ret, uint256 offset) { offset = startOffset; for (uint256 i = 0; i < 32 / 8; i++) { ret <<= 8; ret |= uint8(proof[offset]); offset++; } } function u64(bytes calldata proof, uint256 startOffset) internal pure returns (uint64 ret, uint256 offset) { offset = startOffset; for (uint256 i = 0; i < 64 / 8; i++) { ret <<= 8; ret |= uint8(proof[offset]); offset++; } } function u256(bytes calldata proof, uint256 startOffset) internal pure returns (uint256 ret, uint256 offset) { offset = startOffset; for (uint256 i = 0; i < 256 / 8; i++) { ret <<= 8; ret |= uint8(proof[offset]); offset++; } } function b32(bytes calldata proof, uint256 startOffset) internal pure returns (bytes32 ret, uint256 offset) { offset = startOffset; uint256 retInt; (retInt, offset) = u256(proof, offset); ret = bytes32(retInt); } function boolean(bytes calldata proof, uint256 startOffset) internal pure returns (bool ret, uint256 offset) { offset = startOffset; ret = uint8(proof[offset]) != 0; offset++; } function value(bytes calldata proof, uint256 startOffset) internal pure returns (Value memory val, uint256 offset) { offset = startOffset; uint8 typeInt = uint8(proof[offset]); offset++; require(typeInt <= uint8(ValueLib.maxValueType()), "BAD_VALUE_TYPE"); uint256 contents; (contents, offset) = u256(proof, offset); val = Value({valueType: ValueType(typeInt), contents: contents}); } function valueStack(bytes calldata proof, uint256 startOffset) internal pure returns (ValueStack memory stack, uint256 offset) { offset = startOffset; bytes32 remainingHash; (remainingHash, offset) = b32(proof, offset); uint256 provedLength; (provedLength, offset) = u256(proof, offset); Value[] memory proved = new Value[](provedLength); for (uint256 i = 0; i < proved.length; i++) { (proved[i], offset) = value(proof, offset); } stack = ValueStack({proved: ValueArray(proved), remainingHash: remainingHash}); } function multiStack(bytes calldata proof, uint256 startOffset) internal pure returns (MultiStack memory multistack, uint256 offset) { offset = startOffset; bytes32 inactiveStackHash; (inactiveStackHash, offset) = b32(proof, offset); bytes32 remainingHash; (remainingHash, offset) = b32(proof, offset); multistack = MultiStack({ inactiveStackHash: inactiveStackHash, remainingHash: remainingHash }); } function instructions(bytes calldata proof, uint256 startOffset) internal pure returns (Instruction[] memory code, uint256 offset) { offset = startOffset; uint8 count; (count, offset) = u8(proof, offset); code = new Instruction[](count); for (uint256 i = 0; i < uint256(count); i++) { uint16 opcode; uint256 data; (opcode, offset) = u16(proof, offset); (data, offset) = u256(proof, offset); code[i] = Instruction({opcode: opcode, argumentData: data}); } } function stackFrame(bytes calldata proof, uint256 startOffset) internal pure returns (StackFrame memory window, uint256 offset) { offset = startOffset; Value memory returnPc; bytes32 localsMerkleRoot; uint32 callerModule; uint32 callerModuleInternals; (returnPc, offset) = value(proof, offset); (localsMerkleRoot, offset) = b32(proof, offset); (callerModule, offset) = u32(proof, offset); (callerModuleInternals, offset) = u32(proof, offset); window = StackFrame({ returnPc: returnPc, localsMerkleRoot: localsMerkleRoot, callerModule: callerModule, callerModuleInternals: callerModuleInternals }); } function stackFrameWindow(bytes calldata proof, uint256 startOffset) internal pure returns (StackFrameWindow memory window, uint256 offset) { offset = startOffset; bytes32 remainingHash; (remainingHash, offset) = b32(proof, offset); StackFrame[] memory proved; if (proof[offset] != 0) { offset++; proved = new StackFrame[](1); (proved[0], offset) = stackFrame(proof, offset); } else { offset++; proved = new StackFrame[](0); } window = StackFrameWindow({proved: proved, remainingHash: remainingHash}); } function moduleMemory(bytes calldata proof, uint256 startOffset) internal pure returns (ModuleMemory memory mem, uint256 offset) { offset = startOffset; uint64 size; uint64 maxSize; bytes32 root; (size, offset) = u64(proof, offset); (maxSize, offset) = u64(proof, offset); (root, offset) = b32(proof, offset); mem = ModuleMemory({size: size, maxSize: maxSize, merkleRoot: root}); } function module(bytes calldata proof, uint256 startOffset) internal pure returns (Module memory mod, uint256 offset) { offset = startOffset; bytes32 globalsMerkleRoot; ModuleMemory memory mem; bytes32 tablesMerkleRoot; bytes32 functionsMerkleRoot; bytes32 extraHash; uint32 internalsOffset; (globalsMerkleRoot, offset) = b32(proof, offset); (mem, offset) = moduleMemory(proof, offset); (tablesMerkleRoot, offset) = b32(proof, offset); (functionsMerkleRoot, offset) = b32(proof, offset); (extraHash, offset) = b32(proof, offset); (internalsOffset, offset) = u32(proof, offset); mod = Module({ globalsMerkleRoot: globalsMerkleRoot, moduleMemory: mem, tablesMerkleRoot: tablesMerkleRoot, functionsMerkleRoot: functionsMerkleRoot, extraHash: extraHash, internalsOffset: internalsOffset }); } function globalState(bytes calldata proof, uint256 startOffset) internal pure returns (GlobalState memory state, uint256 offset) { offset = startOffset; // using constant ints for array size requires newer solidity bytes32[2] memory bytes32Vals; uint64[2] memory u64Vals; for (uint8 i = 0; i < GlobalStateLib.BYTES32_VALS_NUM; i++) { (bytes32Vals[i], offset) = b32(proof, offset); } for (uint8 i = 0; i < GlobalStateLib.U64_VALS_NUM; i++) { (u64Vals[i], offset) = u64(proof, offset); } state = GlobalState({bytes32Vals: bytes32Vals, u64Vals: u64Vals}); } function machine(bytes calldata proof, uint256 startOffset) internal pure returns (Machine memory mach, uint256 offset) { offset = startOffset; { MachineStatus status; { uint8 statusU8; (statusU8, offset) = u8(proof, offset); if (statusU8 == 0) { status = MachineStatus.RUNNING; } else if (statusU8 == 1) { status = MachineStatus.FINISHED; } else if (statusU8 == 2) { status = MachineStatus.ERRORED; } else if (statusU8 == 3) { status = MachineStatus.TOO_FAR; } else { revert("UNKNOWN_MACH_STATUS"); } } ValueStack memory values; ValueStack memory internalStack; MultiStack memory valuesMulti; StackFrameWindow memory frameStack; MultiStack memory framesMulti; (values, offset) = valueStack(proof, offset); (valuesMulti, offset) = multiStack(proof, offset); (internalStack, offset) = valueStack(proof, offset); (frameStack, offset) = stackFrameWindow(proof, offset); (framesMulti, offset) = multiStack(proof, offset); mach = Machine({ status: status, valueStack: values, valueMultiStack: valuesMulti, internalStack: internalStack, frameStack: frameStack, frameMultiStack: framesMulti, globalStateHash: bytes32(0), // filled later moduleIdx: 0, // filled later functionIdx: 0, // filled later functionPc: 0, // filled later recoveryPc: bytes32(0), // filled later modulesRoot: bytes32(0) // filled later }); } (mach.globalStateHash, offset) = b32(proof, offset); (mach.moduleIdx, offset) = u32(proof, offset); (mach.functionIdx, offset) = u32(proof, offset); (mach.functionPc, offset) = u32(proof, offset); (mach.recoveryPc, offset) = b32(proof, offset); (mach.modulesRoot, offset) = b32(proof, offset); } function merkleProof(bytes calldata proof, uint256 startOffset) internal pure returns (MerkleProof memory merkle, uint256 offset) { offset = startOffset; uint8 length; (length, offset) = u8(proof, offset); bytes32[] memory counterparts = new bytes32[](length); for (uint8 i = 0; i < length; i++) { (counterparts[i], offset) = b32(proof, offset); } merkle = MerkleProof(counterparts); } }
// Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; struct GlobalState { bytes32[2] bytes32Vals; uint64[2] u64Vals; } library GlobalStateLib { uint16 internal constant BYTES32_VALS_NUM = 2; uint16 internal constant U64_VALS_NUM = 2; function hash(GlobalState memory state) internal pure returns (bytes32) { return keccak256( abi.encodePacked( "Global state:", state.bytes32Vals[0], state.bytes32Vals[1], state.u64Vals[0], state.u64Vals[1] ) ); } function getBlockHash(GlobalState memory state) internal pure returns (bytes32) { return state.bytes32Vals[0]; } function getSendRoot(GlobalState memory state) internal pure returns (bytes32) { return state.bytes32Vals[1]; } function getInboxPosition(GlobalState memory state) internal pure returns (uint64) { return state.u64Vals[0]; } function getPositionInMessage(GlobalState memory state) internal pure returns (uint64) { return state.u64Vals[1]; } function isEmpty(GlobalState calldata state) internal pure returns (bool) { return (state.bytes32Vals[0] == bytes32(0) && state.bytes32Vals[1] == bytes32(0) && state.u64Vals[0] == 0 && state.u64Vals[1] == 0); } }
// Copyright 2021-2023, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; struct Instruction { uint16 opcode; uint256 argumentData; } library Instructions { uint16 internal constant UNREACHABLE = 0x00; uint16 internal constant NOP = 0x01; uint16 internal constant RETURN = 0x0F; uint16 internal constant CALL = 0x10; uint16 internal constant CALL_INDIRECT = 0x11; uint16 internal constant LOCAL_GET = 0x20; uint16 internal constant LOCAL_SET = 0x21; uint16 internal constant GLOBAL_GET = 0x23; uint16 internal constant GLOBAL_SET = 0x24; uint16 internal constant I32_LOAD = 0x28; uint16 internal constant I64_LOAD = 0x29; uint16 internal constant F32_LOAD = 0x2A; uint16 internal constant F64_LOAD = 0x2B; uint16 internal constant I32_LOAD8_S = 0x2C; uint16 internal constant I32_LOAD8_U = 0x2D; uint16 internal constant I32_LOAD16_S = 0x2E; uint16 internal constant I32_LOAD16_U = 0x2F; uint16 internal constant I64_LOAD8_S = 0x30; uint16 internal constant I64_LOAD8_U = 0x31; uint16 internal constant I64_LOAD16_S = 0x32; uint16 internal constant I64_LOAD16_U = 0x33; uint16 internal constant I64_LOAD32_S = 0x34; uint16 internal constant I64_LOAD32_U = 0x35; uint16 internal constant I32_STORE = 0x36; uint16 internal constant I64_STORE = 0x37; uint16 internal constant F32_STORE = 0x38; uint16 internal constant F64_STORE = 0x39; uint16 internal constant I32_STORE8 = 0x3A; uint16 internal constant I32_STORE16 = 0x3B; uint16 internal constant I64_STORE8 = 0x3C; uint16 internal constant I64_STORE16 = 0x3D; uint16 internal constant I64_STORE32 = 0x3E; uint16 internal constant MEMORY_SIZE = 0x3F; uint16 internal constant MEMORY_GROW = 0x40; uint16 internal constant DROP = 0x1A; uint16 internal constant SELECT = 0x1B; uint16 internal constant I32_CONST = 0x41; uint16 internal constant I64_CONST = 0x42; uint16 internal constant F32_CONST = 0x43; uint16 internal constant F64_CONST = 0x44; uint16 internal constant I32_EQZ = 0x45; uint16 internal constant I32_RELOP_BASE = 0x46; uint16 internal constant IRELOP_EQ = 0; uint16 internal constant IRELOP_NE = 1; uint16 internal constant IRELOP_LT_S = 2; uint16 internal constant IRELOP_LT_U = 3; uint16 internal constant IRELOP_GT_S = 4; uint16 internal constant IRELOP_GT_U = 5; uint16 internal constant IRELOP_LE_S = 6; uint16 internal constant IRELOP_LE_U = 7; uint16 internal constant IRELOP_GE_S = 8; uint16 internal constant IRELOP_GE_U = 9; uint16 internal constant IRELOP_LAST = IRELOP_GE_U; uint16 internal constant I64_EQZ = 0x50; uint16 internal constant I64_RELOP_BASE = 0x51; uint16 internal constant I32_UNOP_BASE = 0x67; uint16 internal constant IUNOP_CLZ = 0; uint16 internal constant IUNOP_CTZ = 1; uint16 internal constant IUNOP_POPCNT = 2; uint16 internal constant IUNOP_LAST = IUNOP_POPCNT; uint16 internal constant I32_ADD = 0x6A; uint16 internal constant I32_SUB = 0x6B; uint16 internal constant I32_MUL = 0x6C; uint16 internal constant I32_DIV_S = 0x6D; uint16 internal constant I32_DIV_U = 0x6E; uint16 internal constant I32_REM_S = 0x6F; uint16 internal constant I32_REM_U = 0x70; uint16 internal constant I32_AND = 0x71; uint16 internal constant I32_OR = 0x72; uint16 internal constant I32_XOR = 0x73; uint16 internal constant I32_SHL = 0x74; uint16 internal constant I32_SHR_S = 0x75; uint16 internal constant I32_SHR_U = 0x76; uint16 internal constant I32_ROTL = 0x77; uint16 internal constant I32_ROTR = 0x78; uint16 internal constant I64_UNOP_BASE = 0x79; uint16 internal constant I64_ADD = 0x7C; uint16 internal constant I64_SUB = 0x7D; uint16 internal constant I64_MUL = 0x7E; uint16 internal constant I64_DIV_S = 0x7F; uint16 internal constant I64_DIV_U = 0x80; uint16 internal constant I64_REM_S = 0x81; uint16 internal constant I64_REM_U = 0x82; uint16 internal constant I64_AND = 0x83; uint16 internal constant I64_OR = 0x84; uint16 internal constant I64_XOR = 0x85; uint16 internal constant I64_SHL = 0x86; uint16 internal constant I64_SHR_S = 0x87; uint16 internal constant I64_SHR_U = 0x88; uint16 internal constant I64_ROTL = 0x89; uint16 internal constant I64_ROTR = 0x8A; uint16 internal constant I32_WRAP_I64 = 0xA7; uint16 internal constant I64_EXTEND_I32_S = 0xAC; uint16 internal constant I64_EXTEND_I32_U = 0xAD; uint16 internal constant I32_REINTERPRET_F32 = 0xBC; uint16 internal constant I64_REINTERPRET_F64 = 0xBD; uint16 internal constant F32_REINTERPRET_I32 = 0xBE; uint16 internal constant F64_REINTERPRET_I64 = 0xBF; uint16 internal constant I32_EXTEND_8S = 0xC0; uint16 internal constant I32_EXTEND_16S = 0xC1; uint16 internal constant I64_EXTEND_8S = 0xC2; uint16 internal constant I64_EXTEND_16S = 0xC3; uint16 internal constant I64_EXTEND_32S = 0xC4; uint16 internal constant INIT_FRAME = 0x8002; uint16 internal constant ARBITRARY_JUMP = 0x8003; uint16 internal constant ARBITRARY_JUMP_IF = 0x8004; uint16 internal constant MOVE_FROM_STACK_TO_INTERNAL = 0x8005; uint16 internal constant MOVE_FROM_INTERNAL_TO_STACK = 0x8006; uint16 internal constant DUP = 0x8008; uint16 internal constant CROSS_MODULE_CALL = 0x8009; uint16 internal constant CALLER_MODULE_INTERNAL_CALL = 0x800A; uint16 internal constant CROSS_MODULE_FORWARD = 0x800B; uint16 internal constant CROSS_MODULE_INTERNAL_CALL = 0x800C; uint16 internal constant GET_GLOBAL_STATE_BYTES32 = 0x8010; uint16 internal constant SET_GLOBAL_STATE_BYTES32 = 0x8011; uint16 internal constant GET_GLOBAL_STATE_U64 = 0x8012; uint16 internal constant SET_GLOBAL_STATE_U64 = 0x8013; uint16 internal constant READ_PRE_IMAGE = 0x8020; uint16 internal constant READ_INBOX_MESSAGE = 0x8021; uint16 internal constant HALT_AND_SET_FINISHED = 0x8022; uint16 internal constant LINK_MODULE = 0x8023; uint16 internal constant UNLINK_MODULE = 0x8024; uint16 internal constant NEW_COTHREAD = 0x8030; uint16 internal constant POP_COTHREAD = 0x8031; uint16 internal constant SWITCH_COTHREAD = 0x8032; uint256 internal constant INBOX_INDEX_SEQUENCER = 0; uint256 internal constant INBOX_INDEX_DELAYED = 1; function hash(Instruction[] memory code) internal pure returns (bytes32) { // To avoid quadratic expense, we declare a `bytes` early and populate its contents. bytes memory data = new bytes(13 + 1 + 34 * code.length); assembly { // Represents the string "Instructions:", which we place after the length word. mstore( add(data, 32), 0x496e737472756374696f6e733a00000000000000000000000000000000000000 ) } // write the instruction count uint256 offset = 13; data[offset] = bytes1(uint8(code.length)); offset++; // write each instruction for (uint256 i = 0; i < code.length; i++) { Instruction memory inst = code[i]; data[offset] = bytes1(uint8(inst.opcode >> 8)); data[offset + 1] = bytes1(uint8(inst.opcode)); offset += 2; uint256 argumentData = inst.argumentData; assembly { mstore(add(add(data, 32), offset), argumentData) } offset += 32; } return keccak256(data); } }
// Copyright 2021-2023, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./ValueStack.sol"; import "./Instructions.sol"; import "./MultiStack.sol"; import "./StackFrame.sol"; enum MachineStatus { RUNNING, FINISHED, ERRORED, TOO_FAR } struct Machine { MachineStatus status; ValueStack valueStack; MultiStack valueMultiStack; ValueStack internalStack; StackFrameWindow frameStack; MultiStack frameMultiStack; bytes32 globalStateHash; uint32 moduleIdx; uint32 functionIdx; uint32 functionPc; bytes32 recoveryPc; bytes32 modulesRoot; } library MachineLib { using StackFrameLib for StackFrameWindow; using ValueStackLib for ValueStack; using MultiStackLib for MultiStack; bytes32 internal constant NO_RECOVERY_PC = ~bytes32(0); function hash(Machine memory mach) internal pure returns (bytes32) { // Warning: the non-running hashes are replicated in Challenge if (mach.status == MachineStatus.RUNNING) { bytes32 valueMultiHash = mach.valueMultiStack.hash( mach.valueStack.hash(), mach.recoveryPc != NO_RECOVERY_PC ); bytes32 frameMultiHash = mach.frameMultiStack.hash( mach.frameStack.hash(), mach.recoveryPc != NO_RECOVERY_PC ); bytes memory preimage = abi.encodePacked( "Machine running:", valueMultiHash, mach.internalStack.hash(), frameMultiHash, mach.globalStateHash, mach.moduleIdx, mach.functionIdx, mach.functionPc, mach.recoveryPc, mach.modulesRoot ); return keccak256(preimage); } else if (mach.status == MachineStatus.FINISHED) { return keccak256(abi.encodePacked("Machine finished:", mach.globalStateHash)); } else if (mach.status == MachineStatus.ERRORED) { return keccak256(abi.encodePacked("Machine errored:")); } else if (mach.status == MachineStatus.TOO_FAR) { return keccak256(abi.encodePacked("Machine too far:")); } else { revert("BAD_MACH_STATUS"); } } function switchCoThreadStacks(Machine memory mach) internal pure { bytes32 newActiveValue = mach.valueMultiStack.inactiveStackHash; bytes32 newActiveFrame = mach.frameMultiStack.inactiveStackHash; if ( newActiveFrame == MultiStackLib.NO_STACK_HASH || newActiveValue == MultiStackLib.NO_STACK_HASH ) { mach.status = MachineStatus.ERRORED; return; } mach.frameMultiStack.inactiveStackHash = mach.frameStack.hash(); mach.valueMultiStack.inactiveStackHash = mach.valueStack.hash(); mach.frameStack.overwrite(newActiveFrame); mach.valueStack.overwrite(newActiveValue); } function setPcFromData(Machine memory mach, uint256 data) internal pure returns (bool) { if (data >> 96 != 0) { return false; } mach.functionPc = uint32(data); mach.functionIdx = uint32(data >> 32); mach.moduleIdx = uint32(data >> 64); return true; } function setPcFromRecovery(Machine memory mach) internal pure returns (bool) { if (!setPcFromData(mach, uint256(mach.recoveryPc))) { return false; } mach.recoveryPc = NO_RECOVERY_PC; return true; } function setRecoveryFromPc(Machine memory mach, uint32 offset) internal pure returns (bool) { if (mach.recoveryPc != NO_RECOVERY_PC) { return false; } uint256 result; result = uint256(mach.moduleIdx) << 64; result = result | (uint256(mach.functionIdx) << 32); result = result | uint256(mach.functionPc + offset - 1); mach.recoveryPc = bytes32(result); return true; } function setPc(Machine memory mach, Value memory pc) internal pure { if (pc.valueType == ValueType.REF_NULL) { mach.status = MachineStatus.ERRORED; return; } if (pc.valueType != ValueType.INTERNAL_REF) { mach.status = MachineStatus.ERRORED; return; } if (!setPcFromData(mach, pc.contents)) { mach.status = MachineStatus.ERRORED; return; } } }
// Copyright 2021-2023, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./Value.sol"; import "./Instructions.sol"; import "./Module.sol"; struct MerkleProof { bytes32[] counterparts; } library MerkleProofLib { using ModuleLib for Module; using ValueLib for Value; function computeRootFromValue( MerkleProof memory proof, uint256 index, Value memory leaf ) internal pure returns (bytes32) { return computeRootUnsafe(proof, index, leaf.hash(), "Value merkle tree:"); } function computeRootFromInstructions( MerkleProof memory proof, uint256 index, Instruction[] memory code ) internal pure returns (bytes32) { return computeRootUnsafe(proof, index, Instructions.hash(code), "Instruction merkle tree:"); } function computeRootFromFunction( MerkleProof memory proof, uint256 index, bytes32 codeRoot ) internal pure returns (bytes32) { bytes32 h = keccak256(abi.encodePacked("Function:", codeRoot)); return computeRootUnsafe(proof, index, h, "Function merkle tree:"); } function computeRootFromMemory( MerkleProof memory proof, uint256 index, bytes32 contents ) internal pure returns (bytes32) { bytes32 h = keccak256(abi.encodePacked("Memory leaf:", contents)); return computeRootUnsafe(proof, index, h, "Memory merkle tree:"); } function computeRootFromElement( MerkleProof memory proof, uint256 index, bytes32 funcTypeHash, Value memory val ) internal pure returns (bytes32) { bytes32 h = keccak256(abi.encodePacked("Table element:", funcTypeHash, val.hash())); return computeRootUnsafe(proof, index, h, "Table element merkle tree:"); } function computeRootFromTable( MerkleProof memory proof, uint256 index, uint8 tableType, uint64 tableSize, bytes32 elementsRoot ) internal pure returns (bytes32) { bytes32 h = keccak256(abi.encodePacked("Table:", tableType, tableSize, elementsRoot)); return computeRootUnsafe(proof, index, h, "Table merkle tree:"); } function computeRootFromModule( MerkleProof memory proof, uint256 index, Module memory mod ) internal pure returns (bytes32) { return computeRootUnsafe(proof, index, mod.hash(), "Module merkle tree:"); } // WARNING: leafHash must be computed in such a way that it cannot be a non-leaf hash. function computeRootUnsafe( MerkleProof memory proof, uint256 index, bytes32 leafHash, string memory prefix ) internal pure returns (bytes32 h) { h = leafHash; for (uint256 layer = 0; layer < proof.counterparts.length; layer++) { if (index & 1 == 0) { h = keccak256(abi.encodePacked(prefix, h, proof.counterparts[layer])); } else { h = keccak256(abi.encodePacked(prefix, proof.counterparts[layer], h)); } index >>= 1; } require(index == 0, "PROOF_TOO_SHORT"); } function growToNewRoot( bytes32 root, uint256 leaf, bytes32 hash, bytes32 zero, string memory prefix ) internal pure returns (bytes32) { bytes32 h = hash; uint256 node = leaf; while (node > 1) { h = keccak256(abi.encodePacked(prefix, h, zero)); zero = keccak256(abi.encodePacked(prefix, zero, zero)); node >>= 1; } return keccak256(abi.encodePacked(prefix, root, h)); } }
// Copyright 2021-2023, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./ModuleMemoryCompact.sol"; struct Module { bytes32 globalsMerkleRoot; ModuleMemory moduleMemory; bytes32 tablesMerkleRoot; bytes32 functionsMerkleRoot; bytes32 extraHash; uint32 internalsOffset; } library ModuleLib { using ModuleMemoryCompactLib for ModuleMemory; function hash(Module memory mod) internal pure returns (bytes32) { return keccak256( abi.encodePacked( "Module:", mod.globalsMerkleRoot, mod.moduleMemory.hash(), mod.tablesMerkleRoot, mod.functionsMerkleRoot, mod.extraHash, mod.internalsOffset ) ); } }
// Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./MerkleProof.sol"; import "./Deserialize.sol"; import "./ModuleMemoryCompact.sol"; library ModuleMemoryLib { using MerkleProofLib for MerkleProof; uint256 private constant LEAF_SIZE = 32; function hash(ModuleMemory memory mem) internal pure returns (bytes32) { return ModuleMemoryCompactLib.hash(mem); } function proveLeaf( ModuleMemory memory mem, uint256 leafIdx, bytes calldata proof, uint256 startOffset ) internal pure returns ( bytes32 contents, uint256 offset, MerkleProof memory merkle ) { offset = startOffset; (contents, offset) = Deserialize.b32(proof, offset); (merkle, offset) = Deserialize.merkleProof(proof, offset); bytes32 recomputedRoot = merkle.computeRootFromMemory(leafIdx, contents); require(recomputedRoot == mem.merkleRoot, "WRONG_MEM_ROOT"); } function isValidLeaf(ModuleMemory memory mem, uint256 pointer) internal pure returns (bool) { return pointer + 32 <= mem.size && pointer % LEAF_SIZE == 0; } function pullLeafByte(bytes32 leaf, uint256 idx) internal pure returns (uint8) { require(idx < LEAF_SIZE, "BAD_PULL_LEAF_BYTE_IDX"); // Take into account that we are casting the leaf to a big-endian integer uint256 leafShift = (LEAF_SIZE - 1 - idx) * 8; return uint8(uint256(leaf) >> leafShift); } // loads a big-endian value from memory function load( ModuleMemory memory mem, uint256 start, uint256 width, bytes calldata proof, uint256 proofOffset ) internal pure returns ( bool err, uint256 value, uint256 offset ) { if (start + width > mem.size) { return (true, 0, proofOffset); } uint256 lastProvedLeafIdx = ~uint256(0); bytes32 lastProvedLeafContents; uint256 readValue; for (uint256 i = 0; i < width; i++) { uint256 idx = start + i; uint256 leafIdx = idx / LEAF_SIZE; if (leafIdx != lastProvedLeafIdx) { (lastProvedLeafContents, proofOffset, ) = proveLeaf( mem, leafIdx, proof, proofOffset ); lastProvedLeafIdx = leafIdx; } uint256 indexWithinLeaf = idx % LEAF_SIZE; readValue |= uint256(pullLeafByte(lastProvedLeafContents, indexWithinLeaf)) << (i * 8); } return (false, readValue, proofOffset); } }
// Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; struct ModuleMemory { uint64 size; uint64 maxSize; bytes32 merkleRoot; } library ModuleMemoryCompactLib { function hash(ModuleMemory memory mem) internal pure returns (bytes32) { return keccak256(abi.encodePacked("Memory:", mem.size, mem.maxSize, mem.merkleRoot)); } }
// Copyright 2021-2024, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; struct MultiStack { bytes32 inactiveStackHash; // NO_STACK_HASH if no stack, 0 if empty stack bytes32 remainingHash; // 0 if less than 2 cothreads exist } library MultiStackLib { bytes32 internal constant NO_STACK_HASH = ~bytes32(0); function hash( MultiStack memory multi, bytes32 activeStackHash, bool cothread ) internal pure returns (bytes32) { require(activeStackHash != NO_STACK_HASH, "MULTISTACK_NOSTACK_ACTIVE"); if (cothread) { require(multi.inactiveStackHash != NO_STACK_HASH, "MULTISTACK_NOSTACK_MAIN"); return keccak256( abi.encodePacked( "multistack:", multi.inactiveStackHash, activeStackHash, multi.remainingHash ) ); } else { return keccak256( abi.encodePacked( "multistack:", activeStackHash, multi.inactiveStackHash, multi.remainingHash ) ); } } function setEmpty(MultiStack memory multi) internal pure { multi.inactiveStackHash = NO_STACK_HASH; multi.remainingHash = 0; } function pushNew(MultiStack memory multi) internal pure { if (multi.inactiveStackHash != NO_STACK_HASH) { multi.remainingHash = keccak256( abi.encodePacked("cothread:", multi.inactiveStackHash, multi.remainingHash) ); } multi.inactiveStackHash = 0; } }
// Copyright 2021-2023, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./Value.sol"; struct StackFrame { Value returnPc; bytes32 localsMerkleRoot; uint32 callerModule; uint32 callerModuleInternals; } struct StackFrameWindow { StackFrame[] proved; bytes32 remainingHash; } library StackFrameLib { using ValueLib for Value; function hash(StackFrame memory frame) internal pure returns (bytes32) { return keccak256( abi.encodePacked( "Stack frame:", frame.returnPc.hash(), frame.localsMerkleRoot, frame.callerModule, frame.callerModuleInternals ) ); } function hash(StackFrameWindow memory window) internal pure returns (bytes32 h) { h = window.remainingHash; for (uint256 i = 0; i < window.proved.length; i++) { h = keccak256(abi.encodePacked("Stack frame stack:", hash(window.proved[i]), h)); } } function peek(StackFrameWindow memory window) internal pure returns (StackFrame memory) { require(window.proved.length == 1, "BAD_WINDOW_LENGTH"); return window.proved[0]; } function pop(StackFrameWindow memory window) internal pure returns (StackFrame memory frame) { require(window.proved.length == 1, "BAD_WINDOW_LENGTH"); frame = window.proved[0]; window.proved = new StackFrame[](0); } function push(StackFrameWindow memory window, StackFrame memory frame) internal pure { StackFrame[] memory newProved = new StackFrame[](window.proved.length + 1); for (uint256 i = 0; i < window.proved.length; i++) { newProved[i] = window.proved[i]; } newProved[window.proved.length] = frame; window.proved = newProved; } function overwrite(StackFrameWindow memory window, bytes32 root) internal pure { window.remainingHash = root; delete window.proved; } }
// Copyright 2021-2023, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; enum ValueType { I32, I64, F32, F64, REF_NULL, FUNC_REF, INTERNAL_REF } struct Value { ValueType valueType; uint256 contents; } library ValueLib { function hash(Value memory val) internal pure returns (bytes32) { return keccak256(abi.encodePacked("Value:", val.valueType, val.contents)); } function maxValueType() internal pure returns (ValueType) { return ValueType.INTERNAL_REF; } function assumeI32(Value memory val) internal pure returns (uint32) { uint256 uintval = uint256(val.contents); require(val.valueType == ValueType.I32, "NOT_I32"); require(uintval < (1 << 32), "BAD_I32"); return uint32(uintval); } function assumeI64(Value memory val) internal pure returns (uint64) { uint256 uintval = uint256(val.contents); require(val.valueType == ValueType.I64, "NOT_I64"); require(uintval < (1 << 64), "BAD_I64"); return uint64(uintval); } function newRefNull() internal pure returns (Value memory) { return Value({valueType: ValueType.REF_NULL, contents: 0}); } function newI32(uint32 x) internal pure returns (Value memory) { return Value({valueType: ValueType.I32, contents: uint256(x)}); } function newI64(uint64 x) internal pure returns (Value memory) { return Value({valueType: ValueType.I64, contents: uint256(x)}); } function newBoolean(bool x) internal pure returns (Value memory) { if (x) { return newI32(uint32(1)); } else { return newI32(uint32(0)); } } function newPc( uint32 funcPc, uint32 func, uint32 module ) internal pure returns (Value memory) { uint256 data = 0; data |= funcPc; data |= uint256(func) << 32; data |= uint256(module) << 64; return Value({valueType: ValueType.INTERNAL_REF, contents: data}); } }
// Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./Value.sol"; struct ValueArray { Value[] inner; } library ValueArrayLib { function get(ValueArray memory arr, uint256 index) internal pure returns (Value memory) { return arr.inner[index]; } function set( ValueArray memory arr, uint256 index, Value memory val ) internal pure { arr.inner[index] = val; } function length(ValueArray memory arr) internal pure returns (uint256) { return arr.inner.length; } function push(ValueArray memory arr, Value memory val) internal pure { Value[] memory newInner = new Value[](arr.inner.length + 1); for (uint256 i = 0; i < arr.inner.length; i++) { newInner[i] = arr.inner[i]; } newInner[arr.inner.length] = val; arr.inner = newInner; } function pop(ValueArray memory arr) internal pure returns (Value memory popped) { popped = arr.inner[arr.inner.length - 1]; Value[] memory newInner = new Value[](arr.inner.length - 1); for (uint256 i = 0; i < newInner.length; i++) { newInner[i] = arr.inner[i]; } arr.inner = newInner; } }
// Copyright 2021-2023, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./Value.sol"; import "./ValueArray.sol"; struct ValueStack { ValueArray proved; bytes32 remainingHash; } library ValueStackLib { using ValueLib for Value; using ValueArrayLib for ValueArray; function hash(ValueStack memory stack) internal pure returns (bytes32 h) { h = stack.remainingHash; uint256 len = stack.proved.length(); for (uint256 i = 0; i < len; i++) { h = keccak256(abi.encodePacked("Value stack:", stack.proved.get(i).hash(), h)); } } function peek(ValueStack memory stack) internal pure returns (Value memory) { uint256 len = stack.proved.length(); return stack.proved.get(len - 1); } function pop(ValueStack memory stack) internal pure returns (Value memory) { return stack.proved.pop(); } function push(ValueStack memory stack, Value memory val) internal pure { return stack.proved.push(val); } function overwrite(ValueStack memory stack, bytes32 root) internal pure { stack.remainingHash = root; delete stack.proved; } }
{ "optimizer": { "enabled": true, "runs": 100 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"components":[{"internalType":"uint256","name":"maxInboxMessagesRead","type":"uint256"},{"internalType":"contract IBridge","name":"bridge","type":"address"}],"internalType":"struct ExecutionContext","name":"execCtx","type":"tuple"},{"components":[{"internalType":"enum MachineStatus","name":"status","type":"uint8"},{"components":[{"components":[{"components":[{"internalType":"enum ValueType","name":"valueType","type":"uint8"},{"internalType":"uint256","name":"contents","type":"uint256"}],"internalType":"struct Value[]","name":"inner","type":"tuple[]"}],"internalType":"struct ValueArray","name":"proved","type":"tuple"},{"internalType":"bytes32","name":"remainingHash","type":"bytes32"}],"internalType":"struct ValueStack","name":"valueStack","type":"tuple"},{"components":[{"internalType":"bytes32","name":"inactiveStackHash","type":"bytes32"},{"internalType":"bytes32","name":"remainingHash","type":"bytes32"}],"internalType":"struct MultiStack","name":"valueMultiStack","type":"tuple"},{"components":[{"components":[{"components":[{"internalType":"enum ValueType","name":"valueType","type":"uint8"},{"internalType":"uint256","name":"contents","type":"uint256"}],"internalType":"struct Value[]","name":"inner","type":"tuple[]"}],"internalType":"struct ValueArray","name":"proved","type":"tuple"},{"internalType":"bytes32","name":"remainingHash","type":"bytes32"}],"internalType":"struct ValueStack","name":"internalStack","type":"tuple"},{"components":[{"components":[{"components":[{"internalType":"enum ValueType","name":"valueType","type":"uint8"},{"internalType":"uint256","name":"contents","type":"uint256"}],"internalType":"struct Value","name":"returnPc","type":"tuple"},{"internalType":"bytes32","name":"localsMerkleRoot","type":"bytes32"},{"internalType":"uint32","name":"callerModule","type":"uint32"},{"internalType":"uint32","name":"callerModuleInternals","type":"uint32"}],"internalType":"struct StackFrame[]","name":"proved","type":"tuple[]"},{"internalType":"bytes32","name":"remainingHash","type":"bytes32"}],"internalType":"struct StackFrameWindow","name":"frameStack","type":"tuple"},{"components":[{"internalType":"bytes32","name":"inactiveStackHash","type":"bytes32"},{"internalType":"bytes32","name":"remainingHash","type":"bytes32"}],"internalType":"struct MultiStack","name":"frameMultiStack","type":"tuple"},{"internalType":"bytes32","name":"globalStateHash","type":"bytes32"},{"internalType":"uint32","name":"moduleIdx","type":"uint32"},{"internalType":"uint32","name":"functionIdx","type":"uint32"},{"internalType":"uint32","name":"functionPc","type":"uint32"},{"internalType":"bytes32","name":"recoveryPc","type":"bytes32"},{"internalType":"bytes32","name":"modulesRoot","type":"bytes32"}],"internalType":"struct Machine","name":"startMach","type":"tuple"},{"components":[{"internalType":"bytes32","name":"globalsMerkleRoot","type":"bytes32"},{"components":[{"internalType":"uint64","name":"size","type":"uint64"},{"internalType":"uint64","name":"maxSize","type":"uint64"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"internalType":"struct ModuleMemory","name":"moduleMemory","type":"tuple"},{"internalType":"bytes32","name":"tablesMerkleRoot","type":"bytes32"},{"internalType":"bytes32","name":"functionsMerkleRoot","type":"bytes32"},{"internalType":"bytes32","name":"extraHash","type":"bytes32"},{"internalType":"uint32","name":"internalsOffset","type":"uint32"}],"internalType":"struct Module","name":"startMod","type":"tuple"},{"components":[{"internalType":"uint16","name":"opcode","type":"uint16"},{"internalType":"uint256","name":"argumentData","type":"uint256"}],"internalType":"struct Instruction","name":"inst","type":"tuple"},{"internalType":"bytes","name":"proof","type":"bytes"}],"name":"executeOneStep","outputs":[{"components":[{"internalType":"enum MachineStatus","name":"status","type":"uint8"},{"components":[{"components":[{"components":[{"internalType":"enum ValueType","name":"valueType","type":"uint8"},{"internalType":"uint256","name":"contents","type":"uint256"}],"internalType":"struct Value[]","name":"inner","type":"tuple[]"}],"internalType":"struct ValueArray","name":"proved","type":"tuple"},{"internalType":"bytes32","name":"remainingHash","type":"bytes32"}],"internalType":"struct ValueStack","name":"valueStack","type":"tuple"},{"components":[{"internalType":"bytes32","name":"inactiveStackHash","type":"bytes32"},{"internalType":"bytes32","name":"remainingHash","type":"bytes32"}],"internalType":"struct MultiStack","name":"valueMultiStack","type":"tuple"},{"components":[{"components":[{"components":[{"internalType":"enum ValueType","name":"valueType","type":"uint8"},{"internalType":"uint256","name":"contents","type":"uint256"}],"internalType":"struct Value[]","name":"inner","type":"tuple[]"}],"internalType":"struct ValueArray","name":"proved","type":"tuple"},{"internalType":"bytes32","name":"remainingHash","type":"bytes32"}],"internalType":"struct ValueStack","name":"internalStack","type":"tuple"},{"components":[{"components":[{"components":[{"internalType":"enum ValueType","name":"valueType","type":"uint8"},{"internalType":"uint256","name":"contents","type":"uint256"}],"internalType":"struct Value","name":"returnPc","type":"tuple"},{"internalType":"bytes32","name":"localsMerkleRoot","type":"bytes32"},{"internalType":"uint32","name":"callerModule","type":"uint32"},{"internalType":"uint32","name":"callerModuleInternals","type":"uint32"}],"internalType":"struct StackFrame[]","name":"proved","type":"tuple[]"},{"internalType":"bytes32","name":"remainingHash","type":"bytes32"}],"internalType":"struct StackFrameWindow","name":"frameStack","type":"tuple"},{"components":[{"internalType":"bytes32","name":"inactiveStackHash","type":"bytes32"},{"internalType":"bytes32","name":"remainingHash","type":"bytes32"}],"internalType":"struct MultiStack","name":"frameMultiStack","type":"tuple"},{"internalType":"bytes32","name":"globalStateHash","type":"bytes32"},{"internalType":"uint32","name":"moduleIdx","type":"uint32"},{"internalType":"uint32","name":"functionIdx","type":"uint32"},{"internalType":"uint32","name":"functionPc","type":"uint32"},{"internalType":"bytes32","name":"recoveryPc","type":"bytes32"},{"internalType":"bytes32","name":"modulesRoot","type":"bytes32"}],"internalType":"struct Machine","name":"mach","type":"tuple"},{"components":[{"internalType":"bytes32","name":"globalsMerkleRoot","type":"bytes32"},{"components":[{"internalType":"uint64","name":"size","type":"uint64"},{"internalType":"uint64","name":"maxSize","type":"uint64"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"internalType":"struct ModuleMemory","name":"moduleMemory","type":"tuple"},{"internalType":"bytes32","name":"tablesMerkleRoot","type":"bytes32"},{"internalType":"bytes32","name":"functionsMerkleRoot","type":"bytes32"},{"internalType":"bytes32","name":"extraHash","type":"bytes32"},{"internalType":"uint32","name":"internalsOffset","type":"uint32"}],"internalType":"struct Module","name":"mod","type":"tuple"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50613b99806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80633604366f14610030575b600080fd5b61004361003e366004612e1c565b61005a565b604051610051929190613030565b60405180910390f35b610062612c84565b61006a612d65565b61007387613558565b915061008436879003870187613694565b905060006100956020870187613736565b9050612dbd61801061ffff8316108015906100b6575061801361ffff831611155b156100c457506101e06101c1565b61ffff821661802014156100db57506103286101c1565b61ffff821661802114156100f257506109e56101c1565b61ffff821661802214156101095750610d0a6101c1565b61ffff821661802314156101205750610d166101c1565b61ffff821661802414156101375750610e3c6101c1565b61ffff8216618030141561014e5750610ee46101c1565b61ffff821661803114156101655750610f2b6101c1565b61ffff8216618032141561017c5750610f826101c1565b60405162461bcd60e51b8152602060048201526015602482015274494e56414c49445f4d454d4f52595f4f50434f444560581b60448201526064015b60405180910390fd5b6101d38a85858a8a8a8763ffffffff16565b5050965096945050505050565b60006101ef6020850185613736565b90506101f9612dc7565b6000610206858583610ff6565b60c08a01519193509150610219836110d1565b146102595760405162461bcd60e51b815260206004820152601060248201526f4241445f474c4f42414c5f535441544560801b60448201526064016101b8565b61ffff83166180101480610272575061ffff8316618011145b156102945761028f8888848961028a8987818d61375a565b611152565b61030c565b61ffff831661801214156102ac5761028f88836112d7565b61ffff831661801314156102c45761028f8883611385565b60405162461bcd60e51b815260206004820152601a60248201527f494e56414c49445f474c4f42414c53544154455f4f50434f444500000000000060448201526064016101b8565b610315826110d1565b60c0909801979097525050505050505050565b600061033f61033a87602001516113fb565b611420565b63ffffffff169050600061035961033a88602001516113fb565b63ffffffff16905061036c60208361379a565b1515806103925750602080870151516001600160401b0316906103909083906137c4565b115b806103a657506103a360208261379a565b15155b156103cd578660025b908160038111156103c2576103c2612f01565b8152505050506109dd565b60006103da6020836137dc565b90506000806103f56040518060200160405280606081525090565b60208a015161040790858a8a876114b1565b909450909250905060606000898986818110610425576104256137f0565b919091013560f81c915085905061043b81613806565b95505060208b01356105165760ff81166104fe5736600061045e8b88818f61375a565b91509150858282604051610473929190613821565b6040518091039020146104985760405162461bcd60e51b81526004016101b890613831565b60006104a58b60206137c4565b9050818111156104b25750805b6104be818c848661375a565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092975061096195505050505050565b60405162461bcd60e51b81526004016101b890613857565b8a60200135600114156105c75760ff8116156105445760405162461bcd60e51b81526004016101b890613857565b3660006105538b88818f61375a565b91509150856002838360405161056a929190613821565b602060405180830381855afa158015610587573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906105aa9190613887565b146104985760405162461bcd60e51b81526004016101b890613831565b8a60200135600214156109215760ff8116156105f55760405162461bcd60e51b81526004016101b890613857565b3660006106048b88818f61375a565b90925090508561061860206000848661375a565b610621916138a0565b146106655760405162461bcd60e51b8152602060048201526014602482015273096b48ebea0a49e9e8cbeaea49e9c8ebe9082a6960631b60448201526064016101b8565b600080600080600a6001600160a01b03168686604051610686929190613821565b600060405180830381855afa9150503d80600081146106c1576040519150601f19603f3d011682016040523d82523d6000602084013e6106c6565b606091505b50915091508161070c5760405162461bcd60e51b815260206004820152601160248201527024a72b20a624a22fa5ad23afa82927a7a360791b60448201526064016101b8565b60008151116107565760405162461bcd60e51b81526020600482015260166024820152754b5a475f505245434f4d50494c455f4d495353494e4760501b60448201526064016101b8565b8080602001905181019061076a91906138be565b9094509250507f73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001821490506107d75760405162461bcd60e51b8152602060048201526013602482015272554e4b4e4f574e5f424c535f4d4f44554c555360681b60448201526064016101b8565b6107e28260206138e2565b8c1015610918576000806107f760208f6137dc565b905060015b8481101561082657600192831b92828116141561081a576001831792505b600191821c911b6107fc565b506000610838856401000000006137dc565b905061084483826138e2565b905060006108737f16a2a19edfe81f20d09b681922c813b4b63683508c2280b93829971f439f0d2b838761154b565b905080610884604060208a8c61375a565b61088d916138a0565b146108ce5760405162461bcd60e51b815260206004820152601160248201527025ad23afa82927a7a32faba927a723afad60791b60448201526064016101b8565b6108dc60606040898b61375a565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929c50505050505050505b50505050610961565b60405162461bcd60e51b8152602060048201526015602482015274554e4b4e4f574e5f505245494d4147455f5459504560581b60448201526064016101b8565b60005b82518110156109a5576109918582858481518110610984576109846137f0565b016020015160f81c61167f565b94508061099d81613806565b915050610964565b506109b1838786611704565b60208d01516040015281516109d4906109c990611783565b60208f0151906117b6565b50505050505050505b505050505050565b60006109f761033a87602001516113fb565b63ffffffff1690506000610a1161033a88602001516113fb565b63ffffffff1690506000610a30610a2b89602001516113fb565b6117c6565b6001600160401b031690506020860135158015610a4e575088358110155b15610a76578760035b90816003811115610a6a57610a6a612f01565b815250505050506109dd565b602080880151516001600160401b031690610a929084906137c4565b1180610aa75750610aa460208361379a565b15155b15610ab457876002610a57565b6000610ac16020846137dc565b9050600080610adc6040518060200160405280606081525090565b60208b0151610aee90858b8b876114b1565b9094509092509050888884818110610b0857610b086137f0565b909101356001600160f81b031916159050610b5b5760405162461bcd60e51b81526020600482015260136024820152722aa725a727aba72fa4a72127ac2fa82927a7a360691b60448201526064016101b8565b82610b6581613806565b935050612dbd6000808c602001351415610b83576118579150610bc3565b60018c602001351415610b9a57611b589150610bc3565b8d60025b90816003811115610bb157610bb1612f01565b815250505050505050505050506109dd565b610be38f888d8d89908092610bda9392919061375a565b8663ffffffff16565b905080610bf2578d6002610b9e565b505082881015610c385760405162461bcd60e51b81526020600482015260116024820152702120a22fa6a2a9a9a0a3a2afa82927a7a360791b60448201526064016101b8565b6000610c44848a613901565b905060005b60208163ffffffff16108015610c6d575081610c6b63ffffffff83168b6137c4565b105b15610cc657610cb28463ffffffff83168d8d82610c8a8f8c6137c4565b610c9491906137c4565b818110610ca357610ca36137f0565b919091013560f81c905061167f565b935080610cbe81613918565b915050610c49565b610cd1838786611704565b60208e015160400152610cf9610ce682611783565b8f602001516117b690919063ffffffff16565b505050505050505050505050505050565b50506001909252505050565b60006040518060400160405280601381526020017226b7b23ab6329036b2b935b632903a3932b29d60691b8152509050600086610160015190506000610d6261033a89602001516113fb565b63ffffffff169050610d81818860200151611dfa90919063ffffffff16565b610d8d57876002610a57565b600080610dad610d9e6020856137dc565b60208b015190898960006114b1565b5091509150600080610dc18c848b8b611e2f565b92505091506000610ddd836001610dd891906137c4565b61200f565b90508015610e0857610dfd87610df48560016137c4565b8760008c61202f565b6101608e0152610e26565b610e1f610e168460016137c4565b8390878b6120d9565b6101608e01525b6109d46109c9610e378560016137c4565b611783565b60408051808201909152601381527226b7b23ab6329036b2b935b632903a3932b29d60691b6020820152600080610e7588828787611e2f565b50915091506000610e858361200f565b90508015610ec45781518051610e9d90600190613901565b81518110610ead57610ead6137f0565b602002602001015189610160018181525050610ed8565b610ed182846000876120d9565b6101608a01525b50505050505050505050565b61014085015160001914610f11578460025b90816003811115610f0957610f09612f01565b9052506109dd565b610f1e8560a001516121e3565b6109dd85604001516121e3565b61014085015160001914610f4157846002610ef6565b60a0850151516000191415610f5857846002610ef6565b610f6785604001518383612226565b60a08501516109dd90610f7d836040818761375a565b612226565b60a0850151516000191415610f9957846002610ef6565b6020830135610fc7576101408501516000191415610fb957846002610ef6565b600019610140860152610fed565b61014085015160001914610fdd57846002610ef6565b610feb856020850135612314565b505b6109dd85612387565b610ffe612dc7565b81611007612dec565b61100f612dec565b60005b600260ff8216101561105a5761102988888661240b565b848360ff166002811061103e5761103e6137f0565b60200201919091529350806110528161393c565b915050611012565b5060005b600260ff821610156110b457611075888886612427565b838360ff166002811061108a5761108a6137f0565b6001600160401b0390931660209390930201919091529350806110ac8161393c565b91505061105e565b506040805180820190915291825260208201529590945092505050565b80518051602091820151828401518051908401516040516c23b637b130b61039ba30ba329d60991b95810195909552602d850193909352604d8401919091526001600160c01b031960c091821b8116606d85015291901b166075820152600090607d015b604051602081830303815290604052805190602001209050919050565b600061116461033a88602001516113fb565b63ffffffff169050600061117e61033a89602001516113fb565b9050600263ffffffff821610611196578760026103af565b60208701516111a59083611dfa565b6111b1578760026103af565b60006111be6020846137dc565b90506000806111d96040518060200160405280606081525090565b60208b01516111eb90858a8a876114b1565b909450909250905061801061120360208b018b613736565b61ffff1614156112485761123a848b600001518763ffffffff166002811061122d5761122d6137f0565b6020020151839190611704565b60208c0151604001526112c9565b61801161125860208b018b613736565b61ffff161415611287578951829063ffffffff87166002811061127d5761127d6137f0565b60200201526112c9565b60405162461bcd60e51b81526020600482015260176024820152764241445f474c4f42414c5f53544154455f4f50434f444560481b60448201526064016101b8565b505050505050505050505050565b60006112e961033a84602001516113fb565b9050600263ffffffff821610611318578260025b9081600381111561131057611310612f01565b905250505050565b61138061137583602001518363ffffffff166002811061133a5761133a6137f0565b602002015160408051808201909152600080825260208201525060408051808201909152600181526001600160401b03909116602082015290565b6020850151906117b6565b505050565b6000611397610a2b84602001516113fb565b905060006113ab61033a85602001516113fb565b9050600263ffffffff8216106113c5575050600290915250565b8183602001518263ffffffff16600281106113e2576113e26137f0565b6001600160401b03909216602092909202015250505050565b6040805180820190915260008082526020820152815161141a9061248e565b92915050565b6020810151600090818351600681111561143c5761143c612f01565b146114735760405162461bcd60e51b81526020600482015260076024820152662727aa2fa4999960c91b60448201526064016101b8565b640100000000811061141a5760405162461bcd60e51b81526020600482015260076024820152662120a22fa4999960c91b60448201526064016101b8565b6000806114ca6040518060200160405280606081525090565b8391506114d886868461240b565b90935091506114e886868461259e565b9250905060006114f9828986611704565b90508860400151811461153f5760405162461bcd60e51b815260206004820152600e60248201526d15d493d391d7d3515357d493d3d560921b60448201526064016101b8565b50955095509592505050565b60408051602080820181905281830181905260608201526080810185905260a0810184905260c08082018490528251808303909101815260e090910191829052600091829081906005906115a090859061398c565b600060405180830381855afa9150503d80600081146115db576040519150601f19603f3d011682016040523d82523d6000602084013e6115e0565b606091505b5091509150816116225760405162461bcd60e51b815260206004820152600d60248201526c1353d111561417d19052531151609a1b60448201526064016101b8565b80516020146116695760405162461bcd60e51b815260206004820152601360248201527209a9e888ab0a0beaea49e9c8ebe988a9c8ea89606b1b60448201526064016101b8565b611672816139a8565b93505050505b9392505050565b6000602083106116c95760405162461bcd60e51b81526020600482015260156024820152740848288bea68aa8be988a828cbe84b2a88abe9288b605b1b60448201526064016101b8565b6000836116d860016020613901565b6116e29190613901565b6116ed9060086138e2565b60ff848116821b911b198616179150509392505050565b6040516b26b2b6b7b93c903632b0b31d60a11b6020820152602c81018290526000908190604c0160405160208183030381529060405280519060200120905061177a8585836040518060400160405280601381526020017226b2b6b7b93c9036b2b935b632903a3932b29d60691b8152506120d9565b95945050505050565b604080518082019091526000808252602082015250604080518082019091526000815263ffffffff909116602082015290565b81516117c29082612678565b5050565b60208101516000906001835160068111156117e3576117e3612f01565b1461181a5760405162461bcd60e51b81526020600482015260076024820152661393d517d24d8d60ca1b60448201526064016101b8565b600160401b811061141a5760405162461bcd60e51b815260206004820152600760248201526610905117d24d8d60ca1b60448201526064016101b8565b6000602882101561189f5760405162461bcd60e51b81526020600482015260126024820152712120a22fa9a2a8a4a72127ac2fa82927a7a360711b60448201526064016101b8565b60006118ad84846020612427565b5080915050600084846040516118c4929190613821565b60405190819003902090506000806001600160401b03881615611984576118f160408a0160208b016139cc565b6001600160a01b03166316bf557961190a60018b6139f5565b6040516001600160e01b031960e084901b1681526001600160401b03909116600482015260240160206040518083038186803b15801561194957600080fd5b505afa15801561195d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119819190613887565b91505b6001600160401b03841615611a36576119a360408a0160208b016139cc565b6001600160a01b031663d5719dc26119bc6001876139f5565b6040516001600160e01b031960e084901b1681526001600160401b03909116600482015260240160206040518083038186803b1580156119fb57600080fd5b505afa158015611a0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a339190613887565b90505b604080516020810184905290810184905260608101829052600090608001604051602081830303815290604052805190602001209050896020016020810190611a7f91906139cc565b6040516316bf557960e01b81526001600160401b038b1660048201526001600160a01b0391909116906316bf55799060240160206040518083038186803b158015611ac957600080fd5b505afa158015611add573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b019190613887565b8114611b465760405162461bcd60e51b81526020600482015260146024820152734241445f534551494e424f585f4d45535341474560601b60448201526064016101b8565b6001955050505050505b949350505050565b60006071821015611b9f5760405162461bcd60e51b81526020600482015260116024820152702120a22fa222a620aca2a22fa82927a7a360791b60448201526064016101b8565b60006001600160401b03851615611c5357611bc060408701602088016139cc565b6001600160a01b031663d5719dc2611bd96001886139f5565b6040516001600160e01b031960e084901b1681526001600160401b03909116600482015260240160206040518083038186803b158015611c1857600080fd5b505afa158015611c2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c509190613887565b90505b6000611c62846071818861375a565b604051611c70929190613821565b60405180910390209050600085856000818110611c8f57611c8f6137f0565b9050013560f81c60f81b90506000611ca98787600161276b565b50905060008282611cbe607160218b8d61375a565b87604051602001611cd3959493929190613a1d565b60408051601f19818403018152828252805160209182012083820189905283830181905282518085038401815260609094019092528251920191909120909150611d2360408c0160208d016139cc565b604051636ab8cee160e11b81526001600160401b038c1660048201526001600160a01b03919091169063d5719dc29060240160206040518083038186803b158015611d6d57600080fd5b505afa158015611d81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611da59190613887565b8114611de95760405162461bcd60e51b81526020600482015260136024820152724241445f44454c415945445f4d45535341474560681b60448201526064016101b8565b5060019a9950505050505050505050565b81516000906001600160401b0316611e138360206137c4565b111580156116785750611e2760208361379a565b159392505050565b6000611e476040518060200160405280606081525090565b60408051602081019091526060815260408051808201909152601381527226b7b23ab6329036b2b935b632903a3932b29d60691b6020820152610160880151611e8e612d65565b6000611e9b89898c6127c0565b9a509150611eaa89898c612884565b9a509050611eb989898c61259e565b9a5063ffffffff8083169850909650600090611edb9088908a9086906128df16565b9050838114611f225760405162461bcd60e51b81526020600482015260136024820152722ba927a723afa927a7aa2fa327a92fa622a0a360691b60448201526064016101b8565b5050506000611f37866001610dd891906137c4565b90508015611f9057611f4a8660016137c4565b8551516001901b14611f8b5760405162461bcd60e51b815260206004820152600a6024820152692ba927a723afa622a0a360b11b60448201526064016101b8565b612002565b611f9b88888b61259e565b995093506000611fb9611faf8860016137c4565b86906000876120d9565b90508281146120005760405162461bcd60e51b815260206004820152601360248201527257524f4e475f524f4f545f464f525f5a45524f60681b60448201526064016101b8565b505b5050509450945094915050565b6000811580159061141a5750612026600183613901565b82161592915050565b600083855b60018111156120a15783828660405160200161205293929190613a5c565b60405160208183030381529060405280519060200120915083858660405160200161207f93929190613a5c565b60408051601f198184030181529190528051602090910120945060011c612034565b8388836040516020016120b693929190613a5c565b604051602081830303815290604052805190602001209250505095945050505050565b8160005b8551518110156121a2576001851661213e57828287600001518381518110612107576121076137f0565b602002602001015160405160200161212193929190613a5c565b604051602081830303815290604052805190602001209150612189565b8286600001518281518110612155576121556137f0565b60200260200101518360405160200161217093929190613a5c565b6040516020818303038152906040528051906020012091505b60019490941c938061219a81613806565b9150506120dd565b508315611b505760405162461bcd60e51b815260206004820152600f60248201526e141493d3d197d513d3d7d4d213d495608a1b60448201526064016101b8565b805160001914612220578051602080830151604051612203939201613a83565b60408051601f198184030181529190528051602091820120908201525b60009052565b6000808061223585858561240b565b9350915061224485858561240b565b935090506000198214156122975780156122705760405162461bcd60e51b81526004016101b890613aa5565b6020860151156122925760405162461bcd60e51b81526004016101b890613aa5565b612307565b856020015182826040516020016122af929190613a83565b60405160208183030381529060405280519060200120146123075760405162461bcd60e51b8152602060048201526012602482015271057524f4e475f434f5448524541445f504f560741b60448201526064016101b8565b6020860152909352505050565b6101408201516000906000191461232d5750600061141a565b600060408460e0015163ffffffff16901b9050602084610100015163ffffffff16901b811790506001838561012001516123679190613ad3565b6123719190613afb565b63ffffffff161761014084015250600192915050565b60408101515160a0820151516000198114806123a4575060001982145b156123b1578260026112fd565b6123be8360800151612920565b60a08401515260208301516123d2906129b9565b60408401515260808301516123ed9082602082015260609052565b50602091820151808301919091526040805192830190526060825252565b6000818161241a86868461276b565b9097909650945050505050565b600081815b6008811015612485576008836001600160401b0316901b9250858583818110612457576124576137f0565b919091013560f81c9390931792508161246f81613806565b925050808061247d90613806565b91505061242c565b50935093915050565b6040805180820190915260008082526020820152815180516124b290600190613901565b815181106124c2576124c26137f0565b60200260200101519050600060018360000151516124e09190613901565b6001600160401b038111156124f7576124f76131a8565b60405190808252806020026020018201604052801561253c57816020015b60408051808201909152600080825260208201528152602001906001900390816125155790505b50905060005b815181101561259757835180518290811061255f5761255f6137f0565b6020026020010151828281518110612579576125796137f0565b6020026020010181905250808061258f90613806565b915050612542565b5090915290565b6040805160208101909152606081528160006125bb868684612a3e565b92509050600060ff82166001600160401b038111156125dc576125dc6131a8565b604051908082528060200260200182016040528015612605578160200160208202803683370190505b50905060005b8260ff168160ff16101561265c5761262488888661240b565b838360ff1681518110612639576126396137f0565b6020026020010181965082815250505080806126549061393c565b91505061260b565b5060405180602001604052808281525093505050935093915050565b8151516000906126899060016137c4565b6001600160401b038111156126a0576126a06131a8565b6040519080825280602002602001820160405280156126e557816020015b60408051808201909152600080825260208201528152602001906001900390816126be5790505b50905060005b835151811015612741578351805182908110612709576127096137f0565b6020026020010151828281518110612723576127236137f0565b6020026020010181905250808061273990613806565b9150506126eb565b5081818460000151518151811061275a5761275a6137f0565b602090810291909101015290915250565b600081815b602081101561248557600883901b9250858583818110612792576127926137f0565b919091013560f81c939093179250816127aa81613806565b92505080806127b890613806565b915050612770565b6127c8612d65565b604080516060810182526000808252602082018190529181018290528391906000806000806127f88b8b8961240b565b975095506128078b8b89612a74565b975094506128168b8b8961240b565b975093506128258b8b8961240b565b975092506128348b8b8961240b565b975091506128438b8b89612884565b6040805160c081018252988952602089019790975295870194909452506060850191909152608084015263ffffffff1660a083015290969095509350505050565b600081815b60048110156124855760088363ffffffff16901b92508585838181106128b1576128b16137f0565b919091013560f81c939093179250816128c981613806565b92505080806128d790613806565b915050612889565b6000611b5084846128ef85612aef565b6040518060400160405280601381526020017226b7b23ab6329036b2b935b632903a3932b29d60691b8152506120d9565b602081015160005b8251518110156129b3576129588360000151828151811061294b5761294b6137f0565b6020026020010151612b6b565b6040517129ba30b1b590333930b6b29039ba30b1b59d60711b602082015260328101919091526052810183905260720160405160208183030381529060405280519060200120915080806129ab90613806565b915050612928565b50919050565b60208101518151515160005b81811015612a375783516129e2906129dd9083612bdb565b612c13565b6040516b2b30b63ab29039ba30b1b59d60a11b6020820152602c810191909152604c8101849052606c016040516020818303038152906040528051906020012092508080612a2f90613806565b9150506129c5565b5050919050565b600081848482818110612a5357612a536137f0565b919091013560f81c9250819050612a6981613806565b915050935093915050565b60408051606081018252600080825260208201819052918101919091528160008080612aa1888886612427565b94509250612ab0888886612427565b94509150612abf88888661240b565b604080516060810182526001600160401b0396871681529490951660208501529383015250969095509350505050565b60008160000151612b038360200151612c30565b6040808501516060860151608087015160a08801519351611135969594906020016626b7b23ab6329d60c91b81526007810196909652602786019490945260478501929092526067840152608783015260e01b6001600160e01b03191660a782015260ab0190565b6000612b7a8260000151612c13565b602080840151604080860151606087015191516b29ba30b1b590333930b6b29d60a11b94810194909452602c840194909452604c8301919091526001600160e01b031960e093841b8116606c840152921b9091166070820152607401611135565b60408051808201909152600080825260208201528251805183908110612c0357612c036137f0565b6020026020010151905092915050565b600081600001518260200151604051602001611135929190613b18565b805160208083015160408085015190516626b2b6b7b93c9d60c91b938101939093526001600160c01b031960c094851b811660278501529190931b16602f8201526037810191909152600090605701611135565b6040805161018081019091528060008152602001612cb960408051606080820183529181019182529081526000602082015290565b8152604080518082018252600080825260208083019190915283015201612cf760408051606080820183529181019182529081526000602082015290565b8152602001612d1c604051806040016040528060608152602001600080191681525090565b815260408051808201825260008082526020808301829052840191909152908201819052606082018190526080820181905260a0820181905260c0820181905260e09091015290565b6040805160c081019091526000815260208101612d9b604080516060810182526000808252602082018190529181019190915290565b8152600060208201819052604082018190526060820181905260809091015290565b612dc5613b4d565b565b6040518060400160405280612dda612dec565b8152602001612de7612dec565b905290565b60405180604001604052806002906020820280368337509192915050565b6000604082840312156129b357600080fd5b6000806000806000808688036101c080821215612e3857600080fd5b612e428a8a612e0a565b975060408901356001600160401b0380821115612e5e57600080fd5b818b01915082828d031215612e7257600080fd5b819850610100605f1985011215612e8857600080fd5b60608b019750612e9c8c6101608d01612e0a565b96506101a08b0135935080841115612eb357600080fd5b838b0193508b601f850112612ec757600080fd5b8335925080831115612ed857600080fd5b5050896020828401011115612eec57600080fd5b60208201935080925050509295509295509295565b634e487b7160e01b600052602160045260246000fd5b60048110612f2757612f27612f01565b9052565b805160078110612f3d57612f3d612f01565b8252602090810151910152565b805160408084529051602084830181905281516060860181905260009392820191849160808801905b80841015612f9a57612f86828651612f2b565b938201936001939093019290850190612f73565b509581015196019590955250919392505050565b8051604080845281518482018190526000926060916020918201918388019190865b82811015613019578451612fe5858251612f2b565b80830151858901528781015163ffffffff90811688870152908701511660808501529381019360a090930192600101612fd0565b509687015197909601969096525093949350505050565b60006101208083526130458184018651612f17565b60208501516101c061014081818701526130636102e0870184612f4a565b925060408801516101606130838189018380518252602090810151910152565b60608a0151915061011f1980898703016101a08a01526130a38684612f4a565b955060808b015192508089870301858a0152506130c08583612fae565b60a08b015180516101e08b015260208101516102008b0152909550935060c08a015161022089015260e08a015163ffffffff81166102408a015293506101008a015163ffffffff81166102608a015293509489015163ffffffff811661028089015294918901516102a0880152508701516102c0860152509150611678905060208301848051825260208101516001600160401b0380825116602085015280602083015116604085015250604081015160608401525060408101516080830152606081015160a0830152608081015160c083015263ffffffff60a08201511660e08301525050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b03811182821017156131e0576131e06131a8565b60405290565b604051602081016001600160401b03811182821017156131e0576131e06131a8565b604051608081016001600160401b03811182821017156131e0576131e06131a8565b60405161018081016001600160401b03811182821017156131e0576131e06131a8565b60405160c081016001600160401b03811182821017156131e0576131e06131a8565b604051606081016001600160401b03811182821017156131e0576131e06131a8565b604051601f8201601f191681016001600160401b03811182821017156132b9576132b96131a8565b604052919050565b8035600481106132d057600080fd5b919050565b60006001600160401b038211156132ee576132ee6131a8565b5060051b60200190565b60006040828403121561330a57600080fd5b6133126131be565b905081356007811061332357600080fd5b808252506020820135602082015292915050565b6000604080838503121561334a57600080fd5b6133526131be565b915082356001600160401b038082111561336b57600080fd5b8185019150602080838803121561338157600080fd5b6133896131e6565b83358381111561339857600080fd5b80850194505087601f8501126133ad57600080fd5b833592506133c26133bd846132d5565b613291565b83815260069390931b840182019282810190898511156133e157600080fd5b948301945b84861015613407576133f88a876132f8565b825294860194908301906133e6565b8252508552948501359484019490945250909392505050565b60006040828403121561343257600080fd5b61343a6131be565b9050813581526020820135602082015292915050565b803563ffffffff811681146132d057600080fd5b6000604080838503121561347757600080fd5b61347f6131be565b915082356001600160401b0381111561349757600080fd5b8301601f810185136134a857600080fd5b803560206134b86133bd836132d5565b82815260a092830284018201928282019190898511156134d757600080fd5b948301945b848610156135405780868b0312156134f45760008081fd5b6134fc613208565b6135068b886132f8565b81528787013585820152606061351d818901613450565b8983015261352d60808901613450565b90820152835294850194918301916134dc565b50808752505080860135818601525050505092915050565b60006101c0823603121561356b57600080fd5b61357361322a565b61357c836132c1565b815260208301356001600160401b038082111561359857600080fd5b6135a436838701613337565b60208401526135b63660408701613420565b604084015260808501359150808211156135cf57600080fd5b6135db36838701613337565b606084015260a08501359150808211156135f457600080fd5b5061360136828601613464565b6080830152506136143660c08501613420565b60a08201526101008084013560c0830152610120613633818601613450565b60e0840152610140613646818701613450565b83850152610160925061365a838701613450565b91840191909152610180850135908301526101a090930135928101929092525090565b80356001600160401b03811681146132d057600080fd5b60008183036101008112156136a857600080fd5b6136b061324d565b833581526060601f19830112156136c657600080fd5b6136ce61326f565b91506136dc6020850161367d565b82526136ea6040850161367d565b6020830152606084013560408301528160208201526080840135604082015260a0840135606082015260c0840135608082015261372960e08501613450565b60a0820152949350505050565b60006020828403121561374857600080fd5b813561ffff8116811461167857600080fd5b6000808585111561376a57600080fd5b8386111561377757600080fd5b5050820193919092039150565b634e487b7160e01b600052601260045260246000fd5b6000826137a9576137a9613784565b500690565b634e487b7160e01b600052601160045260246000fd5b600082198211156137d7576137d76137ae565b500190565b6000826137eb576137eb613784565b500490565b634e487b7160e01b600052603260045260246000fd5b600060001982141561381a5761381a6137ae565b5060010190565b8183823760009101908152919050565b6020808252600c908201526b4241445f505245494d41474560a01b604082015260600190565b6020808252601690820152752aa725a727aba72fa82922a4a6a0a3a2afa82927a7a360511b604082015260600190565b60006020828403121561389957600080fd5b5051919050565b8035602083101561141a57600019602084900360031b1b1692915050565b600080604083850312156138d157600080fd5b505080516020909101519092909150565b60008160001904831182151516156138fc576138fc6137ae565b500290565b600082821015613913576139136137ae565b500390565b600063ffffffff80831681811415613932576139326137ae565b6001019392505050565b600060ff821660ff811415613953576139536137ae565b60010192915050565b60005b8381101561397757818101518382015260200161395f565b83811115613986576000848401525b50505050565b6000825161399e81846020870161395c565b9190910192915050565b805160208083015191908110156129b35760001960209190910360031b1b16919050565b6000602082840312156139de57600080fd5b81356001600160a01b038116811461167857600080fd5b60006001600160401b0383811690831681811015613a1557613a156137ae565b039392505050565b6001600160f81b031986168152606085901b6bffffffffffffffffffffffff191660018201528284601583013760159201918201526035019392505050565b60008451613a6e81846020890161395c565b91909101928352506020820152604001919050565b6831b7ba343932b0b21d60b91b81526009810192909252602982015260490190565b60208082526014908201527357524f4e475f434f5448524541445f454d50545960601b604082015260600190565b600063ffffffff808316818516808303821115613af257613af26137ae565b01949350505050565b600063ffffffff83811690831681811015613a1557613a156137ae565b652b30b63ab29d60d11b8152600060078410613b3657613b36612f01565b5060f89290921b6006830152600782015260270190565b634e487b7160e01b600052605160045260246000fdfea26469706673582212205d08bb1a4317b988ca889fd9b2948ff407a0aaf15d9e442789c6ce9d58fd6f6a64736f6c63430008090033
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061002b5760003560e01c80633604366f14610030575b600080fd5b61004361003e366004612e1c565b61005a565b604051610051929190613030565b60405180910390f35b610062612c84565b61006a612d65565b61007387613558565b915061008436879003870187613694565b905060006100956020870187613736565b9050612dbd61801061ffff8316108015906100b6575061801361ffff831611155b156100c457506101e06101c1565b61ffff821661802014156100db57506103286101c1565b61ffff821661802114156100f257506109e56101c1565b61ffff821661802214156101095750610d0a6101c1565b61ffff821661802314156101205750610d166101c1565b61ffff821661802414156101375750610e3c6101c1565b61ffff8216618030141561014e5750610ee46101c1565b61ffff821661803114156101655750610f2b6101c1565b61ffff8216618032141561017c5750610f826101c1565b60405162461bcd60e51b8152602060048201526015602482015274494e56414c49445f4d454d4f52595f4f50434f444560581b60448201526064015b60405180910390fd5b6101d38a85858a8a8a8763ffffffff16565b5050965096945050505050565b60006101ef6020850185613736565b90506101f9612dc7565b6000610206858583610ff6565b60c08a01519193509150610219836110d1565b146102595760405162461bcd60e51b815260206004820152601060248201526f4241445f474c4f42414c5f535441544560801b60448201526064016101b8565b61ffff83166180101480610272575061ffff8316618011145b156102945761028f8888848961028a8987818d61375a565b611152565b61030c565b61ffff831661801214156102ac5761028f88836112d7565b61ffff831661801314156102c45761028f8883611385565b60405162461bcd60e51b815260206004820152601a60248201527f494e56414c49445f474c4f42414c53544154455f4f50434f444500000000000060448201526064016101b8565b610315826110d1565b60c0909801979097525050505050505050565b600061033f61033a87602001516113fb565b611420565b63ffffffff169050600061035961033a88602001516113fb565b63ffffffff16905061036c60208361379a565b1515806103925750602080870151516001600160401b0316906103909083906137c4565b115b806103a657506103a360208261379a565b15155b156103cd578660025b908160038111156103c2576103c2612f01565b8152505050506109dd565b60006103da6020836137dc565b90506000806103f56040518060200160405280606081525090565b60208a015161040790858a8a876114b1565b909450909250905060606000898986818110610425576104256137f0565b919091013560f81c915085905061043b81613806565b95505060208b01356105165760ff81166104fe5736600061045e8b88818f61375a565b91509150858282604051610473929190613821565b6040518091039020146104985760405162461bcd60e51b81526004016101b890613831565b60006104a58b60206137c4565b9050818111156104b25750805b6104be818c848661375a565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092975061096195505050505050565b60405162461bcd60e51b81526004016101b890613857565b8a60200135600114156105c75760ff8116156105445760405162461bcd60e51b81526004016101b890613857565b3660006105538b88818f61375a565b91509150856002838360405161056a929190613821565b602060405180830381855afa158015610587573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906105aa9190613887565b146104985760405162461bcd60e51b81526004016101b890613831565b8a60200135600214156109215760ff8116156105f55760405162461bcd60e51b81526004016101b890613857565b3660006106048b88818f61375a565b90925090508561061860206000848661375a565b610621916138a0565b146106655760405162461bcd60e51b8152602060048201526014602482015273096b48ebea0a49e9e8cbeaea49e9c8ebe9082a6960631b60448201526064016101b8565b600080600080600a6001600160a01b03168686604051610686929190613821565b600060405180830381855afa9150503d80600081146106c1576040519150601f19603f3d011682016040523d82523d6000602084013e6106c6565b606091505b50915091508161070c5760405162461bcd60e51b815260206004820152601160248201527024a72b20a624a22fa5ad23afa82927a7a360791b60448201526064016101b8565b60008151116107565760405162461bcd60e51b81526020600482015260166024820152754b5a475f505245434f4d50494c455f4d495353494e4760501b60448201526064016101b8565b8080602001905181019061076a91906138be565b9094509250507f73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001821490506107d75760405162461bcd60e51b8152602060048201526013602482015272554e4b4e4f574e5f424c535f4d4f44554c555360681b60448201526064016101b8565b6107e28260206138e2565b8c1015610918576000806107f760208f6137dc565b905060015b8481101561082657600192831b92828116141561081a576001831792505b600191821c911b6107fc565b506000610838856401000000006137dc565b905061084483826138e2565b905060006108737f16a2a19edfe81f20d09b681922c813b4b63683508c2280b93829971f439f0d2b838761154b565b905080610884604060208a8c61375a565b61088d916138a0565b146108ce5760405162461bcd60e51b815260206004820152601160248201527025ad23afa82927a7a32faba927a723afad60791b60448201526064016101b8565b6108dc60606040898b61375a565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929c50505050505050505b50505050610961565b60405162461bcd60e51b8152602060048201526015602482015274554e4b4e4f574e5f505245494d4147455f5459504560581b60448201526064016101b8565b60005b82518110156109a5576109918582858481518110610984576109846137f0565b016020015160f81c61167f565b94508061099d81613806565b915050610964565b506109b1838786611704565b60208d01516040015281516109d4906109c990611783565b60208f0151906117b6565b50505050505050505b505050505050565b60006109f761033a87602001516113fb565b63ffffffff1690506000610a1161033a88602001516113fb565b63ffffffff1690506000610a30610a2b89602001516113fb565b6117c6565b6001600160401b031690506020860135158015610a4e575088358110155b15610a76578760035b90816003811115610a6a57610a6a612f01565b815250505050506109dd565b602080880151516001600160401b031690610a929084906137c4565b1180610aa75750610aa460208361379a565b15155b15610ab457876002610a57565b6000610ac16020846137dc565b9050600080610adc6040518060200160405280606081525090565b60208b0151610aee90858b8b876114b1565b9094509092509050888884818110610b0857610b086137f0565b909101356001600160f81b031916159050610b5b5760405162461bcd60e51b81526020600482015260136024820152722aa725a727aba72fa4a72127ac2fa82927a7a360691b60448201526064016101b8565b82610b6581613806565b935050612dbd6000808c602001351415610b83576118579150610bc3565b60018c602001351415610b9a57611b589150610bc3565b8d60025b90816003811115610bb157610bb1612f01565b815250505050505050505050506109dd565b610be38f888d8d89908092610bda9392919061375a565b8663ffffffff16565b905080610bf2578d6002610b9e565b505082881015610c385760405162461bcd60e51b81526020600482015260116024820152702120a22fa6a2a9a9a0a3a2afa82927a7a360791b60448201526064016101b8565b6000610c44848a613901565b905060005b60208163ffffffff16108015610c6d575081610c6b63ffffffff83168b6137c4565b105b15610cc657610cb28463ffffffff83168d8d82610c8a8f8c6137c4565b610c9491906137c4565b818110610ca357610ca36137f0565b919091013560f81c905061167f565b935080610cbe81613918565b915050610c49565b610cd1838786611704565b60208e015160400152610cf9610ce682611783565b8f602001516117b690919063ffffffff16565b505050505050505050505050505050565b50506001909252505050565b60006040518060400160405280601381526020017226b7b23ab6329036b2b935b632903a3932b29d60691b8152509050600086610160015190506000610d6261033a89602001516113fb565b63ffffffff169050610d81818860200151611dfa90919063ffffffff16565b610d8d57876002610a57565b600080610dad610d9e6020856137dc565b60208b015190898960006114b1565b5091509150600080610dc18c848b8b611e2f565b92505091506000610ddd836001610dd891906137c4565b61200f565b90508015610e0857610dfd87610df48560016137c4565b8760008c61202f565b6101608e0152610e26565b610e1f610e168460016137c4565b8390878b6120d9565b6101608e01525b6109d46109c9610e378560016137c4565b611783565b60408051808201909152601381527226b7b23ab6329036b2b935b632903a3932b29d60691b6020820152600080610e7588828787611e2f565b50915091506000610e858361200f565b90508015610ec45781518051610e9d90600190613901565b81518110610ead57610ead6137f0565b602002602001015189610160018181525050610ed8565b610ed182846000876120d9565b6101608a01525b50505050505050505050565b61014085015160001914610f11578460025b90816003811115610f0957610f09612f01565b9052506109dd565b610f1e8560a001516121e3565b6109dd85604001516121e3565b61014085015160001914610f4157846002610ef6565b60a0850151516000191415610f5857846002610ef6565b610f6785604001518383612226565b60a08501516109dd90610f7d836040818761375a565b612226565b60a0850151516000191415610f9957846002610ef6565b6020830135610fc7576101408501516000191415610fb957846002610ef6565b600019610140860152610fed565b61014085015160001914610fdd57846002610ef6565b610feb856020850135612314565b505b6109dd85612387565b610ffe612dc7565b81611007612dec565b61100f612dec565b60005b600260ff8216101561105a5761102988888661240b565b848360ff166002811061103e5761103e6137f0565b60200201919091529350806110528161393c565b915050611012565b5060005b600260ff821610156110b457611075888886612427565b838360ff166002811061108a5761108a6137f0565b6001600160401b0390931660209390930201919091529350806110ac8161393c565b91505061105e565b506040805180820190915291825260208201529590945092505050565b80518051602091820151828401518051908401516040516c23b637b130b61039ba30ba329d60991b95810195909552602d850193909352604d8401919091526001600160c01b031960c091821b8116606d85015291901b166075820152600090607d015b604051602081830303815290604052805190602001209050919050565b600061116461033a88602001516113fb565b63ffffffff169050600061117e61033a89602001516113fb565b9050600263ffffffff821610611196578760026103af565b60208701516111a59083611dfa565b6111b1578760026103af565b60006111be6020846137dc565b90506000806111d96040518060200160405280606081525090565b60208b01516111eb90858a8a876114b1565b909450909250905061801061120360208b018b613736565b61ffff1614156112485761123a848b600001518763ffffffff166002811061122d5761122d6137f0565b6020020151839190611704565b60208c0151604001526112c9565b61801161125860208b018b613736565b61ffff161415611287578951829063ffffffff87166002811061127d5761127d6137f0565b60200201526112c9565b60405162461bcd60e51b81526020600482015260176024820152764241445f474c4f42414c5f53544154455f4f50434f444560481b60448201526064016101b8565b505050505050505050505050565b60006112e961033a84602001516113fb565b9050600263ffffffff821610611318578260025b9081600381111561131057611310612f01565b905250505050565b61138061137583602001518363ffffffff166002811061133a5761133a6137f0565b602002015160408051808201909152600080825260208201525060408051808201909152600181526001600160401b03909116602082015290565b6020850151906117b6565b505050565b6000611397610a2b84602001516113fb565b905060006113ab61033a85602001516113fb565b9050600263ffffffff8216106113c5575050600290915250565b8183602001518263ffffffff16600281106113e2576113e26137f0565b6001600160401b03909216602092909202015250505050565b6040805180820190915260008082526020820152815161141a9061248e565b92915050565b6020810151600090818351600681111561143c5761143c612f01565b146114735760405162461bcd60e51b81526020600482015260076024820152662727aa2fa4999960c91b60448201526064016101b8565b640100000000811061141a5760405162461bcd60e51b81526020600482015260076024820152662120a22fa4999960c91b60448201526064016101b8565b6000806114ca6040518060200160405280606081525090565b8391506114d886868461240b565b90935091506114e886868461259e565b9250905060006114f9828986611704565b90508860400151811461153f5760405162461bcd60e51b815260206004820152600e60248201526d15d493d391d7d3515357d493d3d560921b60448201526064016101b8565b50955095509592505050565b60408051602080820181905281830181905260608201526080810185905260a0810184905260c08082018490528251808303909101815260e090910191829052600091829081906005906115a090859061398c565b600060405180830381855afa9150503d80600081146115db576040519150601f19603f3d011682016040523d82523d6000602084013e6115e0565b606091505b5091509150816116225760405162461bcd60e51b815260206004820152600d60248201526c1353d111561417d19052531151609a1b60448201526064016101b8565b80516020146116695760405162461bcd60e51b815260206004820152601360248201527209a9e888ab0a0beaea49e9c8ebe988a9c8ea89606b1b60448201526064016101b8565b611672816139a8565b93505050505b9392505050565b6000602083106116c95760405162461bcd60e51b81526020600482015260156024820152740848288bea68aa8be988a828cbe84b2a88abe9288b605b1b60448201526064016101b8565b6000836116d860016020613901565b6116e29190613901565b6116ed9060086138e2565b60ff848116821b911b198616179150509392505050565b6040516b26b2b6b7b93c903632b0b31d60a11b6020820152602c81018290526000908190604c0160405160208183030381529060405280519060200120905061177a8585836040518060400160405280601381526020017226b2b6b7b93c9036b2b935b632903a3932b29d60691b8152506120d9565b95945050505050565b604080518082019091526000808252602082015250604080518082019091526000815263ffffffff909116602082015290565b81516117c29082612678565b5050565b60208101516000906001835160068111156117e3576117e3612f01565b1461181a5760405162461bcd60e51b81526020600482015260076024820152661393d517d24d8d60ca1b60448201526064016101b8565b600160401b811061141a5760405162461bcd60e51b815260206004820152600760248201526610905117d24d8d60ca1b60448201526064016101b8565b6000602882101561189f5760405162461bcd60e51b81526020600482015260126024820152712120a22fa9a2a8a4a72127ac2fa82927a7a360711b60448201526064016101b8565b60006118ad84846020612427565b5080915050600084846040516118c4929190613821565b60405190819003902090506000806001600160401b03881615611984576118f160408a0160208b016139cc565b6001600160a01b03166316bf557961190a60018b6139f5565b6040516001600160e01b031960e084901b1681526001600160401b03909116600482015260240160206040518083038186803b15801561194957600080fd5b505afa15801561195d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119819190613887565b91505b6001600160401b03841615611a36576119a360408a0160208b016139cc565b6001600160a01b031663d5719dc26119bc6001876139f5565b6040516001600160e01b031960e084901b1681526001600160401b03909116600482015260240160206040518083038186803b1580156119fb57600080fd5b505afa158015611a0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a339190613887565b90505b604080516020810184905290810184905260608101829052600090608001604051602081830303815290604052805190602001209050896020016020810190611a7f91906139cc565b6040516316bf557960e01b81526001600160401b038b1660048201526001600160a01b0391909116906316bf55799060240160206040518083038186803b158015611ac957600080fd5b505afa158015611add573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b019190613887565b8114611b465760405162461bcd60e51b81526020600482015260146024820152734241445f534551494e424f585f4d45535341474560601b60448201526064016101b8565b6001955050505050505b949350505050565b60006071821015611b9f5760405162461bcd60e51b81526020600482015260116024820152702120a22fa222a620aca2a22fa82927a7a360791b60448201526064016101b8565b60006001600160401b03851615611c5357611bc060408701602088016139cc565b6001600160a01b031663d5719dc2611bd96001886139f5565b6040516001600160e01b031960e084901b1681526001600160401b03909116600482015260240160206040518083038186803b158015611c1857600080fd5b505afa158015611c2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c509190613887565b90505b6000611c62846071818861375a565b604051611c70929190613821565b60405180910390209050600085856000818110611c8f57611c8f6137f0565b9050013560f81c60f81b90506000611ca98787600161276b565b50905060008282611cbe607160218b8d61375a565b87604051602001611cd3959493929190613a1d565b60408051601f19818403018152828252805160209182012083820189905283830181905282518085038401815260609094019092528251920191909120909150611d2360408c0160208d016139cc565b604051636ab8cee160e11b81526001600160401b038c1660048201526001600160a01b03919091169063d5719dc29060240160206040518083038186803b158015611d6d57600080fd5b505afa158015611d81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611da59190613887565b8114611de95760405162461bcd60e51b81526020600482015260136024820152724241445f44454c415945445f4d45535341474560681b60448201526064016101b8565b5060019a9950505050505050505050565b81516000906001600160401b0316611e138360206137c4565b111580156116785750611e2760208361379a565b159392505050565b6000611e476040518060200160405280606081525090565b60408051602081019091526060815260408051808201909152601381527226b7b23ab6329036b2b935b632903a3932b29d60691b6020820152610160880151611e8e612d65565b6000611e9b89898c6127c0565b9a509150611eaa89898c612884565b9a509050611eb989898c61259e565b9a5063ffffffff8083169850909650600090611edb9088908a9086906128df16565b9050838114611f225760405162461bcd60e51b81526020600482015260136024820152722ba927a723afa927a7aa2fa327a92fa622a0a360691b60448201526064016101b8565b5050506000611f37866001610dd891906137c4565b90508015611f9057611f4a8660016137c4565b8551516001901b14611f8b5760405162461bcd60e51b815260206004820152600a6024820152692ba927a723afa622a0a360b11b60448201526064016101b8565b612002565b611f9b88888b61259e565b995093506000611fb9611faf8860016137c4565b86906000876120d9565b90508281146120005760405162461bcd60e51b815260206004820152601360248201527257524f4e475f524f4f545f464f525f5a45524f60681b60448201526064016101b8565b505b5050509450945094915050565b6000811580159061141a5750612026600183613901565b82161592915050565b600083855b60018111156120a15783828660405160200161205293929190613a5c565b60405160208183030381529060405280519060200120915083858660405160200161207f93929190613a5c565b60408051601f198184030181529190528051602090910120945060011c612034565b8388836040516020016120b693929190613a5c565b604051602081830303815290604052805190602001209250505095945050505050565b8160005b8551518110156121a2576001851661213e57828287600001518381518110612107576121076137f0565b602002602001015160405160200161212193929190613a5c565b604051602081830303815290604052805190602001209150612189565b8286600001518281518110612155576121556137f0565b60200260200101518360405160200161217093929190613a5c565b6040516020818303038152906040528051906020012091505b60019490941c938061219a81613806565b9150506120dd565b508315611b505760405162461bcd60e51b815260206004820152600f60248201526e141493d3d197d513d3d7d4d213d495608a1b60448201526064016101b8565b805160001914612220578051602080830151604051612203939201613a83565b60408051601f198184030181529190528051602091820120908201525b60009052565b6000808061223585858561240b565b9350915061224485858561240b565b935090506000198214156122975780156122705760405162461bcd60e51b81526004016101b890613aa5565b6020860151156122925760405162461bcd60e51b81526004016101b890613aa5565b612307565b856020015182826040516020016122af929190613a83565b60405160208183030381529060405280519060200120146123075760405162461bcd60e51b8152602060048201526012602482015271057524f4e475f434f5448524541445f504f560741b60448201526064016101b8565b6020860152909352505050565b6101408201516000906000191461232d5750600061141a565b600060408460e0015163ffffffff16901b9050602084610100015163ffffffff16901b811790506001838561012001516123679190613ad3565b6123719190613afb565b63ffffffff161761014084015250600192915050565b60408101515160a0820151516000198114806123a4575060001982145b156123b1578260026112fd565b6123be8360800151612920565b60a08401515260208301516123d2906129b9565b60408401515260808301516123ed9082602082015260609052565b50602091820151808301919091526040805192830190526060825252565b6000818161241a86868461276b565b9097909650945050505050565b600081815b6008811015612485576008836001600160401b0316901b9250858583818110612457576124576137f0565b919091013560f81c9390931792508161246f81613806565b925050808061247d90613806565b91505061242c565b50935093915050565b6040805180820190915260008082526020820152815180516124b290600190613901565b815181106124c2576124c26137f0565b60200260200101519050600060018360000151516124e09190613901565b6001600160401b038111156124f7576124f76131a8565b60405190808252806020026020018201604052801561253c57816020015b60408051808201909152600080825260208201528152602001906001900390816125155790505b50905060005b815181101561259757835180518290811061255f5761255f6137f0565b6020026020010151828281518110612579576125796137f0565b6020026020010181905250808061258f90613806565b915050612542565b5090915290565b6040805160208101909152606081528160006125bb868684612a3e565b92509050600060ff82166001600160401b038111156125dc576125dc6131a8565b604051908082528060200260200182016040528015612605578160200160208202803683370190505b50905060005b8260ff168160ff16101561265c5761262488888661240b565b838360ff1681518110612639576126396137f0565b6020026020010181965082815250505080806126549061393c565b91505061260b565b5060405180602001604052808281525093505050935093915050565b8151516000906126899060016137c4565b6001600160401b038111156126a0576126a06131a8565b6040519080825280602002602001820160405280156126e557816020015b60408051808201909152600080825260208201528152602001906001900390816126be5790505b50905060005b835151811015612741578351805182908110612709576127096137f0565b6020026020010151828281518110612723576127236137f0565b6020026020010181905250808061273990613806565b9150506126eb565b5081818460000151518151811061275a5761275a6137f0565b602090810291909101015290915250565b600081815b602081101561248557600883901b9250858583818110612792576127926137f0565b919091013560f81c939093179250816127aa81613806565b92505080806127b890613806565b915050612770565b6127c8612d65565b604080516060810182526000808252602082018190529181018290528391906000806000806127f88b8b8961240b565b975095506128078b8b89612a74565b975094506128168b8b8961240b565b975093506128258b8b8961240b565b975092506128348b8b8961240b565b975091506128438b8b89612884565b6040805160c081018252988952602089019790975295870194909452506060850191909152608084015263ffffffff1660a083015290969095509350505050565b600081815b60048110156124855760088363ffffffff16901b92508585838181106128b1576128b16137f0565b919091013560f81c939093179250816128c981613806565b92505080806128d790613806565b915050612889565b6000611b5084846128ef85612aef565b6040518060400160405280601381526020017226b7b23ab6329036b2b935b632903a3932b29d60691b8152506120d9565b602081015160005b8251518110156129b3576129588360000151828151811061294b5761294b6137f0565b6020026020010151612b6b565b6040517129ba30b1b590333930b6b29039ba30b1b59d60711b602082015260328101919091526052810183905260720160405160208183030381529060405280519060200120915080806129ab90613806565b915050612928565b50919050565b60208101518151515160005b81811015612a375783516129e2906129dd9083612bdb565b612c13565b6040516b2b30b63ab29039ba30b1b59d60a11b6020820152602c810191909152604c8101849052606c016040516020818303038152906040528051906020012092508080612a2f90613806565b9150506129c5565b5050919050565b600081848482818110612a5357612a536137f0565b919091013560f81c9250819050612a6981613806565b915050935093915050565b60408051606081018252600080825260208201819052918101919091528160008080612aa1888886612427565b94509250612ab0888886612427565b94509150612abf88888661240b565b604080516060810182526001600160401b0396871681529490951660208501529383015250969095509350505050565b60008160000151612b038360200151612c30565b6040808501516060860151608087015160a08801519351611135969594906020016626b7b23ab6329d60c91b81526007810196909652602786019490945260478501929092526067840152608783015260e01b6001600160e01b03191660a782015260ab0190565b6000612b7a8260000151612c13565b602080840151604080860151606087015191516b29ba30b1b590333930b6b29d60a11b94810194909452602c840194909452604c8301919091526001600160e01b031960e093841b8116606c840152921b9091166070820152607401611135565b60408051808201909152600080825260208201528251805183908110612c0357612c036137f0565b6020026020010151905092915050565b600081600001518260200151604051602001611135929190613b18565b805160208083015160408085015190516626b2b6b7b93c9d60c91b938101939093526001600160c01b031960c094851b811660278501529190931b16602f8201526037810191909152600090605701611135565b6040805161018081019091528060008152602001612cb960408051606080820183529181019182529081526000602082015290565b8152604080518082018252600080825260208083019190915283015201612cf760408051606080820183529181019182529081526000602082015290565b8152602001612d1c604051806040016040528060608152602001600080191681525090565b815260408051808201825260008082526020808301829052840191909152908201819052606082018190526080820181905260a0820181905260c0820181905260e09091015290565b6040805160c081019091526000815260208101612d9b604080516060810182526000808252602082018190529181019190915290565b8152600060208201819052604082018190526060820181905260809091015290565b612dc5613b4d565b565b6040518060400160405280612dda612dec565b8152602001612de7612dec565b905290565b60405180604001604052806002906020820280368337509192915050565b6000604082840312156129b357600080fd5b6000806000806000808688036101c080821215612e3857600080fd5b612e428a8a612e0a565b975060408901356001600160401b0380821115612e5e57600080fd5b818b01915082828d031215612e7257600080fd5b819850610100605f1985011215612e8857600080fd5b60608b019750612e9c8c6101608d01612e0a565b96506101a08b0135935080841115612eb357600080fd5b838b0193508b601f850112612ec757600080fd5b8335925080831115612ed857600080fd5b5050896020828401011115612eec57600080fd5b60208201935080925050509295509295509295565b634e487b7160e01b600052602160045260246000fd5b60048110612f2757612f27612f01565b9052565b805160078110612f3d57612f3d612f01565b8252602090810151910152565b805160408084529051602084830181905281516060860181905260009392820191849160808801905b80841015612f9a57612f86828651612f2b565b938201936001939093019290850190612f73565b509581015196019590955250919392505050565b8051604080845281518482018190526000926060916020918201918388019190865b82811015613019578451612fe5858251612f2b565b80830151858901528781015163ffffffff90811688870152908701511660808501529381019360a090930192600101612fd0565b509687015197909601969096525093949350505050565b60006101208083526130458184018651612f17565b60208501516101c061014081818701526130636102e0870184612f4a565b925060408801516101606130838189018380518252602090810151910152565b60608a0151915061011f1980898703016101a08a01526130a38684612f4a565b955060808b015192508089870301858a0152506130c08583612fae565b60a08b015180516101e08b015260208101516102008b0152909550935060c08a015161022089015260e08a015163ffffffff81166102408a015293506101008a015163ffffffff81166102608a015293509489015163ffffffff811661028089015294918901516102a0880152508701516102c0860152509150611678905060208301848051825260208101516001600160401b0380825116602085015280602083015116604085015250604081015160608401525060408101516080830152606081015160a0830152608081015160c083015263ffffffff60a08201511660e08301525050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b03811182821017156131e0576131e06131a8565b60405290565b604051602081016001600160401b03811182821017156131e0576131e06131a8565b604051608081016001600160401b03811182821017156131e0576131e06131a8565b60405161018081016001600160401b03811182821017156131e0576131e06131a8565b60405160c081016001600160401b03811182821017156131e0576131e06131a8565b604051606081016001600160401b03811182821017156131e0576131e06131a8565b604051601f8201601f191681016001600160401b03811182821017156132b9576132b96131a8565b604052919050565b8035600481106132d057600080fd5b919050565b60006001600160401b038211156132ee576132ee6131a8565b5060051b60200190565b60006040828403121561330a57600080fd5b6133126131be565b905081356007811061332357600080fd5b808252506020820135602082015292915050565b6000604080838503121561334a57600080fd5b6133526131be565b915082356001600160401b038082111561336b57600080fd5b8185019150602080838803121561338157600080fd5b6133896131e6565b83358381111561339857600080fd5b80850194505087601f8501126133ad57600080fd5b833592506133c26133bd846132d5565b613291565b83815260069390931b840182019282810190898511156133e157600080fd5b948301945b84861015613407576133f88a876132f8565b825294860194908301906133e6565b8252508552948501359484019490945250909392505050565b60006040828403121561343257600080fd5b61343a6131be565b9050813581526020820135602082015292915050565b803563ffffffff811681146132d057600080fd5b6000604080838503121561347757600080fd5b61347f6131be565b915082356001600160401b0381111561349757600080fd5b8301601f810185136134a857600080fd5b803560206134b86133bd836132d5565b82815260a092830284018201928282019190898511156134d757600080fd5b948301945b848610156135405780868b0312156134f45760008081fd5b6134fc613208565b6135068b886132f8565b81528787013585820152606061351d818901613450565b8983015261352d60808901613450565b90820152835294850194918301916134dc565b50808752505080860135818601525050505092915050565b60006101c0823603121561356b57600080fd5b61357361322a565b61357c836132c1565b815260208301356001600160401b038082111561359857600080fd5b6135a436838701613337565b60208401526135b63660408701613420565b604084015260808501359150808211156135cf57600080fd5b6135db36838701613337565b606084015260a08501359150808211156135f457600080fd5b5061360136828601613464565b6080830152506136143660c08501613420565b60a08201526101008084013560c0830152610120613633818601613450565b60e0840152610140613646818701613450565b83850152610160925061365a838701613450565b91840191909152610180850135908301526101a090930135928101929092525090565b80356001600160401b03811681146132d057600080fd5b60008183036101008112156136a857600080fd5b6136b061324d565b833581526060601f19830112156136c657600080fd5b6136ce61326f565b91506136dc6020850161367d565b82526136ea6040850161367d565b6020830152606084013560408301528160208201526080840135604082015260a0840135606082015260c0840135608082015261372960e08501613450565b60a0820152949350505050565b60006020828403121561374857600080fd5b813561ffff8116811461167857600080fd5b6000808585111561376a57600080fd5b8386111561377757600080fd5b5050820193919092039150565b634e487b7160e01b600052601260045260246000fd5b6000826137a9576137a9613784565b500690565b634e487b7160e01b600052601160045260246000fd5b600082198211156137d7576137d76137ae565b500190565b6000826137eb576137eb613784565b500490565b634e487b7160e01b600052603260045260246000fd5b600060001982141561381a5761381a6137ae565b5060010190565b8183823760009101908152919050565b6020808252600c908201526b4241445f505245494d41474560a01b604082015260600190565b6020808252601690820152752aa725a727aba72fa82922a4a6a0a3a2afa82927a7a360511b604082015260600190565b60006020828403121561389957600080fd5b5051919050565b8035602083101561141a57600019602084900360031b1b1692915050565b600080604083850312156138d157600080fd5b505080516020909101519092909150565b60008160001904831182151516156138fc576138fc6137ae565b500290565b600082821015613913576139136137ae565b500390565b600063ffffffff80831681811415613932576139326137ae565b6001019392505050565b600060ff821660ff811415613953576139536137ae565b60010192915050565b60005b8381101561397757818101518382015260200161395f565b83811115613986576000848401525b50505050565b6000825161399e81846020870161395c565b9190910192915050565b805160208083015191908110156129b35760001960209190910360031b1b16919050565b6000602082840312156139de57600080fd5b81356001600160a01b038116811461167857600080fd5b60006001600160401b0383811690831681811015613a1557613a156137ae565b039392505050565b6001600160f81b031986168152606085901b6bffffffffffffffffffffffff191660018201528284601583013760159201918201526035019392505050565b60008451613a6e81846020890161395c565b91909101928352506020820152604001919050565b6831b7ba343932b0b21d60b91b81526009810192909252602982015260490190565b60208082526014908201527357524f4e475f434f5448524541445f454d50545960601b604082015260600190565b600063ffffffff808316818516808303821115613af257613af26137ae565b01949350505050565b600063ffffffff83811690831681811015613a1557613a156137ae565b652b30b63ab29d60d11b8152600060078410613b3657613b36612f01565b5060f89290921b6006830152600782015260270190565b634e487b7160e01b600052605160045260246000fdfea26469706673582212205d08bb1a4317b988ca889fd9b2948ff407a0aaf15d9e442789c6ce9d58fd6f6a64736f6c63430008090033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.