Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
Loading...
Loading
Loading...
Loading
Contract Name:
ValidatorUtils
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;
pragma experimental ABIEncoderV2;
import "../rollup/IRollupCore.sol";
import "../challenge/IChallengeManager.sol";
import "./IRollupLogic.sol";
import {NO_CHAL_INDEX} from "../libraries/Constants.sol";
contract ValidatorUtils {
using NodeLib for Node;
enum ConfirmType {
NONE,
VALID,
INVALID
}
enum NodeConflictType {
NONE,
FOUND,
INDETERMINATE,
INCOMPLETE
}
struct NodeConflict {
NodeConflictType ty;
uint64 node1;
uint64 node2;
}
function findStakerConflict(
IRollupCore rollup,
address staker1,
address staker2,
uint256 maxDepth
) external view returns (NodeConflict memory) {
uint64 staker1NodeNum = rollup.latestStakedNode(staker1);
uint64 staker2NodeNum = rollup.latestStakedNode(staker2);
return findNodeConflict(rollup, staker1NodeNum, staker2NodeNum, maxDepth);
}
function checkDecidableNextNode(IRollupUserAbs rollup) external view returns (ConfirmType) {
try ValidatorUtils(address(this)).requireConfirmable(rollup) {
return ConfirmType.VALID;
} catch {}
try ValidatorUtils(address(this)).requireRejectable(rollup) {
return ConfirmType.INVALID;
} catch {
return ConfirmType.NONE;
}
}
function requireRejectable(IRollupCore rollup) external view {
IRollupUser(address(rollup)).requireUnresolvedExists();
uint64 firstUnresolvedNode = rollup.firstUnresolvedNode();
Node memory node = rollup.getNode(firstUnresolvedNode);
if (node.prevNum == rollup.latestConfirmed()) {
// Verify the block's deadline has passed
require(block.number >= node.deadlineBlock, "BEFORE_DEADLINE");
rollup.getNode(node.prevNum).requirePastChildConfirmDeadline();
// Verify that no staker is staked on this node
require(
node.stakerCount ==
IRollupUser(address(rollup)).countStakedZombies(firstUnresolvedNode),
"HAS_STAKERS"
);
}
}
function requireConfirmable(IRollupUserAbs rollup) external view {
rollup.requireUnresolvedExists();
uint256 stakerCount = rollup.stakerCount();
// There is at least one non-zombie staker
require(stakerCount > 0, "NO_STAKERS");
uint64 firstUnresolved = rollup.firstUnresolvedNode();
Node memory node = rollup.getNode(firstUnresolved);
// Verify the block's deadline has passed
node.requirePastDeadline();
// Check that prev is latest confirmed
assert(node.prevNum == rollup.latestConfirmed());
Node memory prevNode = rollup.getNode(node.prevNum);
prevNode.requirePastChildConfirmDeadline();
uint256 zombiesStakedOnOtherChildren = rollup.countZombiesStakedOnChildren(node.prevNum) -
rollup.countStakedZombies(firstUnresolved);
require(
prevNode.childStakerCount == node.stakerCount + zombiesStakedOnOtherChildren,
"NOT_ALL_STAKED"
);
}
function refundableStakers(IRollupCore rollup) external view returns (address[] memory) {
uint256 stakerCount = rollup.stakerCount();
address[] memory stakers = new address[](stakerCount);
uint256 latestConfirmed = rollup.latestConfirmed();
uint256 index = 0;
for (uint64 i = 0; i < stakerCount; i++) {
address staker = rollup.getStakerAddress(i);
uint256 latestStakedNode = rollup.latestStakedNode(staker);
if (latestStakedNode <= latestConfirmed && rollup.currentChallenge(staker) == 0) {
stakers[index] = staker;
index++;
}
}
assembly {
mstore(stakers, index)
}
return stakers;
}
function latestStaked(IRollupCore rollup, address staker)
external
view
returns (uint64, Node memory)
{
uint64 num = rollup.latestStakedNode(staker);
if (num == 0) {
num = rollup.latestConfirmed();
}
Node memory node = rollup.getNode(num);
return (num, node);
}
function stakedNodes(IRollupCore rollup, address staker)
external
view
returns (uint64[] memory)
{
uint64[] memory nodes = new uint64[](100000);
uint256 index = 0;
for (uint64 i = rollup.latestConfirmed(); i <= rollup.latestNodeCreated(); i++) {
if (rollup.nodeHasStaker(i, staker)) {
nodes[index] = i;
index++;
}
}
// Shrink array down to real size
assembly {
mstore(nodes, index)
}
return nodes;
}
function findNodeConflict(
IRollupCore rollup,
uint64 node1,
uint64 node2,
uint256 maxDepth
) public view returns (NodeConflict memory) {
uint64 firstUnresolvedNode = rollup.firstUnresolvedNode();
uint64 node1Prev = rollup.getNode(node1).prevNum;
uint64 node2Prev = rollup.getNode(node2).prevNum;
for (uint256 i = 0; i < maxDepth; i++) {
if (node1 == node2) {
return NodeConflict(NodeConflictType.NONE, node1, node2);
}
if (node1Prev == node2Prev) {
return NodeConflict(NodeConflictType.FOUND, node1, node2);
}
if (node1Prev < firstUnresolvedNode && node2Prev < firstUnresolvedNode) {
return NodeConflict(NodeConflictType.INDETERMINATE, 0, 0);
}
if (node1Prev < node2Prev) {
node2 = node2Prev;
node2Prev = rollup.getNode(node2).prevNum;
} else {
node1 = node1Prev;
node1Prev = rollup.getNode(node1).prevNum;
}
}
return NodeConflict(NodeConflictType.INCOMPLETE, 0, 0);
}
function getStakers(
IRollupCore rollup,
uint64 startIndex,
uint64 max
) public view returns (address[] memory, bool hasMore) {
uint256 maxStakers = rollup.stakerCount();
if (startIndex + max <= maxStakers) {
maxStakers = startIndex + max;
hasMore = true;
}
address[] memory stakers = new address[](maxStakers);
for (uint64 i = 0; i < maxStakers; i++) {
stakers[i] = rollup.getStakerAddress(startIndex + i);
}
return (stakers, hasMore);
}
function timedOutChallenges(
IRollupCore rollup,
uint64 startIndex,
uint64 max
) external view returns (uint64[] memory, bool hasMore) {
(address[] memory stakers, bool hasMoreStakers) = getStakers(rollup, startIndex, max);
uint64[] memory challenges = new uint64[](stakers.length);
uint256 index = 0;
IChallengeManager challengeManager = rollup.challengeManager();
for (uint256 i = 0; i < stakers.length; i++) {
address staker = stakers[i];
uint64 challengeIndex = rollup.currentChallenge(staker);
if (
challengeIndex != NO_CHAL_INDEX &&
challengeManager.isTimedOut(challengeIndex) &&
challengeManager.currentResponder(challengeIndex) == staker
) {
challenges[index++] = challengeIndex;
}
}
// Shrink array down to real size
assembly {
mstore(challenges, index)
}
return (challenges, hasMoreStakers);
}
// Worst case runtime of O(depth), as it terminates if it switches paths.
function areUnresolvedNodesLinear(IRollupCore rollup) external view returns (bool) {
uint256 end = rollup.latestNodeCreated();
for (uint64 i = rollup.firstUnresolvedNode(); i <= end; i++) {
if (i > 0 && rollup.getNode(i).prevNum != i - 1) {
return false;
}
}
return true;
}
}// 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.6.9 <0.9.0;
import "./IBridge.sol";
import "./IDelayedMessageProvider.sol";
import "./ISequencerInbox.sol";
interface IInboxBase is IDelayedMessageProvider {
function bridge() external view returns (IBridge);
function sequencerInbox() external view returns (ISequencerInbox);
function maxDataSize() external view returns (uint256);
/**
* @notice Send a generic L2 message to the chain
* @dev This method is an optimization to avoid having to emit the entirety of the messageData in a log. Instead validators are expected to be able to parse the data from the transaction's input
* @param messageData Data of the message being sent
*/
function sendL2MessageFromOrigin(bytes calldata messageData) external returns (uint256);
/**
* @notice Send a generic L2 message to the chain
* @dev This method can be used to send any type of message that doesn't require L1 validation
* @param messageData Data of the message being sent
*/
function sendL2Message(bytes calldata messageData) external returns (uint256);
function sendUnsignedTransaction(
uint256 gasLimit,
uint256 maxFeePerGas,
uint256 nonce,
address to,
uint256 value,
bytes calldata data
) external returns (uint256);
function sendContractTransaction(
uint256 gasLimit,
uint256 maxFeePerGas,
address to,
uint256 value,
bytes calldata data
) external returns (uint256);
/**
* @notice Get the L1 fee for submitting a retryable
* @dev This fee can be paid by funds already in the L2 aliased address or by the current message value
* @dev This formula may change in the future, to future proof your code query this method instead of inlining!!
* @param dataLength The length of the retryable's calldata, in bytes
* @param baseFee The block basefee when the retryable is included in the chain, if 0 current block.basefee will be used
*/
function calculateRetryableSubmissionFee(uint256 dataLength, uint256 baseFee)
external
view
returns (uint256);
// ---------- onlyRollupOrOwner functions ----------
/// @notice pauses all inbox functionality
function pause() external;
/// @notice unpauses all inbox functionality
function unpause() external;
/// @notice add or remove users from allowList
function setAllowList(address[] memory user, bool[] memory val) external;
/// @notice enable or disable allowList
function setAllowListEnabled(bool _allowListEnabled) external;
/// @notice check if user is in allowList
function isAllowed(address user) external view returns (bool);
/// @notice check if allowList is enabled
function allowListEnabled() external view returns (bool);
function initialize(IBridge _bridge, ISequencerInbox _sequencerInbox) external;
/// @notice returns the current admin
function getProxyAdmin() 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;
import "./IBridge.sol";
interface IOutbox {
event SendRootUpdated(bytes32 indexed outputRoot, bytes32 indexed l2BlockHash);
event OutBoxTransactionExecuted(
address indexed to,
address indexed l2Sender,
uint256 indexed zero,
uint256 transactionIndex
);
function initialize(IBridge _bridge) external;
function rollup() external view returns (address); // the rollup contract
function bridge() external view returns (IBridge); // the bridge contract
function spent(uint256) external view returns (bytes32); // packed spent bitmap
function roots(bytes32) external view returns (bytes32); // maps root hashes => L2 block hash
// solhint-disable-next-line func-name-mixedcase
function OUTBOX_VERSION() external view returns (uint128); // the outbox version
function updateSendRoot(bytes32 sendRoot, bytes32 l2BlockHash) external;
function updateRollupAddress() external;
/// @notice When l2ToL1Sender returns a nonzero address, the message was originated by an L2 account
/// When the return value is zero, that means this is a system message
/// @dev the l2ToL1Sender behaves as the tx.origin, the msg.sender should be validated to protect against reentrancies
function l2ToL1Sender() external view returns (address);
/// @return l2Block return L2 block when the L2 tx was initiated or 0 if no L2 to L1 transaction is active
function l2ToL1Block() external view returns (uint256);
/// @return l1Block return L1 block when the L2 tx was initiated or 0 if no L2 to L1 transaction is active
function l2ToL1EthBlock() external view returns (uint256);
/// @return timestamp return L2 timestamp when the L2 tx was initiated or 0 if no L2 to L1 transaction is active
function l2ToL1Timestamp() external view returns (uint256);
/// @return outputId returns the unique output identifier of the L2 to L1 tx or 0 if no L2 to L1 transaction is active
function l2ToL1OutputId() external view returns (bytes32);
/**
* @notice Executes a messages in an Outbox entry.
* @dev Reverts if dispute period hasn't expired, since the outbox entry
* is only created once the rollup confirms the respective assertion.
* @dev it is not possible to execute any L2-to-L1 transaction which contains data
* to a contract address without any code (as enforced by the Bridge contract).
* @param proof Merkle proof of message inclusion in send root
* @param index Merkle path to message
* @param l2Sender sender if original message (i.e., caller of ArbSys.sendTxToL1)
* @param to destination address for L1 contract call
* @param l2Block l2 block number at which sendTxToL1 call was made
* @param l1Block l1 block number at which sendTxToL1 call was made
* @param l2Timestamp l2 Timestamp at which sendTxToL1 call was made
* @param value wei in L1 message
* @param data abi-encoded L1 message data
*/
function executeTransaction(
bytes32[] calldata proof,
uint256 index,
address l2Sender,
address to,
uint256 l2Block,
uint256 l1Block,
uint256 l2Timestamp,
uint256 value,
bytes calldata data
) external;
/**
* @dev function used to simulate the result of a particular function call from the outbox
* it is useful for things such as gas estimates. This function includes all costs except for
* proof validation (which can be considered offchain as a somewhat of a fixed cost - it's
* not really a fixed cost, but can be treated as so with a fixed overhead for gas estimation).
* We can't include the cost of proof validation since this is intended to be used to simulate txs
* that are included in yet-to-be confirmed merkle roots. The simulation entrypoint could instead pretend
* to confirm a pending merkle root, but that would be less practical for integrating with tooling.
* It is only possible to trigger it when the msg sender is address zero, which should be impossible
* unless under simulation in an eth_call or eth_estimateGas
*/
function executeTransactionSimulation(
uint256 index,
address l2Sender,
address to,
uint256 l2Block,
uint256 l1Block,
uint256 l2Timestamp,
uint256 value,
bytes calldata data
) external;
/**
* @param index Merkle path to message
* @return true if the message has been spent
*/
function isSpent(uint256 index) external view returns (bool);
function calculateItemHash(
address l2Sender,
address to,
uint256 l2Block,
uint256 l1Block,
uint256 l2Timestamp,
uint256 value,
bytes calldata data
) external pure returns (bytes32);
function calculateMerkleRoot(
bytes32[] memory proof,
uint256 path,
bytes32 item
) external pure returns (bytes32);
/**
* @dev function to be called one time during the outbox upgrade process
* this is used to fix the storage slots
*/
function postUpgradeInit() 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.4.21 <0.9.0;
interface IOwnable {
function owner() external view returns (address);
}// Copyright 2021-2022, Offchain Labs, Inc.
// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE
// SPDX-License-Identifier: BUSL-1.1
// solhint-disable-next-line compiler-version
pragma solidity >=0.6.9 <0.9.0;
pragma experimental ABIEncoderV2;
import "../libraries/IGasRefunder.sol";
import "./IDelayedMessageProvider.sol";
import "./IBridge.sol";
interface ISequencerInbox is IDelayedMessageProvider {
struct MaxTimeVariation {
uint256 delayBlocks;
uint256 futureBlocks;
uint256 delaySeconds;
uint256 futureSeconds;
}
event SequencerBatchDelivered(
uint256 indexed batchSequenceNumber,
bytes32 indexed beforeAcc,
bytes32 indexed afterAcc,
bytes32 delayedAcc,
uint256 afterDelayedMessagesRead,
IBridge.TimeBounds timeBounds,
IBridge.BatchDataLocation dataLocation
);
event OwnerFunctionCalled(uint256 indexed id);
/// @dev a separate event that emits batch data when this isn't easily accessible in the tx.input
event SequencerBatchData(uint256 indexed batchSequenceNumber, bytes data);
/// @dev a valid keyset was added
event SetValidKeyset(bytes32 indexed keysetHash, bytes keysetBytes);
/// @dev a keyset was invalidated
event InvalidateKeyset(bytes32 indexed keysetHash);
function totalDelayedMessagesRead() external view returns (uint256);
function bridge() external view returns (IBridge);
/// @dev The size of the batch header
// solhint-disable-next-line func-name-mixedcase
function HEADER_LENGTH() external view returns (uint256);
/// @dev If the first batch data byte after the header has this bit set,
/// the sequencer inbox has authenticated the data. Currently only used for 4844 blob support.
/// See: https://github.com/OffchainLabs/nitro/blob/69de0603abf6f900a4128cab7933df60cad54ded/arbstate/das_reader.go
// solhint-disable-next-line func-name-mixedcase
function DATA_AUTHENTICATED_FLAG() external view returns (bytes1);
/// @dev If the first data byte after the header has this bit set,
/// then the batch data is to be found in 4844 data blobs
/// See: https://github.com/OffchainLabs/nitro/blob/69de0603abf6f900a4128cab7933df60cad54ded/arbstate/das_reader.go
// solhint-disable-next-line func-name-mixedcase
function DATA_BLOB_HEADER_FLAG() external view returns (bytes1);
/// @dev If the first data byte after the header has this bit set,
/// then the batch data is a das message
/// See: https://github.com/OffchainLabs/nitro/blob/69de0603abf6f900a4128cab7933df60cad54ded/arbstate/das_reader.go
// solhint-disable-next-line func-name-mixedcase
function DAS_MESSAGE_HEADER_FLAG() external view returns (bytes1);
/// @dev If the first data byte after the header has this bit set,
/// then the batch data is a das message that employs a merklesization strategy
/// See: https://github.com/OffchainLabs/nitro/blob/69de0603abf6f900a4128cab7933df60cad54ded/arbstate/das_reader.go
// solhint-disable-next-line func-name-mixedcase
function TREE_DAS_MESSAGE_HEADER_FLAG() external view returns (bytes1);
/// @dev If the first data byte after the header has this bit set,
/// then the batch data has been brotli compressed
/// See: https://github.com/OffchainLabs/nitro/blob/69de0603abf6f900a4128cab7933df60cad54ded/arbstate/das_reader.go
// solhint-disable-next-line func-name-mixedcase
function BROTLI_MESSAGE_HEADER_FLAG() external view returns (bytes1);
/// @dev If the first data byte after the header has this bit set,
/// then the batch data uses a zero heavy encoding
/// See: https://github.com/OffchainLabs/nitro/blob/69de0603abf6f900a4128cab7933df60cad54ded/arbstate/das_reader.go
// solhint-disable-next-line func-name-mixedcase
function ZERO_HEAVY_MESSAGE_HEADER_FLAG() external view returns (bytes1);
function rollup() external view returns (IOwnable);
function isBatchPoster(address) external view returns (bool);
function isSequencer(address) external view returns (bool);
function maxDataSize() external view returns (uint256);
/// @notice The batch poster manager has the ability to change the batch poster addresses
/// This enables the batch poster to do key rotation
function batchPosterManager() external view returns (address);
struct DasKeySetInfo {
bool isValidKeyset;
uint64 creationBlock;
}
/// @dev returns 4 uint256 to be compatible with older version
function maxTimeVariation()
external
view
returns (
uint256 delayBlocks,
uint256 futureBlocks,
uint256 delaySeconds,
uint256 futureSeconds
);
function dasKeySetInfo(bytes32) external view returns (bool, uint64);
/// @notice Remove force inclusion delay after a L1 chainId fork
function removeDelayAfterFork() external;
/// @notice Force messages from the delayed inbox to be included in the chain
/// Callable by any address, but message can only be force-included after maxTimeVariation.delayBlocks and
/// maxTimeVariation.delaySeconds has elapsed. As part of normal behaviour the sequencer will include these
/// messages so it's only necessary to call this if the sequencer is down, or not including any delayed messages.
/// @param _totalDelayedMessagesRead The total number of messages to read up to
/// @param kind The kind of the last message to be included
/// @param l1BlockAndTime The l1 block and the l1 timestamp of the last message to be included
/// @param baseFeeL1 The l1 gas price of the last message to be included
/// @param sender The sender of the last message to be included
/// @param messageDataHash The messageDataHash of the last message to be included
function forceInclusion(
uint256 _totalDelayedMessagesRead,
uint8 kind,
uint64[2] calldata l1BlockAndTime,
uint256 baseFeeL1,
address sender,
bytes32 messageDataHash
) external;
function inboxAccs(uint256 index) external view returns (bytes32);
function batchCount() external view returns (uint256);
function isValidKeysetHash(bytes32 ksHash) external view returns (bool);
/// @notice the creation block is intended to still be available after a keyset is deleted
function getKeysetCreationBlock(bytes32 ksHash) external view returns (uint256);
// ---------- BatchPoster functions ----------
function addSequencerL2BatchFromOrigin(
uint256 sequenceNumber,
bytes calldata data,
uint256 afterDelayedMessagesRead,
IGasRefunder gasRefunder
) external;
function addSequencerL2BatchFromOrigin(
uint256 sequenceNumber,
bytes calldata data,
uint256 afterDelayedMessagesRead,
IGasRefunder gasRefunder,
uint256 prevMessageCount,
uint256 newMessageCount
) external;
function addSequencerL2Batch(
uint256 sequenceNumber,
bytes calldata data,
uint256 afterDelayedMessagesRead,
IGasRefunder gasRefunder,
uint256 prevMessageCount,
uint256 newMessageCount
) external;
function addSequencerL2BatchFromBlobs(
uint256 sequenceNumber,
uint256 afterDelayedMessagesRead,
IGasRefunder gasRefunder,
uint256 prevMessageCount,
uint256 newMessageCount
) external;
// ---------- onlyRollupOrOwner functions ----------
/**
* @notice Set max delay for sequencer inbox
* @param maxTimeVariation_ the maximum time variation parameters
*/
function setMaxTimeVariation(MaxTimeVariation memory maxTimeVariation_) external;
/**
* @notice Updates whether an address is authorized to be a batch poster at the sequencer inbox
* @param addr the address
* @param isBatchPoster_ if the specified address should be authorized as a batch poster
*/
function setIsBatchPoster(address addr, bool isBatchPoster_) external;
/**
* @notice Makes Data Availability Service keyset valid
* @param keysetBytes bytes of the serialized keyset
*/
function setValidKeyset(bytes calldata keysetBytes) external;
/**
* @notice Invalidates a Data Availability Service keyset
* @param ksHash hash of the keyset
*/
function invalidateKeysetHash(bytes32 ksHash) external;
/**
* @notice Updates whether an address is authorized to be a sequencer.
* @dev The IsSequencer information is used only off-chain by the nitro node to validate sequencer feed signer.
* @param addr the address
* @param isSequencer_ if the specified address should be authorized as a sequencer
*/
function setIsSequencer(address addr, bool isSequencer_) external;
/**
* @notice Updates the batch poster manager, the address which has the ability to rotate batch poster keys
* @param newBatchPosterManager The new batch poster manager to be set
*/
function setBatchPosterManager(address newBatchPosterManager) external;
/// @notice Allows the rollup owner to sync the rollup address
function updateRollupAddress() external;
// ---------- initializer ----------
function initialize(IBridge bridge_, MaxTimeVariation calldata maxTimeVariation_) external;
}// Copyright 2021-2022, Offchain Labs, Inc.
// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
import "../state/Machine.sol";
import "../state/GlobalState.sol";
library ChallengeLib {
using MachineLib for Machine;
using ChallengeLib for Challenge;
/// @dev It's assumed that that uninitialzed challenges have mode NONE
enum ChallengeMode {
NONE,
BLOCK,
EXECUTION
}
struct Participant {
address addr;
uint256 timeLeft;
}
struct Challenge {
Participant current;
Participant next;
uint256 lastMoveTimestamp;
bytes32 wasmModuleRoot;
bytes32 challengeStateHash;
uint64 maxInboxMessages;
ChallengeMode mode;
}
struct SegmentSelection {
uint256 oldSegmentsStart;
uint256 oldSegmentsLength;
bytes32[] oldSegments;
uint256 challengePosition;
}
function timeUsedSinceLastMove(Challenge storage challenge) internal view returns (uint256) {
return block.timestamp - challenge.lastMoveTimestamp;
}
function isTimedOut(Challenge storage challenge) internal view returns (bool) {
return challenge.timeUsedSinceLastMove() > challenge.current.timeLeft;
}
function extractChallengeSegment(SegmentSelection calldata selection)
internal
pure
returns (uint256 segmentStart, uint256 segmentLength)
{
uint256 oldChallengeDegree = selection.oldSegments.length - 1;
segmentLength = selection.oldSegmentsLength / oldChallengeDegree;
// Intentionally done before challengeLength is potentially added to for the final segment
segmentStart = selection.oldSegmentsStart + segmentLength * selection.challengePosition;
if (selection.challengePosition == selection.oldSegments.length - 2) {
segmentLength += selection.oldSegmentsLength % oldChallengeDegree;
}
}
function hashChallengeState(
uint256 segmentsStart,
uint256 segmentsLength,
bytes32[] memory segments
) internal pure returns (bytes32) {
return keccak256(abi.encodePacked(segmentsStart, segmentsLength, segments));
}
function blockStateHash(MachineStatus status, bytes32 globalStateHash)
internal
pure
returns (bytes32)
{
if (status == MachineStatus.FINISHED) {
return keccak256(abi.encodePacked("Block state:", globalStateHash));
} else if (status == MachineStatus.ERRORED) {
return keccak256(abi.encodePacked("Block state, errored:", globalStateHash));
} else if (status == MachineStatus.TOO_FAR) {
return keccak256(abi.encodePacked("Block state, too far:"));
} else {
revert("BAD_BLOCK_STATUS");
}
}
}// 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 "../bridge/IBridge.sol";
import "../bridge/ISequencerInbox.sol";
import "../osp/IOneStepProofEntry.sol";
import "./IChallengeResultReceiver.sol";
import "./ChallengeLib.sol";
interface IChallengeManager {
enum ChallengeTerminationType {
TIMEOUT,
BLOCK_PROOF,
EXECUTION_PROOF,
CLEARED
}
event InitiatedChallenge(
uint64 indexed challengeIndex,
GlobalState startState,
GlobalState endState
);
event Bisected(
uint64 indexed challengeIndex,
bytes32 indexed challengeRoot,
uint256 challengedSegmentStart,
uint256 challengedSegmentLength,
bytes32[] chainHashes
);
event ExecutionChallengeBegun(uint64 indexed challengeIndex, uint256 blockSteps);
event OneStepProofCompleted(uint64 indexed challengeIndex);
event ChallengeEnded(uint64 indexed challengeIndex, ChallengeTerminationType kind);
function initialize(
IChallengeResultReceiver resultReceiver_,
ISequencerInbox sequencerInbox_,
IBridge bridge_,
IOneStepProofEntry osp_
) external;
function postUpgradeInit(
IOneStepProofEntry osp_,
bytes32 condRoot,
IOneStepProofEntry condOsp
) external;
/// @notice Get the default osp, which is used for all wasm module roots that don't have a conditional OSP set
/// Use getOsp(wasmModuleRoot) to get the OSP for a specific wasm module root
function osp() external view returns (IOneStepProofEntry);
/// @notice Get the OSP for a given wasm module root
function getOsp(bytes32 wasmModuleRoot) external view returns (IOneStepProofEntry);
function createChallenge(
bytes32 wasmModuleRoot_,
MachineStatus[2] calldata startAndEndMachineStatuses_,
GlobalState[2] calldata startAndEndGlobalStates_,
uint64 numBlocks,
address asserter_,
address challenger_,
uint256 asserterTimeLeft_,
uint256 challengerTimeLeft_
) external returns (uint64);
function challengeInfo(uint64 challengeIndex_)
external
view
returns (ChallengeLib.Challenge memory);
function currentResponder(uint64 challengeIndex) external view returns (address);
function isTimedOut(uint64 challengeIndex) external view returns (bool);
function clearChallenge(uint64 challengeIndex_) external;
function timeout(uint64 challengeIndex_) external;
}// Copyright 2021-2022, Offchain Labs, Inc.
// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
interface IChallengeResultReceiver {
function completeChallenge(
uint256 challengeIndex,
address winner,
address loser
) external;
}// Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.4; uint64 constant NO_CHAL_INDEX = 0; // Expected seconds per block in Ethereum PoS uint256 constant ETH_POS_BLOCK_TIME = 12; /// @dev If nativeTokenDecimals is different than 18 decimals, bridge will inflate or deflate token amounts /// when depositing to child chain to match 18 decimal denomination. Opposite process happens when /// amount is withdrawn back to parent chain. In order to avoid uint256 overflows we restrict max number /// of decimals to 36 which should be enough for most practical use-cases. uint8 constant MAX_ALLOWED_NATIVE_TOKEN_DECIMALS = uint8(36); /// @dev Max amount of erc20 native token that can deposit when upscaling is required (i.e. < 18 decimals) /// Amounts higher than this would risk uint256 overflows when adjusting decimals. Considering /// 18 decimals are 60 bits, we choose 2^192 as the limit which equals to ~6.3*10^57 weis of token uint256 constant MAX_UPSCALE_AMOUNT = type(uint192).max;
// 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 "./IOneStepProver.sol";
library OneStepProofEntryLib {
uint256 internal constant MAX_STEPS = 1 << 43;
}
interface IOneStepProofEntry {
function getStartMachineHash(bytes32 globalStateHash, bytes32 wasmModuleRoot)
external
pure
returns (bytes32);
function getEndMachineHash(MachineStatus status, bytes32 globalStateHash)
external
pure
returns (bytes32);
function proveOneStep(
ExecutionContext calldata execCtx,
uint256 machineStep,
bytes32 beforeHash,
bytes calldata proof
) external view returns (bytes32 afterHash);
}// 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 "./Node.sol";
import "../bridge/IBridge.sol";
import "../bridge/IOutbox.sol";
import "../bridge/IInboxBase.sol";
import "./IRollupEventInbox.sol";
import "../challenge/IChallengeManager.sol";
interface IRollupCore {
struct Staker {
uint256 amountStaked;
uint64 index;
uint64 latestStakedNode;
// currentChallenge is 0 if staker is not in a challenge
uint64 currentChallenge;
bool isStaked;
}
event RollupInitialized(bytes32 machineHash, uint256 chainId);
event NodeCreated(
uint64 indexed nodeNum,
bytes32 indexed parentNodeHash,
bytes32 indexed nodeHash,
bytes32 executionHash,
Assertion assertion,
bytes32 afterInboxBatchAcc,
bytes32 wasmModuleRoot,
uint256 inboxMaxCount
);
event NodeConfirmed(uint64 indexed nodeNum, bytes32 blockHash, bytes32 sendRoot);
event NodeRejected(uint64 indexed nodeNum);
event RollupChallengeStarted(
uint64 indexed challengeIndex,
address asserter,
address challenger,
uint64 challengedNode
);
event UserStakeUpdated(address indexed user, uint256 initialBalance, uint256 finalBalance);
event UserWithdrawableFundsUpdated(
address indexed user,
uint256 initialBalance,
uint256 finalBalance
);
function confirmPeriodBlocks() external view returns (uint64);
function extraChallengeTimeBlocks() external view returns (uint64);
function chainId() external view returns (uint256);
function baseStake() external view returns (uint256);
function wasmModuleRoot() external view returns (bytes32);
function bridge() external view returns (IBridge);
function sequencerInbox() external view returns (ISequencerInbox);
function outbox() external view returns (IOutbox);
function rollupEventInbox() external view returns (IRollupEventInbox);
function challengeManager() external view returns (IChallengeManager);
function loserStakeEscrow() external view returns (address);
function stakeToken() external view returns (address);
function minimumAssertionPeriod() external view returns (uint256);
function isValidator(address) external view returns (bool);
function validatorWhitelistDisabled() external view returns (bool);
/**
* @notice Get the Node for the given index.
*/
function getNode(uint64 nodeNum) external view returns (Node memory);
/**
* @notice Returns the block in which the given node was created for looking up its creation event.
* Unlike the Node's createdAtBlock field, this will be the ArbSys blockNumber if the host chain is an Arbitrum chain.
* That means that the block number returned for this is usable for event queries.
* This function will revert if the given node number does not exist.
* @dev This function is meant for internal use only and has no stability guarantees.
*/
function getNodeCreationBlockForLogLookup(uint64 nodeNum) external view returns (uint256);
/**
* @notice Check if the specified node has been staked on by the provided staker.
* Only accurate at the latest confirmed node and afterwards.
*/
function nodeHasStaker(uint64 nodeNum, address staker) external view returns (bool);
/**
* @notice Get the address of the staker at the given index
* @param stakerNum Index of the staker
* @return Address of the staker
*/
function getStakerAddress(uint64 stakerNum) external view returns (address);
/**
* @notice Check whether the given staker is staked
* @param staker Staker address to check
* @return True or False for whether the staker was staked
*/
function isStaked(address staker) external view returns (bool);
/**
* @notice Get the latest staked node of the given staker
* @param staker Staker address to lookup
* @return Latest node staked of the staker
*/
function latestStakedNode(address staker) external view returns (uint64);
/**
* @notice Get the current challenge of the given staker
* @param staker Staker address to lookup
* @return Current challenge of the staker
*/
function currentChallenge(address staker) external view returns (uint64);
/**
* @notice Get the amount staked of the given staker
* @param staker Staker address to lookup
* @return Amount staked of the staker
*/
function amountStaked(address staker) external view returns (uint256);
/**
* @notice Retrieves stored information about a requested staker
* @param staker Staker address to retrieve
* @return A structure with information about the requested staker
*/
function getStaker(address staker) external view returns (Staker memory);
/**
* @notice Get the original staker address of the zombie at the given index
* @param zombieNum Index of the zombie to lookup
* @return Original staker address of the zombie
*/
function zombieAddress(uint256 zombieNum) external view returns (address);
/**
* @notice Get Latest node that the given zombie at the given index is staked on
* @param zombieNum Index of the zombie to lookup
* @return Latest node that the given zombie is staked on
*/
function zombieLatestStakedNode(uint256 zombieNum) external view returns (uint64);
/// @return Current number of un-removed zombies
function zombieCount() external view returns (uint256);
function isZombie(address staker) external view returns (bool);
/**
* @notice Get the amount of funds withdrawable by the given address
* @param owner Address to check the funds of
* @return Amount of funds withdrawable by owner
*/
function withdrawableFunds(address owner) external view returns (uint256);
/**
* @return Index of the first unresolved node
* @dev If all nodes have been resolved, this will be latestNodeCreated + 1
*/
function firstUnresolvedNode() external view returns (uint64);
/// @return Index of the latest confirmed node
function latestConfirmed() external view returns (uint64);
/// @return Index of the latest rollup node created
function latestNodeCreated() external view returns (uint64);
/// @return Ethereum block that the most recent stake was created
function lastStakeBlock() external view returns (uint64);
/// @return Number of active stakers currently staked
function stakerCount() external view returns (uint64);
}// 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 "../bridge/IBridge.sol";
interface IRollupEventInbox {
function bridge() external view returns (IBridge);
function initialize(IBridge _bridge) external;
function rollup() external view returns (address);
function updateRollupAddress() external;
function rollupInitialized(uint256 chainId, string calldata chainConfig) external;
}// Copyright 2021-2022, Offchain Labs, Inc.
// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
import "./IRollupCore.sol";
import "../bridge/ISequencerInbox.sol";
import "../bridge/IOutbox.sol";
import "../bridge/IOwnable.sol";
interface IRollupUserAbs is IRollupCore, IOwnable {
/// @dev the user logic just validated configuration and shouldn't write to state during init
/// this allows the admin logic to ensure consistency on parameters.
function initialize(address stakeToken) external view;
function removeWhitelistAfterFork() external;
function removeWhitelistAfterValidatorAfk() external;
function isERC20Enabled() external view returns (bool);
function rejectNextNode(address stakerAddress) external;
function confirmNextNode(bytes32 blockHash, bytes32 sendRoot) external;
function fastConfirmNextNode(
bytes32 blockHash,
bytes32 sendRoot,
bytes32 nodeHash
) external;
function stakeOnExistingNode(uint64 nodeNum, bytes32 nodeHash) external;
function stakeOnNewNode(
Assertion memory assertion,
bytes32 expectedNodeHash,
uint256 prevNodeInboxMaxCount
) external;
function returnOldDeposit(address stakerAddress) external;
function reduceDeposit(uint256 target) external;
function removeZombie(uint256 zombieNum, uint256 maxNodes) external;
function removeOldZombies(uint256 startIndex) external;
function requiredStake(
uint256 blockNumber,
uint64 firstUnresolvedNodeNum,
uint64 latestCreatedNode
) external view returns (uint256);
function currentRequiredStake() external view returns (uint256);
function countStakedZombies(uint64 nodeNum) external view returns (uint256);
function countZombiesStakedOnChildren(uint64 nodeNum) external view returns (uint256);
function requireUnresolvedExists() external view;
function requireUnresolved(uint256 nodeNum) external view;
function withdrawStakerFunds() external returns (uint256);
function createChallenge(
address[2] calldata stakers,
uint64[2] calldata nodeNums,
MachineStatus[2] calldata machineStatuses,
GlobalState[2] calldata globalStates,
uint64 numBlocks,
bytes32 secondExecutionHash,
uint256[2] calldata proposedTimes,
bytes32[2] calldata wasmModuleRoots
) external;
}
interface IRollupUser is IRollupUserAbs {
function newStakeOnExistingNode(uint64 nodeNum, bytes32 nodeHash) external payable;
function newStakeOnNewNode(
Assertion calldata assertion,
bytes32 expectedNodeHash,
uint256 prevNodeInboxMaxCount
) external payable;
function addToDeposit(address stakerAddress) external payable;
}
interface IRollupUserERC20 is IRollupUserAbs {
function newStakeOnExistingNode(
uint256 tokenAmount,
uint64 nodeNum,
bytes32 nodeHash
) external;
function newStakeOnNewNode(
uint256 tokenAmount,
Assertion calldata assertion,
bytes32 expectedNodeHash,
uint256 prevNodeInboxMaxCount
) external;
function addToDeposit(address stakerAddress, uint256 tokenAmount) external;
}// Copyright 2021-2022, Offchain Labs, Inc.
// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
import "../state/GlobalState.sol";
import "../state/Machine.sol";
struct ExecutionState {
GlobalState globalState;
MachineStatus machineStatus;
}
struct Assertion {
ExecutionState beforeState;
ExecutionState afterState;
uint64 numBlocks;
}
struct Node {
// Hash of the state of the chain as of this node
bytes32 stateHash;
// Hash of the data that can be challenged
bytes32 challengeHash;
// Hash of the data that will be committed if this node is confirmed
bytes32 confirmData;
// Index of the node previous to this one
uint64 prevNum;
// Deadline at which this node can be confirmed
uint64 deadlineBlock;
// Deadline at which a child of this node can be confirmed
uint64 noChildConfirmedBeforeBlock;
// Number of stakers staked on this node. This includes real stakers and zombies
uint64 stakerCount;
// Number of stakers staked on a child node. This includes real stakers and zombies
uint64 childStakerCount;
// This value starts at zero and is set to a value when the first child is created. After that it is constant until the node is destroyed or the owner destroys pending nodes
uint64 firstChildBlock;
// The number of the latest child of this node to be created
uint64 latestChildNumber;
// The block number when this node was created
uint64 createdAtBlock;
// A hash of all the data needed to determine this node's validity, to protect against reorgs
bytes32 nodeHash;
}
/**
* @notice Utility functions for Node
*/
library NodeLib {
/**
* @notice Initialize a Node
* @param _stateHash Initial value of stateHash
* @param _challengeHash Initial value of challengeHash
* @param _confirmData Initial value of confirmData
* @param _prevNum Initial value of prevNum
* @param _deadlineBlock Initial value of deadlineBlock
* @param _nodeHash Initial value of nodeHash
*/
function createNode(
bytes32 _stateHash,
bytes32 _challengeHash,
bytes32 _confirmData,
uint64 _prevNum,
uint64 _deadlineBlock,
bytes32 _nodeHash
) internal view returns (Node memory) {
Node memory node;
node.stateHash = _stateHash;
node.challengeHash = _challengeHash;
node.confirmData = _confirmData;
node.prevNum = _prevNum;
node.deadlineBlock = _deadlineBlock;
node.noChildConfirmedBeforeBlock = _deadlineBlock;
node.createdAtBlock = uint64(block.number);
node.nodeHash = _nodeHash;
return node;
}
/**
* @notice Update child properties
* @param number The child number to set
*/
function childCreated(Node storage self, uint64 number) internal {
if (self.firstChildBlock == 0) {
self.firstChildBlock = uint64(block.number);
}
self.latestChildNumber = number;
}
/**
* @notice Update the child confirmed deadline
* @param deadline The new deadline to set
*/
function newChildConfirmDeadline(Node storage self, uint64 deadline) internal {
self.noChildConfirmedBeforeBlock = deadline;
}
/**
* @notice Check whether the current block number has met or passed the node's deadline
*/
function requirePastDeadline(Node memory self) internal view {
require(block.number >= self.deadlineBlock, "BEFORE_DEADLINE");
}
/**
* @notice Check whether the current block number has met or passed deadline for children of this node to be confirmed
*/
function requirePastChildConfirmDeadline(Node memory self) internal view {
require(block.number >= self.noChildConfirmedBeforeBlock, "CHILD_TOO_RECENT");
}
}// 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 "./ModuleMemoryCompact.sol";
struct Module {
bytes32 globalsMerkleRoot;
ModuleMemory moduleMemory;
bytes32 tablesMerkleRoot;
bytes32 functionsMerkleRoot;
bytes32 extraHash;
uint32 internalsOffset;
}
library ModuleLib {
using ModuleMemoryCompactLib for ModuleMemory;
function hash(Module memory mod) internal pure returns (bytes32) {
return
keccak256(
abi.encodePacked(
"Module:",
mod.globalsMerkleRoot,
mod.moduleMemory.hash(),
mod.tablesMerkleRoot,
mod.functionsMerkleRoot,
mod.extraHash,
mod.internalsOffset
)
);
}
}// Copyright 2021-2022, Offchain Labs, Inc.
// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
struct ModuleMemory {
uint64 size;
uint64 maxSize;
bytes32 merkleRoot;
}
library ModuleMemoryCompactLib {
function hash(ModuleMemory memory mem) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("Memory:", mem.size, mem.maxSize, mem.merkleRoot));
}
}// Copyright 2021-2024, Offchain Labs, Inc.
// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
struct MultiStack {
bytes32 inactiveStackHash; // NO_STACK_HASH if no stack, 0 if empty stack
bytes32 remainingHash; // 0 if less than 2 cothreads exist
}
library MultiStackLib {
bytes32 internal constant NO_STACK_HASH = ~bytes32(0);
function hash(
MultiStack memory multi,
bytes32 activeStackHash,
bool cothread
) internal pure returns (bytes32) {
require(activeStackHash != NO_STACK_HASH, "MULTISTACK_NOSTACK_ACTIVE");
if (cothread) {
require(multi.inactiveStackHash != NO_STACK_HASH, "MULTISTACK_NOSTACK_MAIN");
return
keccak256(
abi.encodePacked(
"multistack:",
multi.inactiveStackHash,
activeStackHash,
multi.remainingHash
)
);
} else {
return
keccak256(
abi.encodePacked(
"multistack:",
activeStackHash,
multi.inactiveStackHash,
multi.remainingHash
)
);
}
}
function setEmpty(MultiStack memory multi) internal pure {
multi.inactiveStackHash = NO_STACK_HASH;
multi.remainingHash = 0;
}
function pushNew(MultiStack memory multi) internal pure {
if (multi.inactiveStackHash != NO_STACK_HASH) {
multi.remainingHash = keccak256(
abi.encodePacked("cothread:", multi.inactiveStackHash, multi.remainingHash)
);
}
multi.inactiveStackHash = 0;
}
}// Copyright 2021-2023, Offchain Labs, Inc.
// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
import "./Value.sol";
struct StackFrame {
Value returnPc;
bytes32 localsMerkleRoot;
uint32 callerModule;
uint32 callerModuleInternals;
}
struct StackFrameWindow {
StackFrame[] proved;
bytes32 remainingHash;
}
library StackFrameLib {
using ValueLib for Value;
function hash(StackFrame memory frame) internal pure returns (bytes32) {
return
keccak256(
abi.encodePacked(
"Stack frame:",
frame.returnPc.hash(),
frame.localsMerkleRoot,
frame.callerModule,
frame.callerModuleInternals
)
);
}
function hash(StackFrameWindow memory window) internal pure returns (bytes32 h) {
h = window.remainingHash;
for (uint256 i = 0; i < window.proved.length; i++) {
h = keccak256(abi.encodePacked("Stack frame stack:", hash(window.proved[i]), h));
}
}
function peek(StackFrameWindow memory window) internal pure returns (StackFrame memory) {
require(window.proved.length == 1, "BAD_WINDOW_LENGTH");
return window.proved[0];
}
function pop(StackFrameWindow memory window) internal pure returns (StackFrame memory frame) {
require(window.proved.length == 1, "BAD_WINDOW_LENGTH");
frame = window.proved[0];
window.proved = new StackFrame[](0);
}
function push(StackFrameWindow memory window, StackFrame memory frame) internal pure {
StackFrame[] memory newProved = new StackFrame[](window.proved.length + 1);
for (uint256 i = 0; i < window.proved.length; i++) {
newProved[i] = window.proved[i];
}
newProved[window.proved.length] = frame;
window.proved = newProved;
}
function overwrite(StackFrameWindow memory window, bytes32 root) internal pure {
window.remainingHash = root;
delete window.proved;
}
}// Copyright 2021-2023, Offchain Labs, Inc.
// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
enum ValueType {
I32,
I64,
F32,
F64,
REF_NULL,
FUNC_REF,
INTERNAL_REF
}
struct Value {
ValueType valueType;
uint256 contents;
}
library ValueLib {
function hash(Value memory val) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("Value:", val.valueType, val.contents));
}
function maxValueType() internal pure returns (ValueType) {
return ValueType.INTERNAL_REF;
}
function assumeI32(Value memory val) internal pure returns (uint32) {
uint256 uintval = uint256(val.contents);
require(val.valueType == ValueType.I32, "NOT_I32");
require(uintval < (1 << 32), "BAD_I32");
return uint32(uintval);
}
function assumeI64(Value memory val) internal pure returns (uint64) {
uint256 uintval = uint256(val.contents);
require(val.valueType == ValueType.I64, "NOT_I64");
require(uintval < (1 << 64), "BAD_I64");
return uint64(uintval);
}
function newRefNull() internal pure returns (Value memory) {
return Value({valueType: ValueType.REF_NULL, contents: 0});
}
function newI32(uint32 x) internal pure returns (Value memory) {
return Value({valueType: ValueType.I32, contents: uint256(x)});
}
function newI64(uint64 x) internal pure returns (Value memory) {
return Value({valueType: ValueType.I64, contents: uint256(x)});
}
function newBoolean(bool x) internal pure returns (Value memory) {
if (x) {
return newI32(uint32(1));
} else {
return newI32(uint32(0));
}
}
function newPc(
uint32 funcPc,
uint32 func,
uint32 module
) internal pure returns (Value memory) {
uint256 data = 0;
data |= funcPc;
data |= uint256(func) << 32;
data |= uint256(module) << 64;
return Value({valueType: ValueType.INTERNAL_REF, contents: data});
}
}// Copyright 2021-2022, Offchain Labs, Inc.
// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
import "./Value.sol";
struct ValueArray {
Value[] inner;
}
library ValueArrayLib {
function get(ValueArray memory arr, uint256 index) internal pure returns (Value memory) {
return arr.inner[index];
}
function set(
ValueArray memory arr,
uint256 index,
Value memory val
) internal pure {
arr.inner[index] = val;
}
function length(ValueArray memory arr) internal pure returns (uint256) {
return arr.inner.length;
}
function push(ValueArray memory arr, Value memory val) internal pure {
Value[] memory newInner = new Value[](arr.inner.length + 1);
for (uint256 i = 0; i < arr.inner.length; i++) {
newInner[i] = arr.inner[i];
}
newInner[arr.inner.length] = val;
arr.inner = newInner;
}
function pop(ValueArray memory arr) internal pure returns (Value memory popped) {
popped = arr.inner[arr.inner.length - 1];
Value[] memory newInner = new Value[](arr.inner.length - 1);
for (uint256 i = 0; i < newInner.length; i++) {
newInner[i] = arr.inner[i];
}
arr.inner = newInner;
}
}// Copyright 2021-2023, Offchain Labs, Inc.
// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
import "./Value.sol";
import "./ValueArray.sol";
struct ValueStack {
ValueArray proved;
bytes32 remainingHash;
}
library ValueStackLib {
using ValueLib for Value;
using ValueArrayLib for ValueArray;
function hash(ValueStack memory stack) internal pure returns (bytes32 h) {
h = stack.remainingHash;
uint256 len = stack.proved.length();
for (uint256 i = 0; i < len; i++) {
h = keccak256(abi.encodePacked("Value stack:", stack.proved.get(i).hash(), h));
}
}
function peek(ValueStack memory stack) internal pure returns (Value memory) {
uint256 len = stack.proved.length();
return stack.proved.get(len - 1);
}
function pop(ValueStack memory stack) internal pure returns (Value memory) {
return stack.proved.pop();
}
function push(ValueStack memory stack, Value memory val) internal pure {
return stack.proved.push(val);
}
function overwrite(ValueStack memory stack, bytes32 root) internal pure {
stack.remainingHash = root;
delete stack.proved;
}
}{
"optimizer": {
"enabled": true,
"runs": 100
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"metadata": {
"useLiteralContent": true
},
"libraries": {}
}Contract ABI
API[{"inputs":[{"internalType":"contract IRollupCore","name":"rollup","type":"address"}],"name":"areUnresolvedNodesLinear","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IRollupUserAbs","name":"rollup","type":"address"}],"name":"checkDecidableNextNode","outputs":[{"internalType":"enum ValidatorUtils.ConfirmType","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IRollupCore","name":"rollup","type":"address"},{"internalType":"uint64","name":"node1","type":"uint64"},{"internalType":"uint64","name":"node2","type":"uint64"},{"internalType":"uint256","name":"maxDepth","type":"uint256"}],"name":"findNodeConflict","outputs":[{"components":[{"internalType":"enum ValidatorUtils.NodeConflictType","name":"ty","type":"uint8"},{"internalType":"uint64","name":"node1","type":"uint64"},{"internalType":"uint64","name":"node2","type":"uint64"}],"internalType":"struct ValidatorUtils.NodeConflict","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IRollupCore","name":"rollup","type":"address"},{"internalType":"address","name":"staker1","type":"address"},{"internalType":"address","name":"staker2","type":"address"},{"internalType":"uint256","name":"maxDepth","type":"uint256"}],"name":"findStakerConflict","outputs":[{"components":[{"internalType":"enum ValidatorUtils.NodeConflictType","name":"ty","type":"uint8"},{"internalType":"uint64","name":"node1","type":"uint64"},{"internalType":"uint64","name":"node2","type":"uint64"}],"internalType":"struct ValidatorUtils.NodeConflict","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IRollupCore","name":"rollup","type":"address"},{"internalType":"uint64","name":"startIndex","type":"uint64"},{"internalType":"uint64","name":"max","type":"uint64"}],"name":"getStakers","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"bool","name":"hasMore","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IRollupCore","name":"rollup","type":"address"},{"internalType":"address","name":"staker","type":"address"}],"name":"latestStaked","outputs":[{"internalType":"uint64","name":"","type":"uint64"},{"components":[{"internalType":"bytes32","name":"stateHash","type":"bytes32"},{"internalType":"bytes32","name":"challengeHash","type":"bytes32"},{"internalType":"bytes32","name":"confirmData","type":"bytes32"},{"internalType":"uint64","name":"prevNum","type":"uint64"},{"internalType":"uint64","name":"deadlineBlock","type":"uint64"},{"internalType":"uint64","name":"noChildConfirmedBeforeBlock","type":"uint64"},{"internalType":"uint64","name":"stakerCount","type":"uint64"},{"internalType":"uint64","name":"childStakerCount","type":"uint64"},{"internalType":"uint64","name":"firstChildBlock","type":"uint64"},{"internalType":"uint64","name":"latestChildNumber","type":"uint64"},{"internalType":"uint64","name":"createdAtBlock","type":"uint64"},{"internalType":"bytes32","name":"nodeHash","type":"bytes32"}],"internalType":"struct Node","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IRollupCore","name":"rollup","type":"address"}],"name":"refundableStakers","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IRollupUserAbs","name":"rollup","type":"address"}],"name":"requireConfirmable","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IRollupCore","name":"rollup","type":"address"}],"name":"requireRejectable","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IRollupCore","name":"rollup","type":"address"},{"internalType":"address","name":"staker","type":"address"}],"name":"stakedNodes","outputs":[{"internalType":"uint64[]","name":"","type":"uint64[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IRollupCore","name":"rollup","type":"address"},{"internalType":"uint64","name":"startIndex","type":"uint64"},{"internalType":"uint64","name":"max","type":"uint64"}],"name":"timedOutChallenges","outputs":[{"internalType":"uint64[]","name":"","type":"uint64[]"},{"internalType":"bool","name":"hasMore","type":"bool"}],"stateMutability":"view","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b506125bf806100206000396000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c80637464ae06116100715780637464ae06146101415780637988ad371461016157806382f50e2d14610181578063aea2f06e14610194578063c308eaaf146101b7578063f36e18cc146101d757600080fd5b806301d9717d146100ae5780630a46c1b5146100d85780631fc43bb6146100f85780633400b5fa1461010d578063712293401461012e575b600080fd5b6100c16100bc366004611efd565b6101f8565b6040516100cf929190611f36565b60405180910390f35b6100eb6100e6366004612043565b6103ec565b6040516100cf919061207d565b61010b610106366004612043565b6104b1565b005b61012061011b3660046120ac565b610973565b6040516100cf92919061213b565b61010b61013c366004612043565b610c83565b61015461014f366004612043565b610fe9565b6040516100cf9190612198565b61017461016f3660046121ab565b611340565b6040516100cf91906121fc565b61017461018f366004612240565b611477565b6101a76101a2366004612043565b611884565b60405190151581526020016100cf565b6101ca6101c5366004611efd565b611a6a565b6040516100cf9190612281565b6101ea6101e53660046120ac565b611c79565b6040516100cf929190612294565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081018290526101608101829052604051631f4b2bb760e11b81526000906001600160a01b03861690633e96576e906102879087906004016122a7565b60206040518083038186803b15801561029f57600080fd5b505afa1580156102b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102d791906122c6565b90506001600160401b03811661035b57846001600160a01b03166365f7f80d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561032057600080fd5b505afa158015610334573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061035891906122c6565b90505b6040516324b204d360e21b81526001600160401b03821660048201526000906001600160a01b038716906392c8134c906024016101806040518083038186803b1580156103a757600080fd5b505afa1580156103bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103df9190612330565b9196919550909350505050565b604051630fe21ddb60e11b81526000903090631fc43bb6906104129085906004016122a7565b60006040518083038186803b15801561042a57600080fd5b505afa92505050801561043b575060015b6104445761044c565b506001919050565b6040516301c48a4d60e61b8152309063712293409061046f9085906004016122a7565b60006040518083038186803b15801561048757600080fd5b505afa925050508015610498575060015b6104a457506000919050565b506002919050565b919050565b806001600160a01b03166367425daf6040518163ffffffff1660e01b815260040160006040518083038186803b1580156104ea57600080fd5b505afa1580156104fe573d6000803e3d6000fd5b505050506000816001600160a01b031663dff697876040518163ffffffff1660e01b815260040160206040518083038186803b15801561053d57600080fd5b505afa158015610551573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061057591906122c6565b6001600160401b03169050600081116105c25760405162461bcd60e51b815260206004820152600a6024820152694e4f5f5354414b45525360b01b60448201526064015b60405180910390fd5b6000826001600160a01b031663d735e21d6040518163ffffffff1660e01b815260040160206040518083038186803b1580156105fd57600080fd5b505afa158015610611573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061063591906122c6565b6040516324b204d360e21b81526001600160401b03821660048201529091506000906001600160a01b038516906392c8134c906024016101806040518083038186803b15801561068457600080fd5b505afa158015610698573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106bc9190612330565b90506106c781611e68565b836001600160a01b03166365f7f80d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561070057600080fd5b505afa158015610714573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073891906122c6565b6001600160401b031681606001516001600160401b03161461075c5761075c612402565b60608101516040516324b204d360e21b81526001600160401b0390911660048201526000906001600160a01b038616906392c8134c906024016101806040518083038186803b1580156107ae57600080fd5b505afa1580156107c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e69190612330565b90506107f181611e98565b6040516317185fa560e21b81526001600160401b03841660048201526000906001600160a01b03871690635c617e949060240160206040518083038186803b15801561083c57600080fd5b505afa158015610850573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108749190612418565b6060840151604051633684685160e11b81526001600160401b0390911660048201526001600160a01b03881690636d08d0a29060240160206040518083038186803b1580156108c257600080fd5b505afa1580156108d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108fa9190612418565b6109049190612447565b9050808360c001516001600160401b031661091f919061245e565b8260e001516001600160401b03161461096b5760405162461bcd60e51b815260206004820152600e60248201526d1393d517d0531317d4d51052d15160921b60448201526064016105b9565b505050505050565b60606000806000610985878787611c79565b91509150600082516001600160401b038111156109a4576109a46122e3565b6040519080825280602002602001820160405280156109cd578160200160208202803683370190505b509050600080896001600160a01b031663023a96fe6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a0c57600080fd5b505afa158015610a20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a449190612476565b905060005b8551811015610c73576000868281518110610a6657610a66612493565b6020026020010151905060008c6001600160a01b03166369fd251c836040518263ffffffff1660e01b8152600401610a9e91906122a7565b60206040518083038186803b158015610ab657600080fd5b505afa158015610aca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aee91906122c6565b90506001600160401b03811615801590610b835750604051639ede42b960e01b81526001600160401b03821660048201526001600160a01b03851690639ede42b99060240160206040518083038186803b158015610b4b57600080fd5b505afa158015610b5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8391906124a9565b8015610c1a57506040516323a9ef2360e01b81526001600160401b03821660048201526001600160a01b0380841691908616906323a9ef239060240160206040518083038186803b158015610bd757600080fd5b505afa158015610beb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0f9190612476565b6001600160a01b0316145b15610c5e57808686610c2b816124cb565b975081518110610c3d57610c3d612493565b60200260200101906001600160401b031690816001600160401b0316815250505b50508080610c6b906124cb565b915050610a49565b5050815297909650945050505050565b806001600160a01b03166367425daf6040518163ffffffff1660e01b815260040160006040518083038186803b158015610cbc57600080fd5b505afa158015610cd0573d6000803e3d6000fd5b505050506000816001600160a01b031663d735e21d6040518163ffffffff1660e01b815260040160206040518083038186803b158015610d0f57600080fd5b505afa158015610d23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4791906122c6565b6040516324b204d360e21b81526001600160401b03821660048201529091506000906001600160a01b038416906392c8134c906024016101806040518083038186803b158015610d9657600080fd5b505afa158015610daa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dce9190612330565b9050826001600160a01b03166365f7f80d6040518163ffffffff1660e01b815260040160206040518083038186803b158015610e0957600080fd5b505afa158015610e1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e4191906122c6565b6001600160401b031681606001516001600160401b03161415610fe45780608001516001600160401b0316431015610e8b5760405162461bcd60e51b81526004016105b9906124e6565b60608101516040516324b204d360e21b81526001600160401b039091166004820152610f1b906001600160a01b038516906392c8134c906024016101806040518083038186803b158015610ede57600080fd5b505afa158015610ef2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f169190612330565b611e98565b6040516317185fa560e21b81526001600160401b03831660048201526001600160a01b03841690635c617e949060240160206040518083038186803b158015610f6357600080fd5b505afa158015610f77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f9b9190612418565b8160c001516001600160401b031614610fe45760405162461bcd60e51b815260206004820152600b60248201526a4841535f5354414b45525360a81b60448201526064016105b9565b505050565b60606000826001600160a01b031663dff697876040518163ffffffff1660e01b815260040160206040518083038186803b15801561102657600080fd5b505afa15801561103a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061105e91906122c6565b6001600160401b031690506000816001600160401b03811115611083576110836122e3565b6040519080825280602002602001820160405280156110ac578160200160208202803683370190505b5090506000846001600160a01b03166365f7f80d6040518163ffffffff1660e01b815260040160206040518083038186803b1580156110ea57600080fd5b505afa1580156110fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112291906122c6565b6001600160401b031690506000805b84816001600160401b0316101561133557604051631b774dd160e21b81526001600160401b03821660048201526000906001600160a01b03891690636ddd37449060240160206040518083038186803b15801561118d57600080fd5b505afa1580156111a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111c59190612476565b90506000886001600160a01b0316633e96576e836040518263ffffffff1660e01b81526004016111f591906122a7565b60206040518083038186803b15801561120d57600080fd5b505afa158015611221573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061124591906122c6565b6001600160401b031690508481111580156112e25750604051631a7f494760e21b81526001600160a01b038a16906369fd251c906112879085906004016122a7565b60206040518083038186803b15801561129f57600080fd5b505afa1580156112b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112d791906122c6565b6001600160401b0316155b1561132057818685815181106112fa576112fa612493565b6001600160a01b03909216602092830291909101909101528361131c816124cb565b9450505b5050808061132d9061250f565b915050611131565b508252509392505050565b6040805160608101825260008082526020820181905291810191909152604051631f4b2bb760e11b81526000906001600160a01b03871690633e96576e9061138c9088906004016122a7565b60206040518083038186803b1580156113a457600080fd5b505afa1580156113b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113dc91906122c6565b90506000866001600160a01b0316633e96576e866040518263ffffffff1660e01b815260040161140c91906122a7565b60206040518083038186803b15801561142457600080fd5b505afa158015611438573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061145c91906122c6565b905061146a87838387611477565b925050505b949350505050565b60408051606081018252600080825260208201819052918101919091526000856001600160a01b031663d735e21d6040518163ffffffff1660e01b815260040160206040518083038186803b1580156114cf57600080fd5b505afa1580156114e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061150791906122c6565b6040516324b204d360e21b81526001600160401b03871660048201529091506000906001600160a01b038816906392c8134c906024016101806040518083038186803b15801561155657600080fd5b505afa15801561156a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061158e9190612330565b606001516040516324b204d360e21b81526001600160401b03871660048201529091506000906001600160a01b038916906392c8134c906024016101806040518083038186803b1580156115e157600080fd5b505afa1580156115f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116199190612330565b60600151905060005b8581101561185857866001600160401b0316886001600160401b0316141561167f5760408051606081019091528060005b8152602001896001600160401b03168152602001886001600160401b031681525094505050505061146f565b816001600160401b0316836001600160401b031614156116ac576040805160608101909152806001611653565b836001600160401b0316836001600160401b03161080156116de5750836001600160401b0316826001600160401b0316105b1561170e5760408051606081019091528060028152600060208201819052604090910152945061146f9350505050565b816001600160401b0316836001600160401b031610156117b9576040516324b204d360e21b81526001600160401b038316600482015291965086916001600160a01b038a16906392c8134c906024016101806040518083038186803b15801561177657600080fd5b505afa15801561178a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117ae9190612330565b606001519150611846565b6040516324b204d360e21b81526001600160401b038416600482015292975087926001600160a01b038a16906392c8134c906024016101806040518083038186803b15801561180757600080fd5b505afa15801561181b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061183f9190612330565b6060015192505b80611850816124cb565b915050611622565b506040805160608101909152806003815260006020820181905260409091015298975050505050505050565b600080826001600160a01b0316637ba9534a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156118c057600080fd5b505afa1580156118d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118f891906122c6565b6001600160401b031690506000836001600160a01b031663d735e21d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561193e57600080fd5b505afa158015611952573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061197691906122c6565b90505b81816001600160401b031611611a60576000816001600160401b0316118015611a3f57506119a8600182612536565b6040516324b204d360e21b81526001600160401b03838116600483015291909116906001600160a01b038616906392c8134c906024016101806040518083038186803b1580156119f757600080fd5b505afa158015611a0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a2f9190612330565b606001516001600160401b031614155b15611a4e575060009392505050565b80611a588161250f565b915050611979565b5060019392505050565b60408051620186a08082526230d420820190925260609160009190602082016230d40080368337019050509050600080856001600160a01b03166365f7f80d6040518163ffffffff1660e01b815260040160206040518083038186803b158015611ad357600080fd5b505afa158015611ae7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b0b91906122c6565b90505b856001600160a01b0316637ba9534a6040518163ffffffff1660e01b815260040160206040518083038186803b158015611b4757600080fd5b505afa158015611b5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b7f91906122c6565b6001600160401b0316816001600160401b031611611c6f5760405163154cb5e960e31b81526001600160401b03821660048201526001600160a01b03868116602483015287169063aa65af489060440160206040518083038186803b158015611be757600080fd5b505afa158015611bfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c1f91906124a9565b15611c5d5780838381518110611c3757611c37612493565b6001600160401b039092166020928302919091019091015281611c59816124cb565b9250505b80611c678161250f565b915050611b0e565b5081529392505050565b6060600080856001600160a01b031663dff697876040518163ffffffff1660e01b815260040160206040518083038186803b158015611cb757600080fd5b505afa158015611ccb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cef91906122c6565b6001600160401b0316905080611d05858761255e565b6001600160401b031611611d2d57611d1d848661255e565b6001600160401b03169050600191505b6000816001600160401b03811115611d4757611d476122e3565b604051908082528060200260200182016040528015611d70578160200160208202803683370190505b50905060005b82816001600160401b03161015611e5c576001600160a01b038816636ddd3744611da0838a61255e565b6040516001600160e01b031960e084901b1681526001600160401b03909116600482015260240160206040518083038186803b158015611ddf57600080fd5b505afa158015611df3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e179190612476565b82826001600160401b031681518110611e3257611e32612493565b6001600160a01b039092166020928302919091019091015280611e548161250f565b915050611d76565b50925050935093915050565b80608001516001600160401b0316431015611e955760405162461bcd60e51b81526004016105b9906124e6565b50565b8060a001516001600160401b0316431015611e955760405162461bcd60e51b815260206004820152601060248201526f10d212531117d513d3d7d49150d1539560821b60448201526064016105b9565b6001600160a01b0381168114611e9557600080fd5b60008060408385031215611f1057600080fd5b8235611f1b81611ee8565b91506020830135611f2b81611ee8565b809150509250929050565b60006101a0820190506001600160401b03841682528251602083015260208301516040830152604083015160608301526060830151611f8060808401826001600160401b03169052565b5060808301516001600160401b03811660a08401525060a08301516001600160401b03811660c08401525060c08301516001600160401b03811660e08401525060e0830151610100611fdc818501836001600160401b03169052565b8401519050610120611ff8848201836001600160401b03169052565b8401519050610140612014848201836001600160401b03169052565b8401519050610160612030848201836001600160401b03169052565b8085015161018085015250509392505050565b60006020828403121561205557600080fd5b813561206081611ee8565b9392505050565b634e487b7160e01b600052602160045260246000fd5b602081016003831061209157612091612067565b91905290565b6001600160401b0381168114611e9557600080fd5b6000806000606084860312156120c157600080fd5b83356120cc81611ee8565b925060208401356120dc81612097565b915060408401356120ec81612097565b809150509250925092565b600081518084526020808501945080840160005b838110156121305781516001600160401b03168752958201959082019060010161210b565b509495945050505050565b60408152600061214e60408301856120f7565b905082151560208301529392505050565b600081518084526020808501945080840160005b838110156121305781516001600160a01b031687529582019590820190600101612173565b602081526000612060602083018461215f565b600080600080608085870312156121c157600080fd5b84356121cc81611ee8565b935060208501356121dc81611ee8565b925060408501356121ec81611ee8565b9396929550929360600135925050565b815160608201906004811061221357612213612067565b8083525060208301516001600160401b038082166020850152806040860151166040850152505092915050565b6000806000806080858703121561225657600080fd5b843561226181611ee8565b9350602085013561227181612097565b925060408501356121ec81612097565b60208152600061206060208301846120f7565b60408152600061214e604083018561215f565b6001600160a01b0391909116815260200190565b80516104ac81612097565b6000602082840312156122d857600080fd5b815161206081612097565b634e487b7160e01b600052604160045260246000fd5b60405161018081016001600160401b038111828210171561232a57634e487b7160e01b600052604160045260246000fd5b60405290565b6000610180828403121561234357600080fd5b61234b6122f9565b82518152602083015160208201526040830151604082015261236f606084016122bb565b6060820152612380608084016122bb565b608082015261239160a084016122bb565b60a08201526123a260c084016122bb565b60c08201526123b360e084016122bb565b60e08201526101006123c68185016122bb565b908201526101206123d88482016122bb565b908201526101406123ea8482016122bb565b90820152610160928301519281019290925250919050565b634e487b7160e01b600052600160045260246000fd5b60006020828403121561242a57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b60008282101561245957612459612431565b500390565b6000821982111561247157612471612431565b500190565b60006020828403121561248857600080fd5b815161206081611ee8565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156124bb57600080fd5b8151801515811461206057600080fd5b60006000198214156124df576124df612431565b5060010190565b6020808252600f908201526e4245464f52455f444541444c494e4560881b604082015260600190565b60006001600160401b038083168181141561252c5761252c612431565b6001019392505050565b60006001600160401b038381169083168181101561255657612556612431565b039392505050565b60006001600160401b0380831681851680830382111561258057612580612431565b0194935050505056fea2646970667358221220e58a92a131adb3250802a5b67ca0fae6d59b8f8397c036ccaf63b400d8fa97dd64736f6c63430008090033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100a95760003560e01c80637464ae06116100715780637464ae06146101415780637988ad371461016157806382f50e2d14610181578063aea2f06e14610194578063c308eaaf146101b7578063f36e18cc146101d757600080fd5b806301d9717d146100ae5780630a46c1b5146100d85780631fc43bb6146100f85780633400b5fa1461010d578063712293401461012e575b600080fd5b6100c16100bc366004611efd565b6101f8565b6040516100cf929190611f36565b60405180910390f35b6100eb6100e6366004612043565b6103ec565b6040516100cf919061207d565b61010b610106366004612043565b6104b1565b005b61012061011b3660046120ac565b610973565b6040516100cf92919061213b565b61010b61013c366004612043565b610c83565b61015461014f366004612043565b610fe9565b6040516100cf9190612198565b61017461016f3660046121ab565b611340565b6040516100cf91906121fc565b61017461018f366004612240565b611477565b6101a76101a2366004612043565b611884565b60405190151581526020016100cf565b6101ca6101c5366004611efd565b611a6a565b6040516100cf9190612281565b6101ea6101e53660046120ac565b611c79565b6040516100cf929190612294565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081018290526101608101829052604051631f4b2bb760e11b81526000906001600160a01b03861690633e96576e906102879087906004016122a7565b60206040518083038186803b15801561029f57600080fd5b505afa1580156102b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102d791906122c6565b90506001600160401b03811661035b57846001600160a01b03166365f7f80d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561032057600080fd5b505afa158015610334573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061035891906122c6565b90505b6040516324b204d360e21b81526001600160401b03821660048201526000906001600160a01b038716906392c8134c906024016101806040518083038186803b1580156103a757600080fd5b505afa1580156103bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103df9190612330565b9196919550909350505050565b604051630fe21ddb60e11b81526000903090631fc43bb6906104129085906004016122a7565b60006040518083038186803b15801561042a57600080fd5b505afa92505050801561043b575060015b6104445761044c565b506001919050565b6040516301c48a4d60e61b8152309063712293409061046f9085906004016122a7565b60006040518083038186803b15801561048757600080fd5b505afa925050508015610498575060015b6104a457506000919050565b506002919050565b919050565b806001600160a01b03166367425daf6040518163ffffffff1660e01b815260040160006040518083038186803b1580156104ea57600080fd5b505afa1580156104fe573d6000803e3d6000fd5b505050506000816001600160a01b031663dff697876040518163ffffffff1660e01b815260040160206040518083038186803b15801561053d57600080fd5b505afa158015610551573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061057591906122c6565b6001600160401b03169050600081116105c25760405162461bcd60e51b815260206004820152600a6024820152694e4f5f5354414b45525360b01b60448201526064015b60405180910390fd5b6000826001600160a01b031663d735e21d6040518163ffffffff1660e01b815260040160206040518083038186803b1580156105fd57600080fd5b505afa158015610611573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061063591906122c6565b6040516324b204d360e21b81526001600160401b03821660048201529091506000906001600160a01b038516906392c8134c906024016101806040518083038186803b15801561068457600080fd5b505afa158015610698573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106bc9190612330565b90506106c781611e68565b836001600160a01b03166365f7f80d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561070057600080fd5b505afa158015610714573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073891906122c6565b6001600160401b031681606001516001600160401b03161461075c5761075c612402565b60608101516040516324b204d360e21b81526001600160401b0390911660048201526000906001600160a01b038616906392c8134c906024016101806040518083038186803b1580156107ae57600080fd5b505afa1580156107c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e69190612330565b90506107f181611e98565b6040516317185fa560e21b81526001600160401b03841660048201526000906001600160a01b03871690635c617e949060240160206040518083038186803b15801561083c57600080fd5b505afa158015610850573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108749190612418565b6060840151604051633684685160e11b81526001600160401b0390911660048201526001600160a01b03881690636d08d0a29060240160206040518083038186803b1580156108c257600080fd5b505afa1580156108d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108fa9190612418565b6109049190612447565b9050808360c001516001600160401b031661091f919061245e565b8260e001516001600160401b03161461096b5760405162461bcd60e51b815260206004820152600e60248201526d1393d517d0531317d4d51052d15160921b60448201526064016105b9565b505050505050565b60606000806000610985878787611c79565b91509150600082516001600160401b038111156109a4576109a46122e3565b6040519080825280602002602001820160405280156109cd578160200160208202803683370190505b509050600080896001600160a01b031663023a96fe6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a0c57600080fd5b505afa158015610a20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a449190612476565b905060005b8551811015610c73576000868281518110610a6657610a66612493565b6020026020010151905060008c6001600160a01b03166369fd251c836040518263ffffffff1660e01b8152600401610a9e91906122a7565b60206040518083038186803b158015610ab657600080fd5b505afa158015610aca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aee91906122c6565b90506001600160401b03811615801590610b835750604051639ede42b960e01b81526001600160401b03821660048201526001600160a01b03851690639ede42b99060240160206040518083038186803b158015610b4b57600080fd5b505afa158015610b5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8391906124a9565b8015610c1a57506040516323a9ef2360e01b81526001600160401b03821660048201526001600160a01b0380841691908616906323a9ef239060240160206040518083038186803b158015610bd757600080fd5b505afa158015610beb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0f9190612476565b6001600160a01b0316145b15610c5e57808686610c2b816124cb565b975081518110610c3d57610c3d612493565b60200260200101906001600160401b031690816001600160401b0316815250505b50508080610c6b906124cb565b915050610a49565b5050815297909650945050505050565b806001600160a01b03166367425daf6040518163ffffffff1660e01b815260040160006040518083038186803b158015610cbc57600080fd5b505afa158015610cd0573d6000803e3d6000fd5b505050506000816001600160a01b031663d735e21d6040518163ffffffff1660e01b815260040160206040518083038186803b158015610d0f57600080fd5b505afa158015610d23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4791906122c6565b6040516324b204d360e21b81526001600160401b03821660048201529091506000906001600160a01b038416906392c8134c906024016101806040518083038186803b158015610d9657600080fd5b505afa158015610daa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dce9190612330565b9050826001600160a01b03166365f7f80d6040518163ffffffff1660e01b815260040160206040518083038186803b158015610e0957600080fd5b505afa158015610e1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e4191906122c6565b6001600160401b031681606001516001600160401b03161415610fe45780608001516001600160401b0316431015610e8b5760405162461bcd60e51b81526004016105b9906124e6565b60608101516040516324b204d360e21b81526001600160401b039091166004820152610f1b906001600160a01b038516906392c8134c906024016101806040518083038186803b158015610ede57600080fd5b505afa158015610ef2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f169190612330565b611e98565b6040516317185fa560e21b81526001600160401b03831660048201526001600160a01b03841690635c617e949060240160206040518083038186803b158015610f6357600080fd5b505afa158015610f77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f9b9190612418565b8160c001516001600160401b031614610fe45760405162461bcd60e51b815260206004820152600b60248201526a4841535f5354414b45525360a81b60448201526064016105b9565b505050565b60606000826001600160a01b031663dff697876040518163ffffffff1660e01b815260040160206040518083038186803b15801561102657600080fd5b505afa15801561103a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061105e91906122c6565b6001600160401b031690506000816001600160401b03811115611083576110836122e3565b6040519080825280602002602001820160405280156110ac578160200160208202803683370190505b5090506000846001600160a01b03166365f7f80d6040518163ffffffff1660e01b815260040160206040518083038186803b1580156110ea57600080fd5b505afa1580156110fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112291906122c6565b6001600160401b031690506000805b84816001600160401b0316101561133557604051631b774dd160e21b81526001600160401b03821660048201526000906001600160a01b03891690636ddd37449060240160206040518083038186803b15801561118d57600080fd5b505afa1580156111a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111c59190612476565b90506000886001600160a01b0316633e96576e836040518263ffffffff1660e01b81526004016111f591906122a7565b60206040518083038186803b15801561120d57600080fd5b505afa158015611221573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061124591906122c6565b6001600160401b031690508481111580156112e25750604051631a7f494760e21b81526001600160a01b038a16906369fd251c906112879085906004016122a7565b60206040518083038186803b15801561129f57600080fd5b505afa1580156112b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112d791906122c6565b6001600160401b0316155b1561132057818685815181106112fa576112fa612493565b6001600160a01b03909216602092830291909101909101528361131c816124cb565b9450505b5050808061132d9061250f565b915050611131565b508252509392505050565b6040805160608101825260008082526020820181905291810191909152604051631f4b2bb760e11b81526000906001600160a01b03871690633e96576e9061138c9088906004016122a7565b60206040518083038186803b1580156113a457600080fd5b505afa1580156113b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113dc91906122c6565b90506000866001600160a01b0316633e96576e866040518263ffffffff1660e01b815260040161140c91906122a7565b60206040518083038186803b15801561142457600080fd5b505afa158015611438573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061145c91906122c6565b905061146a87838387611477565b925050505b949350505050565b60408051606081018252600080825260208201819052918101919091526000856001600160a01b031663d735e21d6040518163ffffffff1660e01b815260040160206040518083038186803b1580156114cf57600080fd5b505afa1580156114e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061150791906122c6565b6040516324b204d360e21b81526001600160401b03871660048201529091506000906001600160a01b038816906392c8134c906024016101806040518083038186803b15801561155657600080fd5b505afa15801561156a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061158e9190612330565b606001516040516324b204d360e21b81526001600160401b03871660048201529091506000906001600160a01b038916906392c8134c906024016101806040518083038186803b1580156115e157600080fd5b505afa1580156115f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116199190612330565b60600151905060005b8581101561185857866001600160401b0316886001600160401b0316141561167f5760408051606081019091528060005b8152602001896001600160401b03168152602001886001600160401b031681525094505050505061146f565b816001600160401b0316836001600160401b031614156116ac576040805160608101909152806001611653565b836001600160401b0316836001600160401b03161080156116de5750836001600160401b0316826001600160401b0316105b1561170e5760408051606081019091528060028152600060208201819052604090910152945061146f9350505050565b816001600160401b0316836001600160401b031610156117b9576040516324b204d360e21b81526001600160401b038316600482015291965086916001600160a01b038a16906392c8134c906024016101806040518083038186803b15801561177657600080fd5b505afa15801561178a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117ae9190612330565b606001519150611846565b6040516324b204d360e21b81526001600160401b038416600482015292975087926001600160a01b038a16906392c8134c906024016101806040518083038186803b15801561180757600080fd5b505afa15801561181b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061183f9190612330565b6060015192505b80611850816124cb565b915050611622565b506040805160608101909152806003815260006020820181905260409091015298975050505050505050565b600080826001600160a01b0316637ba9534a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156118c057600080fd5b505afa1580156118d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118f891906122c6565b6001600160401b031690506000836001600160a01b031663d735e21d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561193e57600080fd5b505afa158015611952573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061197691906122c6565b90505b81816001600160401b031611611a60576000816001600160401b0316118015611a3f57506119a8600182612536565b6040516324b204d360e21b81526001600160401b03838116600483015291909116906001600160a01b038616906392c8134c906024016101806040518083038186803b1580156119f757600080fd5b505afa158015611a0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a2f9190612330565b606001516001600160401b031614155b15611a4e575060009392505050565b80611a588161250f565b915050611979565b5060019392505050565b60408051620186a08082526230d420820190925260609160009190602082016230d40080368337019050509050600080856001600160a01b03166365f7f80d6040518163ffffffff1660e01b815260040160206040518083038186803b158015611ad357600080fd5b505afa158015611ae7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b0b91906122c6565b90505b856001600160a01b0316637ba9534a6040518163ffffffff1660e01b815260040160206040518083038186803b158015611b4757600080fd5b505afa158015611b5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b7f91906122c6565b6001600160401b0316816001600160401b031611611c6f5760405163154cb5e960e31b81526001600160401b03821660048201526001600160a01b03868116602483015287169063aa65af489060440160206040518083038186803b158015611be757600080fd5b505afa158015611bfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c1f91906124a9565b15611c5d5780838381518110611c3757611c37612493565b6001600160401b039092166020928302919091019091015281611c59816124cb565b9250505b80611c678161250f565b915050611b0e565b5081529392505050565b6060600080856001600160a01b031663dff697876040518163ffffffff1660e01b815260040160206040518083038186803b158015611cb757600080fd5b505afa158015611ccb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cef91906122c6565b6001600160401b0316905080611d05858761255e565b6001600160401b031611611d2d57611d1d848661255e565b6001600160401b03169050600191505b6000816001600160401b03811115611d4757611d476122e3565b604051908082528060200260200182016040528015611d70578160200160208202803683370190505b50905060005b82816001600160401b03161015611e5c576001600160a01b038816636ddd3744611da0838a61255e565b6040516001600160e01b031960e084901b1681526001600160401b03909116600482015260240160206040518083038186803b158015611ddf57600080fd5b505afa158015611df3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e179190612476565b82826001600160401b031681518110611e3257611e32612493565b6001600160a01b039092166020928302919091019091015280611e548161250f565b915050611d76565b50925050935093915050565b80608001516001600160401b0316431015611e955760405162461bcd60e51b81526004016105b9906124e6565b50565b8060a001516001600160401b0316431015611e955760405162461bcd60e51b815260206004820152601060248201526f10d212531117d513d3d7d49150d1539560821b60448201526064016105b9565b6001600160a01b0381168114611e9557600080fd5b60008060408385031215611f1057600080fd5b8235611f1b81611ee8565b91506020830135611f2b81611ee8565b809150509250929050565b60006101a0820190506001600160401b03841682528251602083015260208301516040830152604083015160608301526060830151611f8060808401826001600160401b03169052565b5060808301516001600160401b03811660a08401525060a08301516001600160401b03811660c08401525060c08301516001600160401b03811660e08401525060e0830151610100611fdc818501836001600160401b03169052565b8401519050610120611ff8848201836001600160401b03169052565b8401519050610140612014848201836001600160401b03169052565b8401519050610160612030848201836001600160401b03169052565b8085015161018085015250509392505050565b60006020828403121561205557600080fd5b813561206081611ee8565b9392505050565b634e487b7160e01b600052602160045260246000fd5b602081016003831061209157612091612067565b91905290565b6001600160401b0381168114611e9557600080fd5b6000806000606084860312156120c157600080fd5b83356120cc81611ee8565b925060208401356120dc81612097565b915060408401356120ec81612097565b809150509250925092565b600081518084526020808501945080840160005b838110156121305781516001600160401b03168752958201959082019060010161210b565b509495945050505050565b60408152600061214e60408301856120f7565b905082151560208301529392505050565b600081518084526020808501945080840160005b838110156121305781516001600160a01b031687529582019590820190600101612173565b602081526000612060602083018461215f565b600080600080608085870312156121c157600080fd5b84356121cc81611ee8565b935060208501356121dc81611ee8565b925060408501356121ec81611ee8565b9396929550929360600135925050565b815160608201906004811061221357612213612067565b8083525060208301516001600160401b038082166020850152806040860151166040850152505092915050565b6000806000806080858703121561225657600080fd5b843561226181611ee8565b9350602085013561227181612097565b925060408501356121ec81612097565b60208152600061206060208301846120f7565b60408152600061214e604083018561215f565b6001600160a01b0391909116815260200190565b80516104ac81612097565b6000602082840312156122d857600080fd5b815161206081612097565b634e487b7160e01b600052604160045260246000fd5b60405161018081016001600160401b038111828210171561232a57634e487b7160e01b600052604160045260246000fd5b60405290565b6000610180828403121561234357600080fd5b61234b6122f9565b82518152602083015160208201526040830151604082015261236f606084016122bb565b6060820152612380608084016122bb565b608082015261239160a084016122bb565b60a08201526123a260c084016122bb565b60c08201526123b360e084016122bb565b60e08201526101006123c68185016122bb565b908201526101206123d88482016122bb565b908201526101406123ea8482016122bb565b90820152610160928301519281019290925250919050565b634e487b7160e01b600052600160045260246000fd5b60006020828403121561242a57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b60008282101561245957612459612431565b500390565b6000821982111561247157612471612431565b500190565b60006020828403121561248857600080fd5b815161206081611ee8565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156124bb57600080fd5b8151801515811461206057600080fd5b60006000198214156124df576124df612431565b5060010190565b6020808252600f908201526e4245464f52455f444541444c494e4560881b604082015260600190565b60006001600160401b038083168181141561252c5761252c612431565b6001019392505050565b60006001600160401b038381169083168181101561255657612556612431565b039392505050565b60006001600160401b0380831681851680830382111561258057612580612431565b0194935050505056fea2646970667358221220e58a92a131adb3250802a5b67ca0fae6d59b8f8397c036ccaf63b400d8fa97dd64736f6c63430008090033
Loading...
Loading
Loading...
Loading
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.