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:
OneStepProver0
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-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 "../state/Value.sol"; import "../state/Machine.sol"; import "../state/Module.sol"; import "../state/Deserialize.sol"; import "./IOneStepProver.sol"; contract OneStepProver0 is IOneStepProver { using MachineLib for Machine; using MerkleProofLib for MerkleProof; using StackFrameLib for StackFrameWindow; using ValueLib for Value; using ValueStackLib for ValueStack; function executeUnreachable( Machine memory mach, Module memory, Instruction calldata, bytes calldata ) internal pure { mach.status = MachineStatus.ERRORED; } function executeNop( Machine memory mach, Module memory, Instruction calldata, bytes calldata ) internal pure { // :) } function executeConstPush( Machine memory mach, Module memory, Instruction calldata inst, bytes calldata ) internal pure { uint16 opcode = inst.opcode; ValueType ty; if (opcode == Instructions.I32_CONST) { ty = ValueType.I32; } else if (opcode == Instructions.I64_CONST) { ty = ValueType.I64; } else if (opcode == Instructions.F32_CONST) { ty = ValueType.F32; } else if (opcode == Instructions.F64_CONST) { ty = ValueType.F64; } else { revert("CONST_PUSH_INVALID_OPCODE"); } mach.valueStack.push(Value({valueType: ty, contents: uint64(inst.argumentData)})); } function executeDrop( Machine memory mach, Module memory, Instruction calldata, bytes calldata ) internal pure { mach.valueStack.pop(); } function executeSelect( Machine memory mach, Module memory, Instruction calldata, bytes calldata ) internal pure { uint32 selector = mach.valueStack.pop().assumeI32(); Value memory b = mach.valueStack.pop(); Value memory a = mach.valueStack.pop(); if (selector != 0) { mach.valueStack.push(a); } else { mach.valueStack.push(b); } } function executeReturn( Machine memory mach, Module memory, Instruction calldata, bytes calldata ) internal pure { StackFrame memory frame = mach.frameStack.pop(); mach.setPc(frame.returnPc); } function createReturnValue(Machine memory mach) internal pure returns (Value memory) { return ValueLib.newPc(mach.functionPc, mach.functionIdx, mach.moduleIdx); } function executeCall( Machine memory mach, Module memory, Instruction calldata inst, bytes calldata ) internal pure { // Push the return pc to the stack mach.valueStack.push(createReturnValue(mach)); // Push caller module info to the stack StackFrame memory frame = mach.frameStack.peek(); mach.valueStack.push(ValueLib.newI32(frame.callerModule)); mach.valueStack.push(ValueLib.newI32(frame.callerModuleInternals)); // Jump to the target uint32 idx = uint32(inst.argumentData); require(idx == inst.argumentData, "BAD_CALL_DATA"); mach.functionIdx = idx; mach.functionPc = 0; } function executeCrossModuleCall( Machine memory mach, Module memory mod, Instruction calldata inst, bytes calldata ) internal pure { // Push the return pc to the stack mach.valueStack.push(createReturnValue(mach)); // Push caller module info to the stack mach.valueStack.push(ValueLib.newI32(mach.moduleIdx)); mach.valueStack.push(ValueLib.newI32(mod.internalsOffset)); // Jump to the target uint32 func = uint32(inst.argumentData); uint32 module = uint32(inst.argumentData >> 32); require(inst.argumentData >> 64 == 0, "BAD_CROSS_MODULE_CALL_DATA"); mach.moduleIdx = module; mach.functionIdx = func; mach.functionPc = 0; } function executeCrossModuleForward( Machine memory mach, Module memory, Instruction calldata inst, bytes calldata ) internal pure { // Push the return pc to the stack mach.valueStack.push(createReturnValue(mach)); // Push caller's caller module info to the stack StackFrame memory frame = mach.frameStack.peek(); mach.valueStack.push(ValueLib.newI32(frame.callerModule)); mach.valueStack.push(ValueLib.newI32(frame.callerModuleInternals)); // Jump to the target uint32 func = uint32(inst.argumentData); uint32 module = uint32(inst.argumentData >> 32); require(inst.argumentData >> 64 == 0, "BAD_CROSS_MODULE_CALL_DATA"); mach.moduleIdx = module; mach.functionIdx = func; mach.functionPc = 0; } function executeCrossModuleInternalCall( Machine memory mach, Module memory mod, Instruction calldata inst, bytes calldata proof ) internal pure { // Get the target from the stack uint32 internalIndex = uint32(inst.argumentData); uint32 moduleIndex = mach.valueStack.pop().assumeI32(); Module memory calledMod; MerkleProof memory modProof; uint256 offset = 0; (calledMod, offset) = Deserialize.module(proof, offset); (modProof, offset) = Deserialize.merkleProof(proof, offset); require( modProof.computeRootFromModule(moduleIndex, calledMod) == mach.modulesRoot, "CROSS_MODULE_INTERNAL_MODULES_ROOT" ); // Push the return pc to the stack mach.valueStack.push(createReturnValue(mach)); // Push caller module info to the stack mach.valueStack.push(ValueLib.newI32(mach.moduleIdx)); mach.valueStack.push(ValueLib.newI32(mod.internalsOffset)); // Jump to the target mach.moduleIdx = moduleIndex; mach.functionIdx = internalIndex + calledMod.internalsOffset; mach.functionPc = 0; } function executeCallerModuleInternalCall( Machine memory mach, Module memory mod, Instruction calldata inst, bytes calldata ) internal pure { // Push the return pc to the stack mach.valueStack.push(createReturnValue(mach)); // Push caller module info to the stack mach.valueStack.push(ValueLib.newI32(mach.moduleIdx)); mach.valueStack.push(ValueLib.newI32(mod.internalsOffset)); StackFrame memory frame = mach.frameStack.peek(); if (frame.callerModuleInternals == 0) { // The caller module has no internals mach.status = MachineStatus.ERRORED; return; } // Jump to the target uint32 offset = uint32(inst.argumentData); require(offset == inst.argumentData, "BAD_CALLER_INTERNAL_CALL_DATA"); mach.moduleIdx = frame.callerModule; mach.functionIdx = frame.callerModuleInternals + offset; mach.functionPc = 0; } function executeCallIndirect( Machine memory mach, Module memory mod, Instruction calldata inst, bytes calldata proof ) internal pure { uint32 funcIdx; { uint32 elementIdx = mach.valueStack.pop().assumeI32(); // Prove metadata about the instruction and tables bytes32 elemsRoot; bytes32 wantedFuncTypeHash; uint256 offset = 0; { uint64 tableIdx; uint8 tableType; uint64 tableSize; MerkleProof memory tableMerkleProof; (tableIdx, offset) = Deserialize.u64(proof, offset); (wantedFuncTypeHash, offset) = Deserialize.b32(proof, offset); (tableType, offset) = Deserialize.u8(proof, offset); (tableSize, offset) = Deserialize.u64(proof, offset); (elemsRoot, offset) = Deserialize.b32(proof, offset); (tableMerkleProof, offset) = Deserialize.merkleProof(proof, offset); // Validate the information by recomputing known hashes bytes32 recomputed = keccak256( abi.encodePacked("Call indirect:", tableIdx, wantedFuncTypeHash) ); require(recomputed == bytes32(inst.argumentData), "BAD_CALL_INDIRECT_DATA"); recomputed = tableMerkleProof.computeRootFromTable( tableIdx, tableType, tableSize, elemsRoot ); require(recomputed == mod.tablesMerkleRoot, "BAD_TABLES_ROOT"); // Check if the table access is out of bounds if (elementIdx >= tableSize) { mach.status = MachineStatus.ERRORED; return; } } bytes32 elemFuncTypeHash; Value memory functionPointer; MerkleProof memory elementMerkleProof; (elemFuncTypeHash, offset) = Deserialize.b32(proof, offset); (functionPointer, offset) = Deserialize.value(proof, offset); (elementMerkleProof, offset) = Deserialize.merkleProof(proof, offset); bytes32 recomputedElemRoot = elementMerkleProof.computeRootFromElement( elementIdx, elemFuncTypeHash, functionPointer ); require(recomputedElemRoot == elemsRoot, "BAD_ELEMENTS_ROOT"); if (elemFuncTypeHash != wantedFuncTypeHash) { mach.status = MachineStatus.ERRORED; return; } if (functionPointer.valueType == ValueType.REF_NULL) { mach.status = MachineStatus.ERRORED; return; } else if (functionPointer.valueType == ValueType.FUNC_REF) { funcIdx = uint32(functionPointer.contents); require(funcIdx == functionPointer.contents, "BAD_FUNC_REF_CONTENTS"); } else { revert("BAD_ELEM_TYPE"); } } // Push the return pc to the stack mach.valueStack.push(createReturnValue(mach)); // Push caller module info to the stack StackFrame memory frame = mach.frameStack.peek(); mach.valueStack.push(ValueLib.newI32(frame.callerModule)); mach.valueStack.push(ValueLib.newI32(frame.callerModuleInternals)); // Jump to the target mach.functionIdx = funcIdx; mach.functionPc = 0; } function executeArbitraryJump( Machine memory mach, Module memory, Instruction calldata inst, bytes calldata ) internal pure { // Jump to target uint32 pc = uint32(inst.argumentData); require(pc == inst.argumentData, "BAD_CALL_DATA"); mach.functionPc = pc; } function executeArbitraryJumpIf( Machine memory mach, Module memory, Instruction calldata inst, bytes calldata ) internal pure { uint32 cond = mach.valueStack.pop().assumeI32(); if (cond != 0) { // Jump to target uint32 pc = uint32(inst.argumentData); require(pc == inst.argumentData, "BAD_CALL_DATA"); mach.functionPc = pc; } } function merkleProveGetValue( bytes32 merkleRoot, uint256 index, bytes calldata proof ) internal pure returns (Value memory) { uint256 offset = 0; Value memory proposedVal; MerkleProof memory merkle; (proposedVal, offset) = Deserialize.value(proof, offset); (merkle, offset) = Deserialize.merkleProof(proof, offset); bytes32 recomputedRoot = merkle.computeRootFromValue(index, proposedVal); require(recomputedRoot == merkleRoot, "WRONG_MERKLE_ROOT"); return proposedVal; } function merkleProveSetValue( bytes32 merkleRoot, uint256 index, Value memory newVal, bytes calldata proof ) internal pure returns (bytes32) { Value memory oldVal; uint256 offset = 0; MerkleProof memory merkle; (oldVal, offset) = Deserialize.value(proof, offset); (merkle, offset) = Deserialize.merkleProof(proof, offset); bytes32 recomputedRoot = merkle.computeRootFromValue(index, oldVal); require(recomputedRoot == merkleRoot, "WRONG_MERKLE_ROOT"); return merkle.computeRootFromValue(index, newVal); } function executeLocalGet( Machine memory mach, Module memory, Instruction calldata inst, bytes calldata proof ) internal pure { StackFrame memory frame = mach.frameStack.peek(); Value memory val = merkleProveGetValue(frame.localsMerkleRoot, inst.argumentData, proof); mach.valueStack.push(val); } function executeLocalSet( Machine memory mach, Module memory, Instruction calldata inst, bytes calldata proof ) internal pure { Value memory newVal = mach.valueStack.pop(); StackFrame memory frame = mach.frameStack.peek(); frame.localsMerkleRoot = merkleProveSetValue( frame.localsMerkleRoot, inst.argumentData, newVal, proof ); } function executeGlobalGet( Machine memory mach, Module memory mod, Instruction calldata inst, bytes calldata proof ) internal pure { Value memory val = merkleProveGetValue(mod.globalsMerkleRoot, inst.argumentData, proof); mach.valueStack.push(val); } function executeGlobalSet( Machine memory mach, Module memory mod, Instruction calldata inst, bytes calldata proof ) internal pure { Value memory newVal = mach.valueStack.pop(); mod.globalsMerkleRoot = merkleProveSetValue( mod.globalsMerkleRoot, inst.argumentData, newVal, proof ); } function executeInitFrame( Machine memory mach, Module memory, Instruction calldata inst, bytes calldata ) internal pure { Value memory callerModuleInternals = mach.valueStack.pop(); Value memory callerModule = mach.valueStack.pop(); Value memory returnPc = mach.valueStack.pop(); StackFrame memory newFrame = StackFrame({ returnPc: returnPc, localsMerkleRoot: bytes32(inst.argumentData), callerModule: callerModule.assumeI32(), callerModuleInternals: callerModuleInternals.assumeI32() }); mach.frameStack.push(newFrame); } function executeMoveInternal( Machine memory mach, Module memory, Instruction calldata inst, bytes calldata ) internal pure { Value memory val; if (inst.opcode == Instructions.MOVE_FROM_STACK_TO_INTERNAL) { val = mach.valueStack.pop(); mach.internalStack.push(val); } else if (inst.opcode == Instructions.MOVE_FROM_INTERNAL_TO_STACK) { val = mach.internalStack.pop(); mach.valueStack.push(val); } else { revert("MOVE_INTERNAL_INVALID_OPCODE"); } } function executeDup( Machine memory mach, Module memory, Instruction calldata, bytes calldata ) internal pure { Value memory val = mach.valueStack.peek(); mach.valueStack.push(val); } function executeOneStep( ExecutionContext calldata, Machine calldata startMach, Module calldata startMod, Instruction calldata inst, bytes calldata proof ) external pure override returns (Machine memory mach, Module memory mod) { mach = startMach; mod = startMod; uint16 opcode = inst.opcode; function(Machine memory, Module memory, Instruction calldata, bytes calldata) internal pure impl; if (opcode == Instructions.UNREACHABLE) { impl = executeUnreachable; } else if (opcode == Instructions.NOP) { impl = executeNop; } else if (opcode == Instructions.RETURN) { impl = executeReturn; } else if (opcode == Instructions.CALL) { impl = executeCall; } else if (opcode == Instructions.CROSS_MODULE_CALL) { impl = executeCrossModuleCall; } else if (opcode == Instructions.CROSS_MODULE_FORWARD) { impl = executeCrossModuleForward; } else if (opcode == Instructions.CROSS_MODULE_INTERNAL_CALL) { impl = executeCrossModuleInternalCall; } else if (opcode == Instructions.CALLER_MODULE_INTERNAL_CALL) { impl = executeCallerModuleInternalCall; } else if (opcode == Instructions.CALL_INDIRECT) { impl = executeCallIndirect; } else if (opcode == Instructions.ARBITRARY_JUMP) { impl = executeArbitraryJump; } else if (opcode == Instructions.ARBITRARY_JUMP_IF) { impl = executeArbitraryJumpIf; } else if (opcode == Instructions.LOCAL_GET) { impl = executeLocalGet; } else if (opcode == Instructions.LOCAL_SET) { impl = executeLocalSet; } else if (opcode == Instructions.GLOBAL_GET) { impl = executeGlobalGet; } else if (opcode == Instructions.GLOBAL_SET) { impl = executeGlobalSet; } else if (opcode == Instructions.INIT_FRAME) { impl = executeInitFrame; } else if (opcode == Instructions.DROP) { impl = executeDrop; } else if (opcode == Instructions.SELECT) { impl = executeSelect; } else if (opcode >= Instructions.I32_CONST && opcode <= Instructions.F64_CONST) { impl = executeConstPush; } else if ( opcode == Instructions.MOVE_FROM_STACK_TO_INTERNAL || opcode == Instructions.MOVE_FROM_INTERNAL_TO_STACK ) { impl = executeMoveInternal; } else if (opcode == Instructions.DUP) { impl = executeDup; } else { revert("INVALID_OPCODE"); } impl(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 // 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; 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":"","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":"pure","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50612c11806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80633604366f14610030575b600080fd5b61004361003e36600461209a565b61005a565b6040516100519291906122ae565b60405180910390f35b610062611f0b565b61006a611fec565b610073876127d6565b915061008436879003870187612912565b9050600061009560208701876129b4565b905061204461ffff82166100ac57506102eb6102cd565b61ffff8216600114156100c257506102f66102cd565b61ffff8216600f14156100d857506102fd6102cd565b61ffff8216601014156100ee57506103246102cd565b61ffff8216618009141561010557506103c06102cd565b61ffff821661800b141561011c575061043e6102cd565b61ffff821661800c141561013357506104ce6102cd565b61ffff821661800a141561014a57506106116102cd565b61ffff82166011141561016057506107026102cd565b61ffff821661800314156101775750610ae06102cd565b61ffff8216618004141561018e5750610b206102cd565b61ffff8216602014156101a45750610b7e6102cd565b61ffff8216602114156101ba5750610bc06102cd565b61ffff8216602314156101d05750610c056102cd565b61ffff8216602414156101e65750610c2d6102cd565b61ffff821661800214156101fd5750610c5d6102cd565b61ffff8216601a14156102135750610cfa6102cd565b61ffff8216601b14156102295750610d076102cd565b604161ffff8316108015906102435750604461ffff831611155b156102515750610d766102cd565b61ffff8216618005148061026a575061ffff8216618006145b156102785750610e6a6102cd565b61ffff8216618008141561028f5750610f3d6102cd565b60405162461bcd60e51b815260206004820152600e60248201526d494e56414c49445f4f50434f444560901b60448201526064015b60405180910390fd5b6102de84848989898663ffffffff16565b5050965096945050505050565b505060029092525050565b5050505050565b600061030c8660800151610f4c565b805190915061031c908790610fec565b505050505050565b61033b61033086611065565b6020870151906110e2565b600061034a86608001516110ee565b905061036761035c826040015161113a565b6020880151906110e2565b61037761035c826060015161113a565b602084013563ffffffff811681146103a15760405162461bcd60e51b81526004016102c4906129d8565b63ffffffff166101008701525050600061012090940193909352505050565b6103cc61033086611065565b6103dc6103308660e0015161113a565b6103ec6103308560a0015161113a565b6020808401359081901c604082901c156104185760405162461bcd60e51b81526004016102c4906129ff565b63ffffffff90811660e08801521661010086015250506000610120909301929092525050565b61044a61033086611065565b600061045986608001516110ee565b905061046b61035c826040015161113a565b61047b61035c826060015161113a565b6020808501359081901c604082901c156104a75760405162461bcd60e51b81526004016102c4906129ff565b63ffffffff90811660e0890152166101008701525050600061012090940193909352505050565b60008360200135905060006104ee6104e9886020015161116d565b61118c565b90506104f8611fec565b604080516020810190915260608152600061051487878361121d565b90935090506105248787836112e1565b6101608c015191935091506105448363ffffffff8088169087906113bb16565b1461059c5760405162461bcd60e51b815260206004820152602260248201527f43524f53535f4d4f44554c455f494e5445524e414c5f4d4f44554c45535f524f60448201526113d560f21b60648201526084016102c4565b6105b36105a88b611065565b60208c0151906110e2565b6105c36105a88b60e0015161113a565b6105d36105a88a60a0015161113a565b63ffffffff841660e08b015260a08301516105ee9086612a4c565b63ffffffff166101008b0152505060006101209098019790975250505050505050565b61061d61033086611065565b61062d6103308660e0015161113a565b61063d6103308560a0015161113a565b600061064c86608001516110ee565b9050806060015163ffffffff166000141561066b5750600285526102f6565b602084013563ffffffff811681146106c55760405162461bcd60e51b815260206004820152601d60248201527f4241445f43414c4c45525f494e5445524e414c5f43414c4c5f4441544100000060448201526064016102c4565b604082015163ffffffff1660e088015260608201516106e5908290612a4c565b63ffffffff16610100880152505060006101208601525050505050565b6000806107156104e9886020015161116d565b90506000806000808060006107366040518060200160405280606081525090565b6107418b8b87611406565b955093506107508b8b8761146d565b90965094506107608b8b87611489565b9550925061076f8b8b87611406565b9550915061077e8b8b8761146d565b909750945061078e8b8b876112e1565b6040516d21b0b6361034b73234b932b1ba1d60911b60208201526001600160c01b031960c088901b16602e8201526036810189905290965090915060009060560160408051601f19818403018152919052805160209182012091508d013581146108335760405162461bcd60e51b81526020600482015260166024820152754241445f43414c4c5f494e4449524543545f4441544160501b60448201526064016102c4565b610849826001600160401b03871686868c6114bf565b90508d6040015181146108905760405162461bcd60e51b815260206004820152600f60248201526e10905117d51050931154d7d493d3d5608a1b60448201526064016102c4565b826001600160401b03168963ffffffff16106108ba57505060028d52506102f69650505050505050565b505050505060006108db604080518082019091526000808252602082015290565b6040805160208101909152606081526108f58a8a8661146d565b945092506109048a8a86611561565b945091506109138a8a866112e1565b9450905060006109308263ffffffff808b16908790879061165d16565b90508681146109755760405162461bcd60e51b815260206004820152601160248201527010905117d153115351539514d7d493d3d5607a1b60448201526064016102c4565b8584146109a5578d60025b908160038111156109935761099361217f565b815250505050505050505050506102f6565b6004835160068111156109ba576109ba61217f565b14156109c8578d6002610980565b6005835160068111156109dd576109dd61217f565b1415610a3c576020830151985063ffffffff89168914610a375760405162461bcd60e51b81526020600482015260156024820152744241445f46554e435f5245465f434f4e54454e545360581b60448201526064016102c4565b610a74565b60405162461bcd60e51b815260206004820152600d60248201526c4241445f454c454d5f5459504560981b60448201526064016102c4565b5050505050505050610a8861035c87611065565b6000610a9787608001516110ee565b9050610ab4610aa9826040015161113a565b6020890151906110e2565b610ac4610aa9826060015161113a565b5063ffffffff1661010086015260006101208601525050505050565b602083013563ffffffff81168114610b0a5760405162461bcd60e51b81526004016102c4906129d8565b63ffffffff166101209095019490945250505050565b6000610b326104e9876020015161116d565b905063ffffffff81161561031c57602084013563ffffffff81168114610b6a5760405162461bcd60e51b81526004016102c4906129d8565b63ffffffff16610120870152505050505050565b6000610b8d86608001516110ee565b90506000610ba58260200151866020013586866116f9565b6020880151909150610bb790826110e2565b50505050505050565b6000610bcf866020015161116d565b90506000610be087608001516110ee565b9050610bf781602001518660200135848787611791565b602090910152505050505050565b6000610c1b8560000151856020013585856116f9565b602087015190915061031c90826110e2565b6000610c3c866020015161116d565b9050610c5385600001518560200135838686611791565b9094525050505050565b6000610c6c866020015161116d565b90506000610c7d876020015161116d565b90506000610c8e886020015161116d565b905060006040518060800160405280838152602001886020013560001b8152602001610cb98561118c565b63ffffffff168152602001610ccd8661118c565b63ffffffff168152509050610cef818a6080015161182b90919063ffffffff16565b505050505050505050565b61031c856020015161116d565b6000610d196104e9876020015161116d565b90506000610d2a876020015161116d565b90506000610d3b886020015161116d565b905063ffffffff831615610d5d576020880151610d5890826110e2565b610d6c565b6020880151610d6c90836110e2565b5050505050505050565b6000610d8560208501856129b4565b9050600061ffff821660411415610d9e57506000610e21565b61ffff821660421415610db357506001610e21565b61ffff821660431415610dc857506002610e21565b61ffff821660441415610ddd57506003610e21565b60405162461bcd60e51b8152602060048201526019602482015278434f4e53545f505553485f494e56414c49445f4f50434f444560381b60448201526064016102c4565b610bb76040518060400160405280836006811115610e4157610e4161217f565b815260200187602001356001600160401b031681525088602001516110e290919063ffffffff16565b6040805180820190915260008082526020820152618005610e8e60208601866129b4565b61ffff161415610ebc57610ea5866020015161116d565b6060870151909150610eb790826110e2565b61031c565b618006610ecc60208601866129b4565b61ffff161415610ef557610ee3866060015161116d565b6020870151909150610eb790826110e2565b60405162461bcd60e51b815260206004820152601c60248201527f4d4f56455f494e5445524e414c5f494e56414c49445f4f50434f44450000000060448201526064016102c4565b6000610c1b8660200151611912565b610f5461204e565b815151600114610f765760405162461bcd60e51b81526004016102c490612a74565b81518051600090610f8957610f89612a9f565b6020026020010151905060006001600160401b03811115610fac57610fac612426565b604051908082528060200260200182016040528015610fe557816020015b610fd261204e565b815260200190600190039081610fca5790505b5090915290565b6004815160068111156110015761100161217f565b1415611025578160025b9081600381111561101e5761101e61217f565b9052505050565b60068151600681111561103a5761103a61217f565b146110475781600261100b565b611055828260200151611940565b6110615781600261100b565b5050565b60408051808201909152600080825260208201526110dc8261012001518361010001518460e001516040805180820190915260008082526020820152506040805180820182526006815263ffffffff94909416602093841b67ffffffff00000000161791901b63ffffffff60401b16179082015290565b92915050565b81516110619082611982565b6110f661204e565b8151516001146111185760405162461bcd60e51b81526004016102c490612a74565b8151805160009061112b5761112b612a9f565b60200260200101519050919050565b604080518082019091526000808252602082015250604080518082019091526000815263ffffffff909116602082015290565b604080518082019091526000808252602082015281516110dc90611a4b565b602081015160009081835160068111156111a8576111a861217f565b146111df5760405162461bcd60e51b81526020600482015260076024820152662727aa2fa4999960c91b60448201526064016102c4565b64010000000081106110dc5760405162461bcd60e51b81526020600482015260076024820152662120a22fa4999960c91b60448201526064016102c4565b611225611fec565b604080516060810182526000808252602082018190529181018290528391906000806000806112558b8b8961146d565b975095506112648b8b89611b54565b975094506112738b8b8961146d565b975093506112828b8b8961146d565b975092506112918b8b8961146d565b975091506112a08b8b89611bcf565b6040805160c081018252988952602089019790975295870194909452506060850191909152608084015263ffffffff1660a083015290969095509350505050565b6040805160208101909152606081528160006112fe868684611489565b92509050600060ff82166001600160401b0381111561131f5761131f612426565b604051908082528060200260200182016040528015611348578160200160208202803683370190505b50905060005b8260ff168160ff16101561139f5761136788888661146d565b838360ff168151811061137c5761137c612a9f565b60200260200101819650828152505050808061139790612ab5565b91505061134e565b5060405180602001604052808281525093505050935093915050565b60006113fc84846113cb85611c2a565b6040518060400160405280601381526020017226b7b23ab6329036b2b935b632903a3932b29d60691b815250611cc3565b90505b9392505050565b600081815b6008811015611464576008836001600160401b0316901b925085858381811061143657611436612a9f565b919091013560f81c9390931792508161144e81612ad5565b925050808061145c90612ad5565b91505061140b565b50935093915050565b6000818161147c868684611dcd565b9097909650945050505050565b60008184848281811061149e5761149e612a9f565b919091013560f81c92508190506114b481612ad5565b915050935093915050565b604051652a30b136329d60d11b60208201526001600160f81b031960f885901b1660268201526001600160c01b031960c084901b166027820152602f81018290526000908190604f01604051602081830303815290604052805190602001209050611556878783604051806040016040528060128152602001712a30b136329036b2b935b632903a3932b29d60711b815250611cc3565b979650505050505050565b604080518082019091526000808252602082015281600085858381811061158a5761158a612a9f565b919091013560f81c91508290506115a081612ad5565b9250506115ab600690565b60068111156115bc576115bc61217f565b60ff168160ff1611156116025760405162461bcd60e51b815260206004820152600e60248201526d4241445f56414c55455f5459504560901b60448201526064016102c4565b600061160f878785611dcd565b809450819250505060405180604001604052808360ff1660068111156116375761163761217f565b60068111156116485761164861217f565b81526020018281525093505050935093915050565b6000808361166a84611e22565b6040516d2a30b136329032b632b6b2b73a1d60911b6020820152602e810192909252604e820152606e016040516020818303038152906040528051906020012090506116ed8686836040518060400160405280601a81526020017f5461626c6520656c656d656e74206d65726b6c6520747265653a000000000000815250611cc3565b9150505b949350505050565b60408051808201909152600080825260208201526000611729604080518082019091526000808252602082015290565b604080516020810190915260608152611743868685611561565b935091506117528686856112e1565b935090506000611763828985611e3f565b90508881146117845760405162461bcd60e51b81526004016102c490612af0565b5090979650505050505050565b60006117ad604080518082019091526000808252602082015290565b60006117c56040518060200160405280606081525090565b6117d0868684611561565b90935091506117e08686846112e1565b9250905060006117f1828a86611e3f565b90508981146118125760405162461bcd60e51b81526004016102c490612af0565b61181d828a8a611e3f565b9a9950505050505050505050565b81515160009061183c906001612b1b565b6001600160401b0381111561185357611853612426565b60405190808252806020026020018201604052801561188c57816020015b61187961204e565b8152602001906001900390816118715790505b50905060005b8351518110156118e85783518051829081106118b0576118b0612a9f565b60200260200101518282815181106118ca576118ca612a9f565b602002602001018190525080806118e090612ad5565b915050611892565b5081818460000151518151811061190157611901612a9f565b602090810291909101015290915250565b6040805180820190915260008082526020820152815151516113ff611938600183612b33565b845190611e7f565b6000606082901c15611954575060006110dc565b5063ffffffff818116610120840152602082901c811661010084015260409190911c1660e090910152600190565b815151600090611993906001612b1b565b6001600160401b038111156119aa576119aa612426565b6040519080825280602002602001820160405280156119ef57816020015b60408051808201909152600080825260208201528152602001906001900390816119c85790505b50905060005b8351518110156118e8578351805182908110611a1357611a13612a9f565b6020026020010151828281518110611a2d57611a2d612a9f565b60200260200101819052508080611a4390612ad5565b9150506119f5565b604080518082019091526000808252602082015281518051611a6f90600190612b33565b81518110611a7f57611a7f612a9f565b6020026020010151905060006001836000015151611a9d9190612b33565b6001600160401b03811115611ab457611ab4612426565b604051908082528060200260200182016040528015611af957816020015b6040805180820190915260008082526020820152815260200190600190039081611ad25790505b50905060005b8151811015610fe5578351805182908110611b1c57611b1c612a9f565b6020026020010151828281518110611b3657611b36612a9f565b60200260200101819052508080611b4c90612ad5565b915050611aff565b60408051606081018252600080825260208201819052918101919091528160008080611b81888886611406565b94509250611b90888886611406565b94509150611b9f88888661146d565b604080516060810182526001600160401b0396871681529490951660208501529383015250969095509350505050565b600081815b60048110156114645760088363ffffffff16901b9250858583818110611bfc57611bfc612a9f565b919091013560f81c93909317925081611c1481612ad5565b9250508080611c2290612ad5565b915050611bd4565b60008160000151611c3e8360200151611eb7565b6040808501516060860151608087015160a08801519351611ca6969594906020016626b7b23ab6329d60c91b81526007810196909652602786019490945260478501929092526067840152608783015260e01b6001600160e01b03191660a782015260ab0190565b604051602081830303815290604052805190602001209050919050565b8160005b855151811015611d8c5760018516611d2857828287600001518381518110611cf157611cf1612a9f565b6020026020010151604051602001611d0b93929190612b4a565b604051602081830303815290604052805190602001209150611d73565b8286600001518281518110611d3f57611d3f612a9f565b602002602001015183604051602001611d5a93929190612b4a565b6040516020818303038152906040528051906020012091505b60019490941c9380611d8481612ad5565b915050611cc7565b5083156116f15760405162461bcd60e51b815260206004820152600f60248201526e141493d3d197d513d3d7d4d213d495608a1b60448201526064016102c4565b600081815b602081101561146457600883901b9250858583818110611df457611df4612a9f565b919091013560f81c93909317925081611e0c81612ad5565b9250508080611e1a90612ad5565b915050611dd2565b600081600001518260200151604051602001611ca6929190612b90565b60006113fc8484611e4f85611e22565b604051806040016040528060128152602001712b30b63ab29036b2b935b632903a3932b29d60711b815250611cc3565b60408051808201909152600080825260208201528251805183908110611ea757611ea7612a9f565b6020026020010151905092915050565b805160208083015160408085015190516626b2b6b7b93c9d60c91b938101939093526001600160c01b031960c094851b811660278501529190931b16602f8201526037810191909152600090605701611ca6565b6040805161018081019091528060008152602001611f4060408051606080820183529181019182529081526000602082015290565b8152604080518082018252600080825260208083019190915283015201611f7e60408051606080820183529181019182529081526000602082015290565b8152602001611fa3604051806040016040528060608152602001600080191681525090565b815260408051808201825260008082526020808301829052840191909152908201819052606082018190526080820181905260a0820181905260c0820181905260e09091015290565b6040805160c081019091526000815260208101612022604080516060810182526000808252602082018190529181019190915290565b8152600060208201819052604082018190526060820181905260809091015290565b61204c612bc5565b565b6040805160c08101825260006080820181815260a08301829052825260208201819052918101829052606081019190915290565b60006040828403121561209457600080fd5b50919050565b6000806000806000808688036101c0808212156120b657600080fd5b6120c08a8a612082565b975060408901356001600160401b03808211156120dc57600080fd5b818b01915082828d0312156120f057600080fd5b819850610100605f198501121561210657600080fd5b60608b01975061211a8c6101608d01612082565b96506101a08b013593508084111561213157600080fd5b838b0193508b601f85011261214557600080fd5b833592508083111561215657600080fd5b505089602082840101111561216a57600080fd5b60208201935080925050509295509295509295565b634e487b7160e01b600052602160045260246000fd5b600481106121a5576121a561217f565b9052565b8051600781106121bb576121bb61217f565b8252602090810151910152565b805160408084529051602084830181905281516060860181905260009392820191849160808801905b80841015612218576122048286516121a9565b9382019360019390930192908501906121f1565b509581015196019590955250919392505050565b8051604080845281518482018190526000926060916020918201918388019190865b828110156122975784516122638582516121a9565b80830151858901528781015163ffffffff90811688870152908701511660808501529381019360a09093019260010161224e565b509687015197909601969096525093949350505050565b60006101208083526122c38184018651612195565b60208501516101c061014081818701526122e16102e08701846121c8565b925060408801516101606123018189018380518252602090810151910152565b60608a0151915061011f1980898703016101a08a015261232186846121c8565b955060808b015192508089870301858a01525061233e858361222c565b60a08b015180516101e08b015260208101516102008b0152909550935060c08a015161022089015260e08a015163ffffffff81166102408a015293506101008a015163ffffffff81166102608a015293509489015163ffffffff811661028089015294918901516102a0880152508701516102c08601525091506113ff905060208301848051825260208101516001600160401b0380825116602085015280602083015116604085015250604081015160608401525060408101516080830152606081015160a0830152608081015160c083015263ffffffff60a08201511660e08301525050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b038111828210171561245e5761245e612426565b60405290565b604051602081016001600160401b038111828210171561245e5761245e612426565b604051608081016001600160401b038111828210171561245e5761245e612426565b60405161018081016001600160401b038111828210171561245e5761245e612426565b60405160c081016001600160401b038111828210171561245e5761245e612426565b604051606081016001600160401b038111828210171561245e5761245e612426565b604051601f8201601f191681016001600160401b038111828210171561253757612537612426565b604052919050565b80356004811061254e57600080fd5b919050565b60006001600160401b0382111561256c5761256c612426565b5060051b60200190565b60006040828403121561258857600080fd5b61259061243c565b90508135600781106125a157600080fd5b808252506020820135602082015292915050565b600060408083850312156125c857600080fd5b6125d061243c565b915082356001600160401b03808211156125e957600080fd5b818501915060208083880312156125ff57600080fd5b612607612464565b83358381111561261657600080fd5b80850194505087601f85011261262b57600080fd5b8335925061264061263b84612553565b61250f565b83815260069390931b8401820192828101908985111561265f57600080fd5b948301945b84861015612685576126768a87612576565b82529486019490830190612664565b8252508552948501359484019490945250909392505050565b6000604082840312156126b057600080fd5b6126b861243c565b9050813581526020820135602082015292915050565b803563ffffffff8116811461254e57600080fd5b600060408083850312156126f557600080fd5b6126fd61243c565b915082356001600160401b0381111561271557600080fd5b8301601f8101851361272657600080fd5b8035602061273661263b83612553565b82815260a0928302840182019282820191908985111561275557600080fd5b948301945b848610156127be5780868b0312156127725760008081fd5b61277a612486565b6127848b88612576565b81528787013585820152606061279b8189016126ce565b898301526127ab608089016126ce565b908201528352948501949183019161275a565b50808752505080860135818601525050505092915050565b60006101c082360312156127e957600080fd5b6127f16124a8565b6127fa8361253f565b815260208301356001600160401b038082111561281657600080fd5b612822368387016125b5565b6020840152612834366040870161269e565b6040840152608085013591508082111561284d57600080fd5b612859368387016125b5565b606084015260a085013591508082111561287257600080fd5b5061287f368286016126e2565b6080830152506128923660c0850161269e565b60a08201526101008084013560c08301526101206128b18186016126ce565b60e08401526101406128c48187016126ce565b8385015261016092506128d88387016126ce565b91840191909152610180850135908301526101a090930135928101929092525090565b80356001600160401b038116811461254e57600080fd5b600081830361010081121561292657600080fd5b61292e6124cb565b833581526060601f198301121561294457600080fd5b61294c6124ed565b915061295a602085016128fb565b8252612968604085016128fb565b6020830152606084013560408301528160208201526080840135604082015260a0840135606082015260c084013560808201526129a760e085016126ce565b60a0820152949350505050565b6000602082840312156129c657600080fd5b813561ffff811681146113ff57600080fd5b6020808252600d908201526c4241445f43414c4c5f4441544160981b604082015260600190565b6020808252601a908201527f4241445f43524f53535f4d4f44554c455f43414c4c5f44415441000000000000604082015260600190565b634e487b7160e01b600052601160045260246000fd5b600063ffffffff808316818516808303821115612a6b57612a6b612a36565b01949350505050565b6020808252601190820152700848288beae929c889eaebe988a9c8ea89607b1b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b600060ff821660ff811415612acc57612acc612a36565b60010192915050565b6000600019821415612ae957612ae9612a36565b5060010190565b60208082526011908201527015d493d391d7d3515492d31157d493d3d5607a1b604082015260600190565b60008219821115612b2e57612b2e612a36565b500190565b600082821015612b4557612b45612a36565b500390565b6000845160005b81811015612b6b5760208188018101518583015201612b51565b81811115612b7a576000828501525b5091909101928352506020820152604001919050565b652b30b63ab29d60d11b8152600060078410612bae57612bae61217f565b5060f89290921b6006830152600782015260270190565b634e487b7160e01b600052605160045260246000fdfea2646970667358221220fc103f19f529f25606dcf95d221632948bea361b65291f312c2bdf94f716271c64736f6c63430008090033
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061002b5760003560e01c80633604366f14610030575b600080fd5b61004361003e36600461209a565b61005a565b6040516100519291906122ae565b60405180910390f35b610062611f0b565b61006a611fec565b610073876127d6565b915061008436879003870187612912565b9050600061009560208701876129b4565b905061204461ffff82166100ac57506102eb6102cd565b61ffff8216600114156100c257506102f66102cd565b61ffff8216600f14156100d857506102fd6102cd565b61ffff8216601014156100ee57506103246102cd565b61ffff8216618009141561010557506103c06102cd565b61ffff821661800b141561011c575061043e6102cd565b61ffff821661800c141561013357506104ce6102cd565b61ffff821661800a141561014a57506106116102cd565b61ffff82166011141561016057506107026102cd565b61ffff821661800314156101775750610ae06102cd565b61ffff8216618004141561018e5750610b206102cd565b61ffff8216602014156101a45750610b7e6102cd565b61ffff8216602114156101ba5750610bc06102cd565b61ffff8216602314156101d05750610c056102cd565b61ffff8216602414156101e65750610c2d6102cd565b61ffff821661800214156101fd5750610c5d6102cd565b61ffff8216601a14156102135750610cfa6102cd565b61ffff8216601b14156102295750610d076102cd565b604161ffff8316108015906102435750604461ffff831611155b156102515750610d766102cd565b61ffff8216618005148061026a575061ffff8216618006145b156102785750610e6a6102cd565b61ffff8216618008141561028f5750610f3d6102cd565b60405162461bcd60e51b815260206004820152600e60248201526d494e56414c49445f4f50434f444560901b60448201526064015b60405180910390fd5b6102de84848989898663ffffffff16565b5050965096945050505050565b505060029092525050565b5050505050565b600061030c8660800151610f4c565b805190915061031c908790610fec565b505050505050565b61033b61033086611065565b6020870151906110e2565b600061034a86608001516110ee565b905061036761035c826040015161113a565b6020880151906110e2565b61037761035c826060015161113a565b602084013563ffffffff811681146103a15760405162461bcd60e51b81526004016102c4906129d8565b63ffffffff166101008701525050600061012090940193909352505050565b6103cc61033086611065565b6103dc6103308660e0015161113a565b6103ec6103308560a0015161113a565b6020808401359081901c604082901c156104185760405162461bcd60e51b81526004016102c4906129ff565b63ffffffff90811660e08801521661010086015250506000610120909301929092525050565b61044a61033086611065565b600061045986608001516110ee565b905061046b61035c826040015161113a565b61047b61035c826060015161113a565b6020808501359081901c604082901c156104a75760405162461bcd60e51b81526004016102c4906129ff565b63ffffffff90811660e0890152166101008701525050600061012090940193909352505050565b60008360200135905060006104ee6104e9886020015161116d565b61118c565b90506104f8611fec565b604080516020810190915260608152600061051487878361121d565b90935090506105248787836112e1565b6101608c015191935091506105448363ffffffff8088169087906113bb16565b1461059c5760405162461bcd60e51b815260206004820152602260248201527f43524f53535f4d4f44554c455f494e5445524e414c5f4d4f44554c45535f524f60448201526113d560f21b60648201526084016102c4565b6105b36105a88b611065565b60208c0151906110e2565b6105c36105a88b60e0015161113a565b6105d36105a88a60a0015161113a565b63ffffffff841660e08b015260a08301516105ee9086612a4c565b63ffffffff166101008b0152505060006101209098019790975250505050505050565b61061d61033086611065565b61062d6103308660e0015161113a565b61063d6103308560a0015161113a565b600061064c86608001516110ee565b9050806060015163ffffffff166000141561066b5750600285526102f6565b602084013563ffffffff811681146106c55760405162461bcd60e51b815260206004820152601d60248201527f4241445f43414c4c45525f494e5445524e414c5f43414c4c5f4441544100000060448201526064016102c4565b604082015163ffffffff1660e088015260608201516106e5908290612a4c565b63ffffffff16610100880152505060006101208601525050505050565b6000806107156104e9886020015161116d565b90506000806000808060006107366040518060200160405280606081525090565b6107418b8b87611406565b955093506107508b8b8761146d565b90965094506107608b8b87611489565b9550925061076f8b8b87611406565b9550915061077e8b8b8761146d565b909750945061078e8b8b876112e1565b6040516d21b0b6361034b73234b932b1ba1d60911b60208201526001600160c01b031960c088901b16602e8201526036810189905290965090915060009060560160408051601f19818403018152919052805160209182012091508d013581146108335760405162461bcd60e51b81526020600482015260166024820152754241445f43414c4c5f494e4449524543545f4441544160501b60448201526064016102c4565b610849826001600160401b03871686868c6114bf565b90508d6040015181146108905760405162461bcd60e51b815260206004820152600f60248201526e10905117d51050931154d7d493d3d5608a1b60448201526064016102c4565b826001600160401b03168963ffffffff16106108ba57505060028d52506102f69650505050505050565b505050505060006108db604080518082019091526000808252602082015290565b6040805160208101909152606081526108f58a8a8661146d565b945092506109048a8a86611561565b945091506109138a8a866112e1565b9450905060006109308263ffffffff808b16908790879061165d16565b90508681146109755760405162461bcd60e51b815260206004820152601160248201527010905117d153115351539514d7d493d3d5607a1b60448201526064016102c4565b8584146109a5578d60025b908160038111156109935761099361217f565b815250505050505050505050506102f6565b6004835160068111156109ba576109ba61217f565b14156109c8578d6002610980565b6005835160068111156109dd576109dd61217f565b1415610a3c576020830151985063ffffffff89168914610a375760405162461bcd60e51b81526020600482015260156024820152744241445f46554e435f5245465f434f4e54454e545360581b60448201526064016102c4565b610a74565b60405162461bcd60e51b815260206004820152600d60248201526c4241445f454c454d5f5459504560981b60448201526064016102c4565b5050505050505050610a8861035c87611065565b6000610a9787608001516110ee565b9050610ab4610aa9826040015161113a565b6020890151906110e2565b610ac4610aa9826060015161113a565b5063ffffffff1661010086015260006101208601525050505050565b602083013563ffffffff81168114610b0a5760405162461bcd60e51b81526004016102c4906129d8565b63ffffffff166101209095019490945250505050565b6000610b326104e9876020015161116d565b905063ffffffff81161561031c57602084013563ffffffff81168114610b6a5760405162461bcd60e51b81526004016102c4906129d8565b63ffffffff16610120870152505050505050565b6000610b8d86608001516110ee565b90506000610ba58260200151866020013586866116f9565b6020880151909150610bb790826110e2565b50505050505050565b6000610bcf866020015161116d565b90506000610be087608001516110ee565b9050610bf781602001518660200135848787611791565b602090910152505050505050565b6000610c1b8560000151856020013585856116f9565b602087015190915061031c90826110e2565b6000610c3c866020015161116d565b9050610c5385600001518560200135838686611791565b9094525050505050565b6000610c6c866020015161116d565b90506000610c7d876020015161116d565b90506000610c8e886020015161116d565b905060006040518060800160405280838152602001886020013560001b8152602001610cb98561118c565b63ffffffff168152602001610ccd8661118c565b63ffffffff168152509050610cef818a6080015161182b90919063ffffffff16565b505050505050505050565b61031c856020015161116d565b6000610d196104e9876020015161116d565b90506000610d2a876020015161116d565b90506000610d3b886020015161116d565b905063ffffffff831615610d5d576020880151610d5890826110e2565b610d6c565b6020880151610d6c90836110e2565b5050505050505050565b6000610d8560208501856129b4565b9050600061ffff821660411415610d9e57506000610e21565b61ffff821660421415610db357506001610e21565b61ffff821660431415610dc857506002610e21565b61ffff821660441415610ddd57506003610e21565b60405162461bcd60e51b8152602060048201526019602482015278434f4e53545f505553485f494e56414c49445f4f50434f444560381b60448201526064016102c4565b610bb76040518060400160405280836006811115610e4157610e4161217f565b815260200187602001356001600160401b031681525088602001516110e290919063ffffffff16565b6040805180820190915260008082526020820152618005610e8e60208601866129b4565b61ffff161415610ebc57610ea5866020015161116d565b6060870151909150610eb790826110e2565b61031c565b618006610ecc60208601866129b4565b61ffff161415610ef557610ee3866060015161116d565b6020870151909150610eb790826110e2565b60405162461bcd60e51b815260206004820152601c60248201527f4d4f56455f494e5445524e414c5f494e56414c49445f4f50434f44450000000060448201526064016102c4565b6000610c1b8660200151611912565b610f5461204e565b815151600114610f765760405162461bcd60e51b81526004016102c490612a74565b81518051600090610f8957610f89612a9f565b6020026020010151905060006001600160401b03811115610fac57610fac612426565b604051908082528060200260200182016040528015610fe557816020015b610fd261204e565b815260200190600190039081610fca5790505b5090915290565b6004815160068111156110015761100161217f565b1415611025578160025b9081600381111561101e5761101e61217f565b9052505050565b60068151600681111561103a5761103a61217f565b146110475781600261100b565b611055828260200151611940565b6110615781600261100b565b5050565b60408051808201909152600080825260208201526110dc8261012001518361010001518460e001516040805180820190915260008082526020820152506040805180820182526006815263ffffffff94909416602093841b67ffffffff00000000161791901b63ffffffff60401b16179082015290565b92915050565b81516110619082611982565b6110f661204e565b8151516001146111185760405162461bcd60e51b81526004016102c490612a74565b8151805160009061112b5761112b612a9f565b60200260200101519050919050565b604080518082019091526000808252602082015250604080518082019091526000815263ffffffff909116602082015290565b604080518082019091526000808252602082015281516110dc90611a4b565b602081015160009081835160068111156111a8576111a861217f565b146111df5760405162461bcd60e51b81526020600482015260076024820152662727aa2fa4999960c91b60448201526064016102c4565b64010000000081106110dc5760405162461bcd60e51b81526020600482015260076024820152662120a22fa4999960c91b60448201526064016102c4565b611225611fec565b604080516060810182526000808252602082018190529181018290528391906000806000806112558b8b8961146d565b975095506112648b8b89611b54565b975094506112738b8b8961146d565b975093506112828b8b8961146d565b975092506112918b8b8961146d565b975091506112a08b8b89611bcf565b6040805160c081018252988952602089019790975295870194909452506060850191909152608084015263ffffffff1660a083015290969095509350505050565b6040805160208101909152606081528160006112fe868684611489565b92509050600060ff82166001600160401b0381111561131f5761131f612426565b604051908082528060200260200182016040528015611348578160200160208202803683370190505b50905060005b8260ff168160ff16101561139f5761136788888661146d565b838360ff168151811061137c5761137c612a9f565b60200260200101819650828152505050808061139790612ab5565b91505061134e565b5060405180602001604052808281525093505050935093915050565b60006113fc84846113cb85611c2a565b6040518060400160405280601381526020017226b7b23ab6329036b2b935b632903a3932b29d60691b815250611cc3565b90505b9392505050565b600081815b6008811015611464576008836001600160401b0316901b925085858381811061143657611436612a9f565b919091013560f81c9390931792508161144e81612ad5565b925050808061145c90612ad5565b91505061140b565b50935093915050565b6000818161147c868684611dcd565b9097909650945050505050565b60008184848281811061149e5761149e612a9f565b919091013560f81c92508190506114b481612ad5565b915050935093915050565b604051652a30b136329d60d11b60208201526001600160f81b031960f885901b1660268201526001600160c01b031960c084901b166027820152602f81018290526000908190604f01604051602081830303815290604052805190602001209050611556878783604051806040016040528060128152602001712a30b136329036b2b935b632903a3932b29d60711b815250611cc3565b979650505050505050565b604080518082019091526000808252602082015281600085858381811061158a5761158a612a9f565b919091013560f81c91508290506115a081612ad5565b9250506115ab600690565b60068111156115bc576115bc61217f565b60ff168160ff1611156116025760405162461bcd60e51b815260206004820152600e60248201526d4241445f56414c55455f5459504560901b60448201526064016102c4565b600061160f878785611dcd565b809450819250505060405180604001604052808360ff1660068111156116375761163761217f565b60068111156116485761164861217f565b81526020018281525093505050935093915050565b6000808361166a84611e22565b6040516d2a30b136329032b632b6b2b73a1d60911b6020820152602e810192909252604e820152606e016040516020818303038152906040528051906020012090506116ed8686836040518060400160405280601a81526020017f5461626c6520656c656d656e74206d65726b6c6520747265653a000000000000815250611cc3565b9150505b949350505050565b60408051808201909152600080825260208201526000611729604080518082019091526000808252602082015290565b604080516020810190915260608152611743868685611561565b935091506117528686856112e1565b935090506000611763828985611e3f565b90508881146117845760405162461bcd60e51b81526004016102c490612af0565b5090979650505050505050565b60006117ad604080518082019091526000808252602082015290565b60006117c56040518060200160405280606081525090565b6117d0868684611561565b90935091506117e08686846112e1565b9250905060006117f1828a86611e3f565b90508981146118125760405162461bcd60e51b81526004016102c490612af0565b61181d828a8a611e3f565b9a9950505050505050505050565b81515160009061183c906001612b1b565b6001600160401b0381111561185357611853612426565b60405190808252806020026020018201604052801561188c57816020015b61187961204e565b8152602001906001900390816118715790505b50905060005b8351518110156118e85783518051829081106118b0576118b0612a9f565b60200260200101518282815181106118ca576118ca612a9f565b602002602001018190525080806118e090612ad5565b915050611892565b5081818460000151518151811061190157611901612a9f565b602090810291909101015290915250565b6040805180820190915260008082526020820152815151516113ff611938600183612b33565b845190611e7f565b6000606082901c15611954575060006110dc565b5063ffffffff818116610120840152602082901c811661010084015260409190911c1660e090910152600190565b815151600090611993906001612b1b565b6001600160401b038111156119aa576119aa612426565b6040519080825280602002602001820160405280156119ef57816020015b60408051808201909152600080825260208201528152602001906001900390816119c85790505b50905060005b8351518110156118e8578351805182908110611a1357611a13612a9f565b6020026020010151828281518110611a2d57611a2d612a9f565b60200260200101819052508080611a4390612ad5565b9150506119f5565b604080518082019091526000808252602082015281518051611a6f90600190612b33565b81518110611a7f57611a7f612a9f565b6020026020010151905060006001836000015151611a9d9190612b33565b6001600160401b03811115611ab457611ab4612426565b604051908082528060200260200182016040528015611af957816020015b6040805180820190915260008082526020820152815260200190600190039081611ad25790505b50905060005b8151811015610fe5578351805182908110611b1c57611b1c612a9f565b6020026020010151828281518110611b3657611b36612a9f565b60200260200101819052508080611b4c90612ad5565b915050611aff565b60408051606081018252600080825260208201819052918101919091528160008080611b81888886611406565b94509250611b90888886611406565b94509150611b9f88888661146d565b604080516060810182526001600160401b0396871681529490951660208501529383015250969095509350505050565b600081815b60048110156114645760088363ffffffff16901b9250858583818110611bfc57611bfc612a9f565b919091013560f81c93909317925081611c1481612ad5565b9250508080611c2290612ad5565b915050611bd4565b60008160000151611c3e8360200151611eb7565b6040808501516060860151608087015160a08801519351611ca6969594906020016626b7b23ab6329d60c91b81526007810196909652602786019490945260478501929092526067840152608783015260e01b6001600160e01b03191660a782015260ab0190565b604051602081830303815290604052805190602001209050919050565b8160005b855151811015611d8c5760018516611d2857828287600001518381518110611cf157611cf1612a9f565b6020026020010151604051602001611d0b93929190612b4a565b604051602081830303815290604052805190602001209150611d73565b8286600001518281518110611d3f57611d3f612a9f565b602002602001015183604051602001611d5a93929190612b4a565b6040516020818303038152906040528051906020012091505b60019490941c9380611d8481612ad5565b915050611cc7565b5083156116f15760405162461bcd60e51b815260206004820152600f60248201526e141493d3d197d513d3d7d4d213d495608a1b60448201526064016102c4565b600081815b602081101561146457600883901b9250858583818110611df457611df4612a9f565b919091013560f81c93909317925081611e0c81612ad5565b9250508080611e1a90612ad5565b915050611dd2565b600081600001518260200151604051602001611ca6929190612b90565b60006113fc8484611e4f85611e22565b604051806040016040528060128152602001712b30b63ab29036b2b935b632903a3932b29d60711b815250611cc3565b60408051808201909152600080825260208201528251805183908110611ea757611ea7612a9f565b6020026020010151905092915050565b805160208083015160408085015190516626b2b6b7b93c9d60c91b938101939093526001600160c01b031960c094851b811660278501529190931b16602f8201526037810191909152600090605701611ca6565b6040805161018081019091528060008152602001611f4060408051606080820183529181019182529081526000602082015290565b8152604080518082018252600080825260208083019190915283015201611f7e60408051606080820183529181019182529081526000602082015290565b8152602001611fa3604051806040016040528060608152602001600080191681525090565b815260408051808201825260008082526020808301829052840191909152908201819052606082018190526080820181905260a0820181905260c0820181905260e09091015290565b6040805160c081019091526000815260208101612022604080516060810182526000808252602082018190529181019190915290565b8152600060208201819052604082018190526060820181905260809091015290565b61204c612bc5565b565b6040805160c08101825260006080820181815260a08301829052825260208201819052918101829052606081019190915290565b60006040828403121561209457600080fd5b50919050565b6000806000806000808688036101c0808212156120b657600080fd5b6120c08a8a612082565b975060408901356001600160401b03808211156120dc57600080fd5b818b01915082828d0312156120f057600080fd5b819850610100605f198501121561210657600080fd5b60608b01975061211a8c6101608d01612082565b96506101a08b013593508084111561213157600080fd5b838b0193508b601f85011261214557600080fd5b833592508083111561215657600080fd5b505089602082840101111561216a57600080fd5b60208201935080925050509295509295509295565b634e487b7160e01b600052602160045260246000fd5b600481106121a5576121a561217f565b9052565b8051600781106121bb576121bb61217f565b8252602090810151910152565b805160408084529051602084830181905281516060860181905260009392820191849160808801905b80841015612218576122048286516121a9565b9382019360019390930192908501906121f1565b509581015196019590955250919392505050565b8051604080845281518482018190526000926060916020918201918388019190865b828110156122975784516122638582516121a9565b80830151858901528781015163ffffffff90811688870152908701511660808501529381019360a09093019260010161224e565b509687015197909601969096525093949350505050565b60006101208083526122c38184018651612195565b60208501516101c061014081818701526122e16102e08701846121c8565b925060408801516101606123018189018380518252602090810151910152565b60608a0151915061011f1980898703016101a08a015261232186846121c8565b955060808b015192508089870301858a01525061233e858361222c565b60a08b015180516101e08b015260208101516102008b0152909550935060c08a015161022089015260e08a015163ffffffff81166102408a015293506101008a015163ffffffff81166102608a015293509489015163ffffffff811661028089015294918901516102a0880152508701516102c08601525091506113ff905060208301848051825260208101516001600160401b0380825116602085015280602083015116604085015250604081015160608401525060408101516080830152606081015160a0830152608081015160c083015263ffffffff60a08201511660e08301525050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b038111828210171561245e5761245e612426565b60405290565b604051602081016001600160401b038111828210171561245e5761245e612426565b604051608081016001600160401b038111828210171561245e5761245e612426565b60405161018081016001600160401b038111828210171561245e5761245e612426565b60405160c081016001600160401b038111828210171561245e5761245e612426565b604051606081016001600160401b038111828210171561245e5761245e612426565b604051601f8201601f191681016001600160401b038111828210171561253757612537612426565b604052919050565b80356004811061254e57600080fd5b919050565b60006001600160401b0382111561256c5761256c612426565b5060051b60200190565b60006040828403121561258857600080fd5b61259061243c565b90508135600781106125a157600080fd5b808252506020820135602082015292915050565b600060408083850312156125c857600080fd5b6125d061243c565b915082356001600160401b03808211156125e957600080fd5b818501915060208083880312156125ff57600080fd5b612607612464565b83358381111561261657600080fd5b80850194505087601f85011261262b57600080fd5b8335925061264061263b84612553565b61250f565b83815260069390931b8401820192828101908985111561265f57600080fd5b948301945b84861015612685576126768a87612576565b82529486019490830190612664565b8252508552948501359484019490945250909392505050565b6000604082840312156126b057600080fd5b6126b861243c565b9050813581526020820135602082015292915050565b803563ffffffff8116811461254e57600080fd5b600060408083850312156126f557600080fd5b6126fd61243c565b915082356001600160401b0381111561271557600080fd5b8301601f8101851361272657600080fd5b8035602061273661263b83612553565b82815260a0928302840182019282820191908985111561275557600080fd5b948301945b848610156127be5780868b0312156127725760008081fd5b61277a612486565b6127848b88612576565b81528787013585820152606061279b8189016126ce565b898301526127ab608089016126ce565b908201528352948501949183019161275a565b50808752505080860135818601525050505092915050565b60006101c082360312156127e957600080fd5b6127f16124a8565b6127fa8361253f565b815260208301356001600160401b038082111561281657600080fd5b612822368387016125b5565b6020840152612834366040870161269e565b6040840152608085013591508082111561284d57600080fd5b612859368387016125b5565b606084015260a085013591508082111561287257600080fd5b5061287f368286016126e2565b6080830152506128923660c0850161269e565b60a08201526101008084013560c08301526101206128b18186016126ce565b60e08401526101406128c48187016126ce565b8385015261016092506128d88387016126ce565b91840191909152610180850135908301526101a090930135928101929092525090565b80356001600160401b038116811461254e57600080fd5b600081830361010081121561292657600080fd5b61292e6124cb565b833581526060601f198301121561294457600080fd5b61294c6124ed565b915061295a602085016128fb565b8252612968604085016128fb565b6020830152606084013560408301528160208201526080840135604082015260a0840135606082015260c084013560808201526129a760e085016126ce565b60a0820152949350505050565b6000602082840312156129c657600080fd5b813561ffff811681146113ff57600080fd5b6020808252600d908201526c4241445f43414c4c5f4441544160981b604082015260600190565b6020808252601a908201527f4241445f43524f53535f4d4f44554c455f43414c4c5f44415441000000000000604082015260600190565b634e487b7160e01b600052601160045260246000fd5b600063ffffffff808316818516808303821115612a6b57612a6b612a36565b01949350505050565b6020808252601190820152700848288beae929c889eaebe988a9c8ea89607b1b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b600060ff821660ff811415612acc57612acc612a36565b60010192915050565b6000600019821415612ae957612ae9612a36565b5060010190565b60208082526011908201527015d493d391d7d3515492d31157d493d3d5607a1b604082015260600190565b60008219821115612b2e57612b2e612a36565b500190565b600082821015612b4557612b45612a36565b500390565b6000845160005b81811015612b6b5760208188018101518583015201612b51565b81811115612b7a576000828501525b5091909101928352506020820152604001919050565b652b30b63ab29d60d11b8152600060078410612bae57612bae61217f565b5060f89290921b6006830152600782015260270190565b634e487b7160e01b600052605160045260246000fdfea2646970667358221220fc103f19f529f25606dcf95d221632948bea361b65291f312c2bdf94f716271c64736f6c63430008090033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 29 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.