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:
OneStepProverMemory
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-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/Value.sol"; import "../state/Machine.sol"; import "../state/Deserialize.sol"; import "../state/ModuleMemory.sol"; import "./IOneStepProver.sol"; contract OneStepProverMemory is IOneStepProver { using MerkleProofLib for MerkleProof; using ModuleMemoryLib for ModuleMemory; using ValueLib for Value; using ValueStackLib for ValueStack; uint256 private constant LEAF_SIZE = 32; uint64 private constant PAGE_SIZE = 65536; function setLeafByte( bytes32 oldLeaf, uint256 idx, uint8 val ) internal pure returns (bytes32) { require(idx < LEAF_SIZE, "BAD_SET_LEAF_BYTE_IDX"); // Take into account that we are casting the leaf to a big-endian integer uint256 leafShift = (LEAF_SIZE - 1 - idx) * 8; uint256 newLeaf = uint256(oldLeaf); newLeaf &= ~(0xFF << leafShift); newLeaf |= uint256(val) << leafShift; return bytes32(newLeaf); } function executeMemoryLoad( Machine memory mach, Module memory mod, Instruction calldata inst, bytes calldata proof ) internal pure { ValueType ty; uint256 readBytes; bool signed; if (inst.opcode == Instructions.I32_LOAD) { ty = ValueType.I32; readBytes = 4; signed = false; } else if (inst.opcode == Instructions.I64_LOAD) { ty = ValueType.I64; readBytes = 8; signed = false; } else if (inst.opcode == Instructions.F32_LOAD) { ty = ValueType.F32; readBytes = 4; signed = false; } else if (inst.opcode == Instructions.F64_LOAD) { ty = ValueType.F64; readBytes = 8; signed = false; } else if (inst.opcode == Instructions.I32_LOAD8_S) { ty = ValueType.I32; readBytes = 1; signed = true; } else if (inst.opcode == Instructions.I32_LOAD8_U) { ty = ValueType.I32; readBytes = 1; signed = false; } else if (inst.opcode == Instructions.I32_LOAD16_S) { ty = ValueType.I32; readBytes = 2; signed = true; } else if (inst.opcode == Instructions.I32_LOAD16_U) { ty = ValueType.I32; readBytes = 2; signed = false; } else if (inst.opcode == Instructions.I64_LOAD8_S) { ty = ValueType.I64; readBytes = 1; signed = true; } else if (inst.opcode == Instructions.I64_LOAD8_U) { ty = ValueType.I64; readBytes = 1; signed = false; } else if (inst.opcode == Instructions.I64_LOAD16_S) { ty = ValueType.I64; readBytes = 2; signed = true; } else if (inst.opcode == Instructions.I64_LOAD16_U) { ty = ValueType.I64; readBytes = 2; signed = false; } else if (inst.opcode == Instructions.I64_LOAD32_S) { ty = ValueType.I64; readBytes = 4; signed = true; } else if (inst.opcode == Instructions.I64_LOAD32_U) { ty = ValueType.I64; readBytes = 4; signed = false; } else { revert("INVALID_MEMORY_LOAD_OPCODE"); } uint256 index = inst.argumentData + mach.valueStack.pop().assumeI32(); (bool err, uint256 value, ) = mod.moduleMemory.load(index, readBytes, proof, 0); if (err) { mach.status = MachineStatus.ERRORED; return; } uint64 readValue = uint64(value); if (signed) { // Go down to the original uint size, change to signed, go up to correct size, convert back to unsigned if (readBytes == 1 && ty == ValueType.I32) { readValue = uint32(int32(int8(uint8(readValue)))); } else if (readBytes == 1 && ty == ValueType.I64) { readValue = uint64(int64(int8(uint8(readValue)))); } else if (readBytes == 2 && ty == ValueType.I32) { readValue = uint32(int32(int16(uint16(readValue)))); } else if (readBytes == 2 && ty == ValueType.I64) { readValue = uint64(int64(int16(uint16(readValue)))); } else if (readBytes == 4 && ty == ValueType.I64) { readValue = uint64(int64(int32(uint32(readValue)))); } else { revert("BAD_READ_BYTES_SIGNED"); } } mach.valueStack.push(Value({valueType: ty, contents: readValue})); } function executeMemoryStore( Machine memory mach, Module memory mod, Instruction calldata inst, bytes calldata proof ) internal pure { uint64 writeBytes; uint64 toWrite; { ValueType ty; if (inst.opcode == Instructions.I32_STORE) { ty = ValueType.I32; writeBytes = 4; } else if (inst.opcode == Instructions.I64_STORE) { ty = ValueType.I64; writeBytes = 8; } else if (inst.opcode == Instructions.F32_STORE) { ty = ValueType.F32; writeBytes = 4; } else if (inst.opcode == Instructions.F64_STORE) { ty = ValueType.F64; writeBytes = 8; } else if (inst.opcode == Instructions.I32_STORE8) { ty = ValueType.I32; writeBytes = 1; } else if (inst.opcode == Instructions.I32_STORE16) { ty = ValueType.I32; writeBytes = 2; } else if (inst.opcode == Instructions.I64_STORE8) { ty = ValueType.I64; writeBytes = 1; } else if (inst.opcode == Instructions.I64_STORE16) { ty = ValueType.I64; writeBytes = 2; } else if (inst.opcode == Instructions.I64_STORE32) { ty = ValueType.I64; writeBytes = 4; } else { revert("INVALID_MEMORY_STORE_OPCODE"); } Value memory writingVal = mach.valueStack.pop(); require(writingVal.valueType == ty, "BAD_STORE_TYPE"); toWrite = uint64(writingVal.contents); if (writeBytes < 8) { toWrite &= (uint64(1) << (writeBytes * 8)) - 1; } } // Neither of these can overflow as they're computed with much less than 256 bit integers. uint256 startIdx = inst.argumentData + mach.valueStack.pop().assumeI32(); if (startIdx + writeBytes > mod.moduleMemory.size) { mach.status = MachineStatus.ERRORED; return; } uint256 proofOffset = 0; uint256 lastProvedLeafIdx = ~uint256(0); MerkleProof memory lastProvedMerkle; bytes32 lastProvedLeafContents; for (uint256 i = 0; i < writeBytes; i++) { uint256 idx = startIdx + i; uint256 leafIdx = idx / LEAF_SIZE; if (leafIdx != lastProvedLeafIdx) { if (lastProvedLeafIdx != ~uint256(0)) { // Apply the last leaf update mod.moduleMemory.merkleRoot = lastProvedMerkle.computeRootFromMemory( lastProvedLeafIdx, lastProvedLeafContents ); } // This hits the stack size if we phrase it as mod.moduleMemory.proveLeaf(...) (lastProvedLeafContents, proofOffset, lastProvedMerkle) = ModuleMemoryLib.proveLeaf( mod.moduleMemory, leafIdx, proof, proofOffset ); lastProvedLeafIdx = leafIdx; } uint256 indexWithinLeaf = idx % LEAF_SIZE; lastProvedLeafContents = setLeafByte( lastProvedLeafContents, indexWithinLeaf, uint8(toWrite) ); toWrite >>= 8; } mod.moduleMemory.merkleRoot = lastProvedMerkle.computeRootFromMemory( lastProvedLeafIdx, lastProvedLeafContents ); } function executeMemorySize( Machine memory mach, Module memory mod, Instruction calldata, bytes calldata ) internal pure { uint32 pages = uint32(mod.moduleMemory.size / PAGE_SIZE); mach.valueStack.push(ValueLib.newI32(pages)); } function executeMemoryGrow( Machine memory mach, Module memory mod, Instruction calldata, bytes calldata ) internal pure { uint32 oldPages = uint32(mod.moduleMemory.size / PAGE_SIZE); uint32 growingPages = mach.valueStack.pop().assumeI32(); // Safe as the input integers are too small to overflow a uint256 uint256 newSize = uint256(oldPages) + uint256(growingPages); if (newSize <= mod.moduleMemory.maxSize) { mod.moduleMemory.size = uint64(newSize * PAGE_SIZE); mach.valueStack.push(ValueLib.newI32(oldPages)); } else { mach.valueStack.push(ValueLib.newI32(~uint32(0))); } } 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.I32_LOAD && opcode <= Instructions.I64_LOAD32_U) { impl = executeMemoryLoad; } else if (opcode >= Instructions.I32_STORE && opcode <= Instructions.I64_STORE32) { impl = executeMemoryStore; } else if (opcode == Instructions.MEMORY_SIZE) { impl = executeMemorySize; } else if (opcode == Instructions.MEMORY_GROW) { impl = executeMemoryGrow; } else { revert("INVALID_MEMORY_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; import "./MerkleProof.sol"; import "./Deserialize.sol"; import "./ModuleMemoryCompact.sol"; library ModuleMemoryLib { using MerkleProofLib for MerkleProof; uint256 private constant LEAF_SIZE = 32; function hash(ModuleMemory memory mem) internal pure returns (bytes32) { return ModuleMemoryCompactLib.hash(mem); } function proveLeaf( ModuleMemory memory mem, uint256 leafIdx, bytes calldata proof, uint256 startOffset ) internal pure returns ( bytes32 contents, uint256 offset, MerkleProof memory merkle ) { offset = startOffset; (contents, offset) = Deserialize.b32(proof, offset); (merkle, offset) = Deserialize.merkleProof(proof, offset); bytes32 recomputedRoot = merkle.computeRootFromMemory(leafIdx, contents); require(recomputedRoot == mem.merkleRoot, "WRONG_MEM_ROOT"); } function isValidLeaf(ModuleMemory memory mem, uint256 pointer) internal pure returns (bool) { return pointer + 32 <= mem.size && pointer % LEAF_SIZE == 0; } function pullLeafByte(bytes32 leaf, uint256 idx) internal pure returns (uint8) { require(idx < LEAF_SIZE, "BAD_PULL_LEAF_BYTE_IDX"); // Take into account that we are casting the leaf to a big-endian integer uint256 leafShift = (LEAF_SIZE - 1 - idx) * 8; return uint8(uint256(leaf) >> leafShift); } // loads a big-endian value from memory function load( ModuleMemory memory mem, uint256 start, uint256 width, bytes calldata proof, uint256 proofOffset ) internal pure returns ( bool err, uint256 value, uint256 offset ) { if (start + width > mem.size) { return (true, 0, proofOffset); } uint256 lastProvedLeafIdx = ~uint256(0); bytes32 lastProvedLeafContents; uint256 readValue; for (uint256 i = 0; i < width; i++) { uint256 idx = start + i; uint256 leafIdx = idx / LEAF_SIZE; if (leafIdx != lastProvedLeafIdx) { (lastProvedLeafContents, proofOffset, ) = proveLeaf( mem, leafIdx, proof, proofOffset ); lastProvedLeafIdx = leafIdx; } uint256 indexWithinLeaf = idx % LEAF_SIZE; readValue |= uint256(pullLeafByte(lastProvedLeafContents, indexWithinLeaf)) << (i * 8); } return (false, readValue, proofOffset); } }
// Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; struct ModuleMemory { uint64 size; uint64 maxSize; bytes32 merkleRoot; } library ModuleMemoryCompactLib { function hash(ModuleMemory memory mem) internal pure returns (bytes32) { return keccak256(abi.encodePacked("Memory:", mem.size, mem.maxSize, mem.merkleRoot)); } }
// Copyright 2021-2024, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; struct MultiStack { bytes32 inactiveStackHash; // NO_STACK_HASH if no stack, 0 if empty stack bytes32 remainingHash; // 0 if less than 2 cothreads exist } library MultiStackLib { bytes32 internal constant NO_STACK_HASH = ~bytes32(0); function hash( MultiStack memory multi, bytes32 activeStackHash, bool cothread ) internal pure returns (bytes32) { require(activeStackHash != NO_STACK_HASH, "MULTISTACK_NOSTACK_ACTIVE"); if (cothread) { require(multi.inactiveStackHash != NO_STACK_HASH, "MULTISTACK_NOSTACK_MAIN"); return keccak256( abi.encodePacked( "multistack:", multi.inactiveStackHash, activeStackHash, multi.remainingHash ) ); } else { return keccak256( abi.encodePacked( "multistack:", activeStackHash, multi.inactiveStackHash, multi.remainingHash ) ); } } function setEmpty(MultiStack memory multi) internal pure { multi.inactiveStackHash = NO_STACK_HASH; multi.remainingHash = 0; } function pushNew(MultiStack memory multi) internal pure { if (multi.inactiveStackHash != NO_STACK_HASH) { multi.remainingHash = keccak256( abi.encodePacked("cothread:", multi.inactiveStackHash, multi.remainingHash) ); } multi.inactiveStackHash = 0; } }
// Copyright 2021-2023, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./Value.sol"; struct StackFrame { Value returnPc; bytes32 localsMerkleRoot; uint32 callerModule; uint32 callerModuleInternals; } struct StackFrameWindow { StackFrame[] proved; bytes32 remainingHash; } library StackFrameLib { using ValueLib for Value; function hash(StackFrame memory frame) internal pure returns (bytes32) { return keccak256( abi.encodePacked( "Stack frame:", frame.returnPc.hash(), frame.localsMerkleRoot, frame.callerModule, frame.callerModuleInternals ) ); } function hash(StackFrameWindow memory window) internal pure returns (bytes32 h) { h = window.remainingHash; for (uint256 i = 0; i < window.proved.length; i++) { h = keccak256(abi.encodePacked("Stack frame stack:", hash(window.proved[i]), h)); } } function peek(StackFrameWindow memory window) internal pure returns (StackFrame memory) { require(window.proved.length == 1, "BAD_WINDOW_LENGTH"); return window.proved[0]; } function pop(StackFrameWindow memory window) internal pure returns (StackFrame memory frame) { require(window.proved.length == 1, "BAD_WINDOW_LENGTH"); frame = window.proved[0]; window.proved = new StackFrame[](0); } function push(StackFrameWindow memory window, StackFrame memory frame) internal pure { StackFrame[] memory newProved = new StackFrame[](window.proved.length + 1); for (uint256 i = 0; i < window.proved.length; i++) { newProved[i] = window.proved[i]; } newProved[window.proved.length] = frame; window.proved = newProved; } function overwrite(StackFrameWindow memory window, bytes32 root) internal pure { window.remainingHash = root; delete window.proved; } }
// Copyright 2021-2023, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; enum ValueType { I32, I64, F32, F64, REF_NULL, FUNC_REF, INTERNAL_REF } struct Value { ValueType valueType; uint256 contents; } library ValueLib { function hash(Value memory val) internal pure returns (bytes32) { return keccak256(abi.encodePacked("Value:", val.valueType, val.contents)); } function maxValueType() internal pure returns (ValueType) { return ValueType.INTERNAL_REF; } function assumeI32(Value memory val) internal pure returns (uint32) { uint256 uintval = uint256(val.contents); require(val.valueType == ValueType.I32, "NOT_I32"); require(uintval < (1 << 32), "BAD_I32"); return uint32(uintval); } function assumeI64(Value memory val) internal pure returns (uint64) { uint256 uintval = uint256(val.contents); require(val.valueType == ValueType.I64, "NOT_I64"); require(uintval < (1 << 64), "BAD_I64"); return uint64(uintval); } function newRefNull() internal pure returns (Value memory) { return Value({valueType: ValueType.REF_NULL, contents: 0}); } function newI32(uint32 x) internal pure returns (Value memory) { return Value({valueType: ValueType.I32, contents: uint256(x)}); } function newI64(uint64 x) internal pure returns (Value memory) { return Value({valueType: ValueType.I64, contents: uint256(x)}); } function newBoolean(bool x) internal pure returns (Value memory) { if (x) { return newI32(uint32(1)); } else { return newI32(uint32(0)); } } function newPc( uint32 funcPc, uint32 func, uint32 module ) internal pure returns (Value memory) { uint256 data = 0; data |= funcPc; data |= uint256(func) << 32; data |= uint256(module) << 64; return Value({valueType: ValueType.INTERNAL_REF, contents: data}); } }
// Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./Value.sol"; struct ValueArray { Value[] inner; } library ValueArrayLib { function get(ValueArray memory arr, uint256 index) internal pure returns (Value memory) { return arr.inner[index]; } function set( ValueArray memory arr, uint256 index, Value memory val ) internal pure { arr.inner[index] = val; } function length(ValueArray memory arr) internal pure returns (uint256) { return arr.inner.length; } function push(ValueArray memory arr, Value memory val) internal pure { Value[] memory newInner = new Value[](arr.inner.length + 1); for (uint256 i = 0; i < arr.inner.length; i++) { newInner[i] = arr.inner[i]; } newInner[arr.inner.length] = val; arr.inner = newInner; } function pop(ValueArray memory arr) internal pure returns (Value memory popped) { popped = arr.inner[arr.inner.length - 1]; Value[] memory newInner = new Value[](arr.inner.length - 1); for (uint256 i = 0; i < newInner.length; i++) { newInner[i] = arr.inner[i]; } arr.inner = newInner; } }
// Copyright 2021-2023, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./Value.sol"; import "./ValueArray.sol"; struct ValueStack { ValueArray proved; bytes32 remainingHash; } library ValueStackLib { using ValueLib for Value; using ValueArrayLib for ValueArray; function hash(ValueStack memory stack) internal pure returns (bytes32 h) { h = stack.remainingHash; uint256 len = stack.proved.length(); for (uint256 i = 0; i < len; i++) { h = keccak256(abi.encodePacked("Value stack:", stack.proved.get(i).hash(), h)); } } function peek(ValueStack memory stack) internal pure returns (Value memory) { uint256 len = stack.proved.length(); return stack.proved.get(len - 1); } function pop(ValueStack memory stack) internal pure returns (Value memory) { return stack.proved.pop(); } function push(ValueStack memory stack, Value memory val) internal pure { return stack.proved.push(val); } function overwrite(ValueStack memory stack, bytes32 root) internal pure { stack.remainingHash = root; delete stack.proved; } }
{ "optimizer": { "enabled": true, "runs": 100 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"components":[{"internalType":"uint256","name":"maxInboxMessagesRead","type":"uint256"},{"internalType":"contract IBridge","name":"bridge","type":"address"}],"internalType":"struct ExecutionContext","name":"","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
608060405234801561001057600080fd5b50611f84806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80633604366f14610030575b600080fd5b61004361003e366004611444565b61005a565b604051610051929190611658565b60405180910390f35b610062611341565b6040805160c081018252600080825282516060808201855282825260208083018490528286018490528401919091529282018190529181018290526080810182905260a08101919091526100b587611b80565b91506100c636879003870187611cbc565b905060006100d76020870187611d5e565b9050611422602861ffff8316108015906100f65750603561ffff831611155b1561010457506101bb61019d565b603661ffff83161080159061011e5750603e61ffff831611155b1561012c575061062661019d565b61ffff8216603f141561014257506109d061019d565b61ffff8216604014156101585750610a0861019d565b60405162461bcd60e51b8152602060048201526015602482015274494e56414c49445f4d454d4f52595f4f50434f444560581b60448201526064015b60405180910390fd5b6101ae84848989898663ffffffff16565b5050965096945050505050565b6000808060286101ce6020880188611d5e565b61ffff1614156101e7575060009150600490508161043c565b60296101f66020880188611d5e565b61ffff16141561021057506001915060089050600061043c565b602a61021f6020880188611d5e565b61ffff16141561023957506002915060049050600061043c565b602b6102486020880188611d5e565b61ffff16141561026257506003915060089050600061043c565b602c6102716020880188611d5e565b61ffff16141561028a575060009150600190508061043c565b602d6102996020880188611d5e565b61ffff1614156102b2575060009150600190508161043c565b602e6102c16020880188611d5e565b61ffff1614156102db57506000915060029050600161043c565b602f6102ea6020880188611d5e565b61ffff161415610303575060009150600290508161043c565b60306103126020880188611d5e565b61ffff16141561032a5750600191508190508061043c565b60316103396020880188611d5e565b61ffff161415610352575060019150819050600061043c565b60326103616020880188611d5e565b61ffff16141561037a575060019150600290508161043c565b60336103896020880188611d5e565b61ffff1614156103a357506001915060029050600061043c565b60346103b26020880188611d5e565b61ffff1614156103cb575060019150600490508161043c565b60356103da6020880188611d5e565b61ffff1614156103f457506001915060049050600061043c565b60405162461bcd60e51b815260206004820152601a60248201527f494e56414c49445f4d454d4f52595f4c4f41445f4f50434f44450000000000006044820152606401610194565b600061045361044e8a60200151610ab7565b610adc565b6104679063ffffffff166020890135611d98565b602089015190915060009081906104829084878b8b86610b6d565b5091509150811561049d575050600289525061061f92505050565b8084156105dc578560011480156104c5575060008760068111156104c3576104c3611529565b145b156104db578060000b63ffffffff1690506105dc565b8560011480156104fc575060018760068111156104fa576104fa611529565b145b156105095760000b6105dc565b85600214801561052a5750600087600681111561052857610528611529565b145b15610540578060010b63ffffffff1690506105dc565b8560021480156105615750600187600681111561055f5761055f611529565b145b1561056e5760010b6105dc565b85600414801561058f5750600187600681111561058d5761058d611529565b145b1561059c5760030b6105dc565b60405162461bcd60e51b815260206004820152601560248201527410905117d491505117d096551154d7d4d251d39151605a1b6044820152606401610194565b61061760405180604001604052808960068111156105fc576105fc611529565b81526001600160401b0384166020918201528e015190610c45565b505050505050505b5050505050565b6000808060366106396020880188611d5e565b61ffff16141561064f57506004915060006107be565b603761065e6020880188611d5e565b61ffff16141561067457506008915060016107be565b60386106836020880188611d5e565b61ffff16141561069957506004915060026107be565b60396106a86020880188611d5e565b61ffff1614156106be57506008915060036107be565b603a6106cd6020880188611d5e565b61ffff1614156106e357506001915060006107be565b603b6106f26020880188611d5e565b61ffff16141561070857506002915060006107be565b603c6107176020880188611d5e565b61ffff16141561072c575060019150816107be565b603d61073b6020880188611d5e565b61ffff16141561075157506002915060016107be565b603e6107606020880188611d5e565b61ffff16141561077657506004915060016107be565b60405162461bcd60e51b815260206004820152601b60248201527f494e56414c49445f4d454d4f52595f53544f52455f4f50434f444500000000006044820152606401610194565b60006107cd8960200151610ab7565b90508160068111156107e1576107e1611529565b815160068111156107f4576107f4611529565b146108325760405162461bcd60e51b815260206004820152600e60248201526d4241445f53544f52455f5459504560901b6044820152606401610194565b806020015192506008846001600160401b0316101561087d576001610858856008611db0565b6001600160401b031660016001600160401b0316901b6108789190611ddf565b831692505b5050600061089161044e8960200151610ab7565b6108a59063ffffffff166020880135611d98565b90508660200151600001516001600160401b0316836001600160401b0316826108ce9190611d98565b11156108e0575050600286525061061f565b604080516020810190915260608152600090600019906000805b876001600160401b03168110156109ad5760006109178288611d98565b90506000610926602083611e1d565b905085811461096b57600019861461094d57610943858786610c55565b60208f0151604001525b61095e8e60200151828e8e8b610cd6565b9098509196509094509250845b6000610978602084611e31565b905061098585828c610d70565b945060088a6001600160401b0316901c995050505080806109a590611e45565b9150506108fa565b506109b9828483610c55565b60208c015160400152505050505050505050505050565b6020840151516000906109e7906201000090611e60565b9050610a006109f582610df5565b602088015190610c45565b505050505050565b602084015151600090610a1f906201000090611e60565b90506000610a3361044e8860200151610ab7565b90506000610a4a63ffffffff808416908516611d98565b90508660200151602001516001600160401b03168111610a9f57610a716201000082611e86565b60208801516001600160401b039091169052610a9a610a8f84610df5565b60208a015190610c45565b610aad565b610aad610a8f600019610df5565b5050505050505050565b60408051808201909152600080825260208201528151610ad690610e28565b92915050565b60208101516000908183516006811115610af857610af8611529565b14610b2f5760405162461bcd60e51b81526020600482015260076024820152662727aa2fa4999960c91b6044820152606401610194565b6401000000008110610ad65760405162461bcd60e51b81526020600482015260076024820152662120a22fa4999960c91b6044820152606401610194565b8551600090819081906001600160401b0316610b89888a611d98565b1115610b9e5750600191506000905082610c39565b600019600080805b8a811015610c2c576000610bba828e611d98565b90506000610bc9602083611e1d565b9050858114610be957610bdf8f828e8e8e610cd6565b509a509095509350845b6000610bf6602084611e31565b9050610c03846008611e86565b610c0d8783610f38565b60ff16901b851794505050508080610c2490611e45565b915050610ba6565b5060009550935085925050505b96509650969350505050565b8151610c519082610fb2565b5050565b6040516b26b2b6b7b93c903632b0b31d60a11b6020820152602c81018290526000908190604c01604051602081830303815290604052805190602001209050610ccb8585836040518060400160405280601381526020017226b2b6b7b93c9036b2b935b632903a3932b29d60691b8152506110a5565b9150505b9392505050565b600080610cef6040518060200160405280606081525090565b839150610cfd8686846111b7565b9093509150610d0d8686846111d3565b925090506000610d1e828986610c55565b905088604001518114610d645760405162461bcd60e51b815260206004820152600e60248201526d15d493d391d7d3515357d493d3d560921b6044820152606401610194565b50955095509592505050565b600060208310610dba5760405162461bcd60e51b81526020600482015260156024820152740848288bea68aa8be988a828cbe84b2a88abe9288b605b1b6044820152606401610194565b600083610dc960016020611ea5565b610dd39190611ea5565b610dde906008611e86565b60ff848116821b911b198616179150509392505050565b604080518082019091526000808252602082015250604080518082019091526000815263ffffffff909116602082015290565b604080518082019091526000808252602082015281518051610e4c90600190611ea5565b81518110610e5c57610e5c611ebc565b6020026020010151905060006001836000015151610e7a9190611ea5565b6001600160401b03811115610e9157610e916117d0565b604051908082528060200260200182016040528015610ed657816020015b6040805180820190915260008082526020820152815260200190600190039081610eaf5790505b50905060005b8151811015610f31578351805182908110610ef957610ef9611ebc565b6020026020010151828281518110610f1357610f13611ebc565b60200260200101819052508080610f2990611e45565b915050610edc565b5090915290565b600060208210610f835760405162461bcd60e51b81526020600482015260166024820152750848288bea0aa9898be988a828cbe84b2a88abe9288b60531b6044820152606401610194565b600082610f9260016020611ea5565b610f9c9190611ea5565b610fa7906008611e86565b9390931c9392505050565b815151600090610fc3906001611d98565b6001600160401b03811115610fda57610fda6117d0565b60405190808252806020026020018201604052801561101f57816020015b6040805180820190915260008082526020820152815260200190600190039081610ff85790505b50905060005b83515181101561107b57835180518290811061104357611043611ebc565b602002602001015182828151811061105d5761105d611ebc565b6020026020010181905250808061107390611e45565b915050611025565b5081818460000151518151811061109457611094611ebc565b602090810291909101015290915250565b8160005b85515181101561116e576001851661110a578282876000015183815181106110d3576110d3611ebc565b60200260200101516040516020016110ed93929190611ed2565b604051602081830303815290604052805190602001209150611155565b828660000151828151811061112157611121611ebc565b60200260200101518360405160200161113c93929190611ed2565b6040516020818303038152906040528051906020012091505b60019490941c938061116681611e45565b9150506110a9565b5083156111af5760405162461bcd60e51b815260206004820152600f60248201526e141493d3d197d513d3d7d4d213d495608a1b6044820152606401610194565b949350505050565b600081816111c68686846112ad565b9097909650945050505050565b6040805160208101909152606081528160006111f086868461130b565b92509050600060ff82166001600160401b03811115611211576112116117d0565b60405190808252806020026020018201604052801561123a578160200160208202803683370190505b50905060005b8260ff168160ff161015611291576112598888866111b7565b838360ff168151811061126e5761126e611ebc565b60200260200101819650828152505050808061128990611f18565b915050611240565b5060405180602001604052808281525093505050935093915050565b600081815b602081101561130257600883901b92508585838181106112d4576112d4611ebc565b919091013560f81c939093179250816112ec81611e45565b92505080806112fa90611e45565b9150506112b2565b50935093915050565b60008184848281811061132057611320611ebc565b919091013560f81c925081905061133681611e45565b915050935093915050565b604080516101808101909152806000815260200161137660408051606080820183529181019182529081526000602082015290565b81526040805180820182526000808252602080830191909152830152016113b460408051606080820183529181019182529081526000602082015290565b81526020016113d9604051806040016040528060608152602001600080191681525090565b815260408051808201825260008082526020808301829052840191909152908201819052606082018190526080820181905260a0820181905260c0820181905260e09091015290565b61142a611f38565b565b60006040828403121561143e57600080fd5b50919050565b6000806000806000808688036101c08082121561146057600080fd5b61146a8a8a61142c565b975060408901356001600160401b038082111561148657600080fd5b818b01915082828d03121561149a57600080fd5b819850610100605f19850112156114b057600080fd5b60608b0197506114c48c6101608d0161142c565b96506101a08b01359350808411156114db57600080fd5b838b0193508b601f8501126114ef57600080fd5b833592508083111561150057600080fd5b505089602082840101111561151457600080fd5b60208201935080925050509295509295509295565b634e487b7160e01b600052602160045260246000fd5b6004811061154f5761154f611529565b9052565b80516007811061156557611565611529565b8252602090810151910152565b805160408084529051602084830181905281516060860181905260009392820191849160808801905b808410156115c2576115ae828651611553565b93820193600193909301929085019061159b565b509581015196019590955250919392505050565b8051604080845281518482018190526000926060916020918201918388019190865b8281101561164157845161160d858251611553565b80830151858901528781015163ffffffff90811688870152908701511660808501529381019360a0909301926001016115f8565b509687015197909601969096525093949350505050565b600061012080835261166d818401865161153f565b60208501516101c0610140818187015261168b6102e0870184611572565b925060408801516101606116ab8189018380518252602090810151910152565b60608a0151915061011f1980898703016101a08a01526116cb8684611572565b955060808b015192508089870301858a0152506116e885836115d6565b60a08b015180516101e08b015260208101516102008b0152909550935060c08a015161022089015260e08a015163ffffffff81166102408a015293506101008a015163ffffffff81166102608a015293509489015163ffffffff811661028089015294918901516102a0880152508701516102c0860152509150610ccf905060208301848051825260208101516001600160401b0380825116602085015280602083015116604085015250604081015160608401525060408101516080830152606081015160a0830152608081015160c083015263ffffffff60a08201511660e08301525050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715611808576118086117d0565b60405290565b604051602081016001600160401b0381118282101715611808576118086117d0565b604051608081016001600160401b0381118282101715611808576118086117d0565b60405161018081016001600160401b0381118282101715611808576118086117d0565b60405160c081016001600160401b0381118282101715611808576118086117d0565b604051606081016001600160401b0381118282101715611808576118086117d0565b604051601f8201601f191681016001600160401b03811182821017156118e1576118e16117d0565b604052919050565b8035600481106118f857600080fd5b919050565b60006001600160401b03821115611916576119166117d0565b5060051b60200190565b60006040828403121561193257600080fd5b61193a6117e6565b905081356007811061194b57600080fd5b808252506020820135602082015292915050565b6000604080838503121561197257600080fd5b61197a6117e6565b915082356001600160401b038082111561199357600080fd5b818501915060208083880312156119a957600080fd5b6119b161180e565b8335838111156119c057600080fd5b80850194505087601f8501126119d557600080fd5b833592506119ea6119e5846118fd565b6118b9565b83815260069390931b84018201928281019089851115611a0957600080fd5b948301945b84861015611a2f57611a208a87611920565b82529486019490830190611a0e565b8252508552948501359484019490945250909392505050565b600060408284031215611a5a57600080fd5b611a626117e6565b9050813581526020820135602082015292915050565b803563ffffffff811681146118f857600080fd5b60006040808385031215611a9f57600080fd5b611aa76117e6565b915082356001600160401b03811115611abf57600080fd5b8301601f81018513611ad057600080fd5b80356020611ae06119e5836118fd565b82815260a09283028401820192828201919089851115611aff57600080fd5b948301945b84861015611b685780868b031215611b1c5760008081fd5b611b24611830565b611b2e8b88611920565b815287870135858201526060611b45818901611a78565b89830152611b5560808901611a78565b9082015283529485019491830191611b04565b50808752505080860135818601525050505092915050565b60006101c08236031215611b9357600080fd5b611b9b611852565b611ba4836118e9565b815260208301356001600160401b0380821115611bc057600080fd5b611bcc3683870161195f565b6020840152611bde3660408701611a48565b60408401526080850135915080821115611bf757600080fd5b611c033683870161195f565b606084015260a0850135915080821115611c1c57600080fd5b50611c2936828601611a8c565b608083015250611c3c3660c08501611a48565b60a08201526101008084013560c0830152610120611c5b818601611a78565b60e0840152610140611c6e818701611a78565b838501526101609250611c82838701611a78565b91840191909152610180850135908301526101a090930135928101929092525090565b80356001600160401b03811681146118f857600080fd5b6000818303610100811215611cd057600080fd5b611cd8611875565b833581526060601f1983011215611cee57600080fd5b611cf6611897565b9150611d0460208501611ca5565b8252611d1260408501611ca5565b6020830152606084013560408301528160208201526080840135604082015260a0840135606082015260c08401356080820152611d5160e08501611a78565b60a0820152949350505050565b600060208284031215611d7057600080fd5b813561ffff81168114610ccf57600080fd5b634e487b7160e01b600052601160045260246000fd5b60008219821115611dab57611dab611d82565b500190565b60006001600160401b0380831681851681830481118215151615611dd657611dd6611d82565b02949350505050565b60006001600160401b0383811690831681811015611dff57611dff611d82565b039392505050565b634e487b7160e01b600052601260045260246000fd5b600082611e2c57611e2c611e07565b500490565b600082611e4057611e40611e07565b500690565b6000600019821415611e5957611e59611d82565b5060010190565b60006001600160401b0380841680611e7a57611e7a611e07565b92169190910492915050565b6000816000190483118215151615611ea057611ea0611d82565b500290565b600082821015611eb757611eb7611d82565b500390565b634e487b7160e01b600052603260045260246000fd5b6000845160005b81811015611ef35760208188018101518583015201611ed9565b81811115611f02576000828501525b5091909101928352506020820152604001919050565b600060ff821660ff811415611f2f57611f2f611d82565b60010192915050565b634e487b7160e01b600052605160045260246000fdfea264697066735822122075656d2789d3f1dcea2eac8ac49fb7a432ca87fcd7794f8df78e6331d332953c64736f6c63430008090033
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061002b5760003560e01c80633604366f14610030575b600080fd5b61004361003e366004611444565b61005a565b604051610051929190611658565b60405180910390f35b610062611341565b6040805160c081018252600080825282516060808201855282825260208083018490528286018490528401919091529282018190529181018290526080810182905260a08101919091526100b587611b80565b91506100c636879003870187611cbc565b905060006100d76020870187611d5e565b9050611422602861ffff8316108015906100f65750603561ffff831611155b1561010457506101bb61019d565b603661ffff83161080159061011e5750603e61ffff831611155b1561012c575061062661019d565b61ffff8216603f141561014257506109d061019d565b61ffff8216604014156101585750610a0861019d565b60405162461bcd60e51b8152602060048201526015602482015274494e56414c49445f4d454d4f52595f4f50434f444560581b60448201526064015b60405180910390fd5b6101ae84848989898663ffffffff16565b5050965096945050505050565b6000808060286101ce6020880188611d5e565b61ffff1614156101e7575060009150600490508161043c565b60296101f66020880188611d5e565b61ffff16141561021057506001915060089050600061043c565b602a61021f6020880188611d5e565b61ffff16141561023957506002915060049050600061043c565b602b6102486020880188611d5e565b61ffff16141561026257506003915060089050600061043c565b602c6102716020880188611d5e565b61ffff16141561028a575060009150600190508061043c565b602d6102996020880188611d5e565b61ffff1614156102b2575060009150600190508161043c565b602e6102c16020880188611d5e565b61ffff1614156102db57506000915060029050600161043c565b602f6102ea6020880188611d5e565b61ffff161415610303575060009150600290508161043c565b60306103126020880188611d5e565b61ffff16141561032a5750600191508190508061043c565b60316103396020880188611d5e565b61ffff161415610352575060019150819050600061043c565b60326103616020880188611d5e565b61ffff16141561037a575060019150600290508161043c565b60336103896020880188611d5e565b61ffff1614156103a357506001915060029050600061043c565b60346103b26020880188611d5e565b61ffff1614156103cb575060019150600490508161043c565b60356103da6020880188611d5e565b61ffff1614156103f457506001915060049050600061043c565b60405162461bcd60e51b815260206004820152601a60248201527f494e56414c49445f4d454d4f52595f4c4f41445f4f50434f44450000000000006044820152606401610194565b600061045361044e8a60200151610ab7565b610adc565b6104679063ffffffff166020890135611d98565b602089015190915060009081906104829084878b8b86610b6d565b5091509150811561049d575050600289525061061f92505050565b8084156105dc578560011480156104c5575060008760068111156104c3576104c3611529565b145b156104db578060000b63ffffffff1690506105dc565b8560011480156104fc575060018760068111156104fa576104fa611529565b145b156105095760000b6105dc565b85600214801561052a5750600087600681111561052857610528611529565b145b15610540578060010b63ffffffff1690506105dc565b8560021480156105615750600187600681111561055f5761055f611529565b145b1561056e5760010b6105dc565b85600414801561058f5750600187600681111561058d5761058d611529565b145b1561059c5760030b6105dc565b60405162461bcd60e51b815260206004820152601560248201527410905117d491505117d096551154d7d4d251d39151605a1b6044820152606401610194565b61061760405180604001604052808960068111156105fc576105fc611529565b81526001600160401b0384166020918201528e015190610c45565b505050505050505b5050505050565b6000808060366106396020880188611d5e565b61ffff16141561064f57506004915060006107be565b603761065e6020880188611d5e565b61ffff16141561067457506008915060016107be565b60386106836020880188611d5e565b61ffff16141561069957506004915060026107be565b60396106a86020880188611d5e565b61ffff1614156106be57506008915060036107be565b603a6106cd6020880188611d5e565b61ffff1614156106e357506001915060006107be565b603b6106f26020880188611d5e565b61ffff16141561070857506002915060006107be565b603c6107176020880188611d5e565b61ffff16141561072c575060019150816107be565b603d61073b6020880188611d5e565b61ffff16141561075157506002915060016107be565b603e6107606020880188611d5e565b61ffff16141561077657506004915060016107be565b60405162461bcd60e51b815260206004820152601b60248201527f494e56414c49445f4d454d4f52595f53544f52455f4f50434f444500000000006044820152606401610194565b60006107cd8960200151610ab7565b90508160068111156107e1576107e1611529565b815160068111156107f4576107f4611529565b146108325760405162461bcd60e51b815260206004820152600e60248201526d4241445f53544f52455f5459504560901b6044820152606401610194565b806020015192506008846001600160401b0316101561087d576001610858856008611db0565b6001600160401b031660016001600160401b0316901b6108789190611ddf565b831692505b5050600061089161044e8960200151610ab7565b6108a59063ffffffff166020880135611d98565b90508660200151600001516001600160401b0316836001600160401b0316826108ce9190611d98565b11156108e0575050600286525061061f565b604080516020810190915260608152600090600019906000805b876001600160401b03168110156109ad5760006109178288611d98565b90506000610926602083611e1d565b905085811461096b57600019861461094d57610943858786610c55565b60208f0151604001525b61095e8e60200151828e8e8b610cd6565b9098509196509094509250845b6000610978602084611e31565b905061098585828c610d70565b945060088a6001600160401b0316901c995050505080806109a590611e45565b9150506108fa565b506109b9828483610c55565b60208c015160400152505050505050505050505050565b6020840151516000906109e7906201000090611e60565b9050610a006109f582610df5565b602088015190610c45565b505050505050565b602084015151600090610a1f906201000090611e60565b90506000610a3361044e8860200151610ab7565b90506000610a4a63ffffffff808416908516611d98565b90508660200151602001516001600160401b03168111610a9f57610a716201000082611e86565b60208801516001600160401b039091169052610a9a610a8f84610df5565b60208a015190610c45565b610aad565b610aad610a8f600019610df5565b5050505050505050565b60408051808201909152600080825260208201528151610ad690610e28565b92915050565b60208101516000908183516006811115610af857610af8611529565b14610b2f5760405162461bcd60e51b81526020600482015260076024820152662727aa2fa4999960c91b6044820152606401610194565b6401000000008110610ad65760405162461bcd60e51b81526020600482015260076024820152662120a22fa4999960c91b6044820152606401610194565b8551600090819081906001600160401b0316610b89888a611d98565b1115610b9e5750600191506000905082610c39565b600019600080805b8a811015610c2c576000610bba828e611d98565b90506000610bc9602083611e1d565b9050858114610be957610bdf8f828e8e8e610cd6565b509a509095509350845b6000610bf6602084611e31565b9050610c03846008611e86565b610c0d8783610f38565b60ff16901b851794505050508080610c2490611e45565b915050610ba6565b5060009550935085925050505b96509650969350505050565b8151610c519082610fb2565b5050565b6040516b26b2b6b7b93c903632b0b31d60a11b6020820152602c81018290526000908190604c01604051602081830303815290604052805190602001209050610ccb8585836040518060400160405280601381526020017226b2b6b7b93c9036b2b935b632903a3932b29d60691b8152506110a5565b9150505b9392505050565b600080610cef6040518060200160405280606081525090565b839150610cfd8686846111b7565b9093509150610d0d8686846111d3565b925090506000610d1e828986610c55565b905088604001518114610d645760405162461bcd60e51b815260206004820152600e60248201526d15d493d391d7d3515357d493d3d560921b6044820152606401610194565b50955095509592505050565b600060208310610dba5760405162461bcd60e51b81526020600482015260156024820152740848288bea68aa8be988a828cbe84b2a88abe9288b605b1b6044820152606401610194565b600083610dc960016020611ea5565b610dd39190611ea5565b610dde906008611e86565b60ff848116821b911b198616179150509392505050565b604080518082019091526000808252602082015250604080518082019091526000815263ffffffff909116602082015290565b604080518082019091526000808252602082015281518051610e4c90600190611ea5565b81518110610e5c57610e5c611ebc565b6020026020010151905060006001836000015151610e7a9190611ea5565b6001600160401b03811115610e9157610e916117d0565b604051908082528060200260200182016040528015610ed657816020015b6040805180820190915260008082526020820152815260200190600190039081610eaf5790505b50905060005b8151811015610f31578351805182908110610ef957610ef9611ebc565b6020026020010151828281518110610f1357610f13611ebc565b60200260200101819052508080610f2990611e45565b915050610edc565b5090915290565b600060208210610f835760405162461bcd60e51b81526020600482015260166024820152750848288bea0aa9898be988a828cbe84b2a88abe9288b60531b6044820152606401610194565b600082610f9260016020611ea5565b610f9c9190611ea5565b610fa7906008611e86565b9390931c9392505050565b815151600090610fc3906001611d98565b6001600160401b03811115610fda57610fda6117d0565b60405190808252806020026020018201604052801561101f57816020015b6040805180820190915260008082526020820152815260200190600190039081610ff85790505b50905060005b83515181101561107b57835180518290811061104357611043611ebc565b602002602001015182828151811061105d5761105d611ebc565b6020026020010181905250808061107390611e45565b915050611025565b5081818460000151518151811061109457611094611ebc565b602090810291909101015290915250565b8160005b85515181101561116e576001851661110a578282876000015183815181106110d3576110d3611ebc565b60200260200101516040516020016110ed93929190611ed2565b604051602081830303815290604052805190602001209150611155565b828660000151828151811061112157611121611ebc565b60200260200101518360405160200161113c93929190611ed2565b6040516020818303038152906040528051906020012091505b60019490941c938061116681611e45565b9150506110a9565b5083156111af5760405162461bcd60e51b815260206004820152600f60248201526e141493d3d197d513d3d7d4d213d495608a1b6044820152606401610194565b949350505050565b600081816111c68686846112ad565b9097909650945050505050565b6040805160208101909152606081528160006111f086868461130b565b92509050600060ff82166001600160401b03811115611211576112116117d0565b60405190808252806020026020018201604052801561123a578160200160208202803683370190505b50905060005b8260ff168160ff161015611291576112598888866111b7565b838360ff168151811061126e5761126e611ebc565b60200260200101819650828152505050808061128990611f18565b915050611240565b5060405180602001604052808281525093505050935093915050565b600081815b602081101561130257600883901b92508585838181106112d4576112d4611ebc565b919091013560f81c939093179250816112ec81611e45565b92505080806112fa90611e45565b9150506112b2565b50935093915050565b60008184848281811061132057611320611ebc565b919091013560f81c925081905061133681611e45565b915050935093915050565b604080516101808101909152806000815260200161137660408051606080820183529181019182529081526000602082015290565b81526040805180820182526000808252602080830191909152830152016113b460408051606080820183529181019182529081526000602082015290565b81526020016113d9604051806040016040528060608152602001600080191681525090565b815260408051808201825260008082526020808301829052840191909152908201819052606082018190526080820181905260a0820181905260c0820181905260e09091015290565b61142a611f38565b565b60006040828403121561143e57600080fd5b50919050565b6000806000806000808688036101c08082121561146057600080fd5b61146a8a8a61142c565b975060408901356001600160401b038082111561148657600080fd5b818b01915082828d03121561149a57600080fd5b819850610100605f19850112156114b057600080fd5b60608b0197506114c48c6101608d0161142c565b96506101a08b01359350808411156114db57600080fd5b838b0193508b601f8501126114ef57600080fd5b833592508083111561150057600080fd5b505089602082840101111561151457600080fd5b60208201935080925050509295509295509295565b634e487b7160e01b600052602160045260246000fd5b6004811061154f5761154f611529565b9052565b80516007811061156557611565611529565b8252602090810151910152565b805160408084529051602084830181905281516060860181905260009392820191849160808801905b808410156115c2576115ae828651611553565b93820193600193909301929085019061159b565b509581015196019590955250919392505050565b8051604080845281518482018190526000926060916020918201918388019190865b8281101561164157845161160d858251611553565b80830151858901528781015163ffffffff90811688870152908701511660808501529381019360a0909301926001016115f8565b509687015197909601969096525093949350505050565b600061012080835261166d818401865161153f565b60208501516101c0610140818187015261168b6102e0870184611572565b925060408801516101606116ab8189018380518252602090810151910152565b60608a0151915061011f1980898703016101a08a01526116cb8684611572565b955060808b015192508089870301858a0152506116e885836115d6565b60a08b015180516101e08b015260208101516102008b0152909550935060c08a015161022089015260e08a015163ffffffff81166102408a015293506101008a015163ffffffff81166102608a015293509489015163ffffffff811661028089015294918901516102a0880152508701516102c0860152509150610ccf905060208301848051825260208101516001600160401b0380825116602085015280602083015116604085015250604081015160608401525060408101516080830152606081015160a0830152608081015160c083015263ffffffff60a08201511660e08301525050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715611808576118086117d0565b60405290565b604051602081016001600160401b0381118282101715611808576118086117d0565b604051608081016001600160401b0381118282101715611808576118086117d0565b60405161018081016001600160401b0381118282101715611808576118086117d0565b60405160c081016001600160401b0381118282101715611808576118086117d0565b604051606081016001600160401b0381118282101715611808576118086117d0565b604051601f8201601f191681016001600160401b03811182821017156118e1576118e16117d0565b604052919050565b8035600481106118f857600080fd5b919050565b60006001600160401b03821115611916576119166117d0565b5060051b60200190565b60006040828403121561193257600080fd5b61193a6117e6565b905081356007811061194b57600080fd5b808252506020820135602082015292915050565b6000604080838503121561197257600080fd5b61197a6117e6565b915082356001600160401b038082111561199357600080fd5b818501915060208083880312156119a957600080fd5b6119b161180e565b8335838111156119c057600080fd5b80850194505087601f8501126119d557600080fd5b833592506119ea6119e5846118fd565b6118b9565b83815260069390931b84018201928281019089851115611a0957600080fd5b948301945b84861015611a2f57611a208a87611920565b82529486019490830190611a0e565b8252508552948501359484019490945250909392505050565b600060408284031215611a5a57600080fd5b611a626117e6565b9050813581526020820135602082015292915050565b803563ffffffff811681146118f857600080fd5b60006040808385031215611a9f57600080fd5b611aa76117e6565b915082356001600160401b03811115611abf57600080fd5b8301601f81018513611ad057600080fd5b80356020611ae06119e5836118fd565b82815260a09283028401820192828201919089851115611aff57600080fd5b948301945b84861015611b685780868b031215611b1c5760008081fd5b611b24611830565b611b2e8b88611920565b815287870135858201526060611b45818901611a78565b89830152611b5560808901611a78565b9082015283529485019491830191611b04565b50808752505080860135818601525050505092915050565b60006101c08236031215611b9357600080fd5b611b9b611852565b611ba4836118e9565b815260208301356001600160401b0380821115611bc057600080fd5b611bcc3683870161195f565b6020840152611bde3660408701611a48565b60408401526080850135915080821115611bf757600080fd5b611c033683870161195f565b606084015260a0850135915080821115611c1c57600080fd5b50611c2936828601611a8c565b608083015250611c3c3660c08501611a48565b60a08201526101008084013560c0830152610120611c5b818601611a78565b60e0840152610140611c6e818701611a78565b838501526101609250611c82838701611a78565b91840191909152610180850135908301526101a090930135928101929092525090565b80356001600160401b03811681146118f857600080fd5b6000818303610100811215611cd057600080fd5b611cd8611875565b833581526060601f1983011215611cee57600080fd5b611cf6611897565b9150611d0460208501611ca5565b8252611d1260408501611ca5565b6020830152606084013560408301528160208201526080840135604082015260a0840135606082015260c08401356080820152611d5160e08501611a78565b60a0820152949350505050565b600060208284031215611d7057600080fd5b813561ffff81168114610ccf57600080fd5b634e487b7160e01b600052601160045260246000fd5b60008219821115611dab57611dab611d82565b500190565b60006001600160401b0380831681851681830481118215151615611dd657611dd6611d82565b02949350505050565b60006001600160401b0383811690831681811015611dff57611dff611d82565b039392505050565b634e487b7160e01b600052601260045260246000fd5b600082611e2c57611e2c611e07565b500490565b600082611e4057611e40611e07565b500690565b6000600019821415611e5957611e59611d82565b5060010190565b60006001600160401b0380841680611e7a57611e7a611e07565b92169190910492915050565b6000816000190483118215151615611ea057611ea0611d82565b500290565b600082821015611eb757611eb7611d82565b500390565b634e487b7160e01b600052603260045260246000fd5b6000845160005b81811015611ef35760208188018101518583015201611ed9565b81811115611f02576000828501525b5091909101928352506020820152604001919050565b600060ff821660ff811415611f2f57611f2f611d82565b60010192915050565b634e487b7160e01b600052605160045260246000fdfea264697066735822122075656d2789d3f1dcea2eac8ac49fb7a432ca87fcd7794f8df78e6331d332953c64736f6c63430008090033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.