ETH Price: $3,100.18 (+0.61%)
Gas: 3 Gwei

Contract

0x2a6DD4433ffa96dc1755814FC0d9cc83A5F68DeC
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Value
0x60a06040187360902023-12-07 18:06:23215 days ago1701972383IN
 Create: Outbox
0 ETH0.0995133675.76815492

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Outbox

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
Yes with 100 runs

Other Settings:
default evmVersion
File 1 of 8 : Outbox.sol
// 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;

import "./AbsOutbox.sol";

contract Outbox is AbsOutbox {
    /// @inheritdoc AbsOutbox
    function _defaultContextAmount() internal pure override returns (uint256) {
        // In ETH-based chains withdrawal amount can be read from msg.value. For that reason
        // amount slot in context will never be accessed and it has 0 default value
        return 0;
    }

    /// @inheritdoc AbsOutbox
    function _amountToSetInContext(uint256) internal pure override returns (uint256) {
        // In ETH-based chains withdrawal amount can be read from msg.value. For that reason
        // amount slot in context will never be accessed, we keep it as 0 all the time
        return 0;
    }
}

File 2 of 8 : AbsOutbox.sol
// Copyright 2021-2022, Offchain Labs, Inc.
// For license information, see https://github.com/nitro/blob/master/LICENSE
// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.8.4;

import {
    AlreadyInit,
    NotRollup,
    ProofTooLong,
    PathNotMinimal,
    UnknownRoot,
    AlreadySpent,
    BridgeCallFailed,
    HadZeroInit,
    BadPostUpgradeInit,
    RollupNotChanged
} from "../libraries/Error.sol";
import "./IBridge.sol";
import "./IOutbox.sol";
import "../libraries/MerkleLib.sol";
import "../libraries/DelegateCallAware.sol";

/// @dev this error is thrown since certain functions are only expected to be used in simulations, not in actual txs
error SimulationOnlyEntrypoint();

abstract contract AbsOutbox is DelegateCallAware, IOutbox {
    address public rollup; // the rollup contract
    IBridge public bridge; // the bridge contract

    mapping(uint256 => bytes32) public spent; // packed spent bitmap
    mapping(bytes32 => bytes32) public roots; // maps root hashes => L2 block hash

    // we're packing this struct into 4 storage slots
    // 1st slot: timestamp, l2Block (128 bits each, max ~3.4*10^38)
    // 2nd slot: outputId (256 bits)
    // 3rd slot: l1Block (96 bits, max ~7.9*10^28), sender (address 160 bits)
    // 4th slot: withdrawalAmount (256 bits)
    struct L2ToL1Context {
        uint128 l2Block;
        uint128 timestamp;
        bytes32 outputId;
        address sender;
        uint96 l1Block;
        uint256 withdrawalAmount;
    }

    // Note, these variables are set and then wiped during a single transaction.
    // Therefore their values don't need to be maintained, and their slots will
    // hold default values (which are interpreted as empty values) outside of transactions
    L2ToL1Context internal context;

    // default context values to be used in storage instead of zero, to save on storage refunds
    // it is assumed that arb-os never assigns these values to a valid leaf to be redeemed
    uint128 private constant L2BLOCK_DEFAULT_CONTEXT = type(uint128).max;
    uint96 private constant L1BLOCK_DEFAULT_CONTEXT = type(uint96).max;
    uint128 private constant TIMESTAMP_DEFAULT_CONTEXT = type(uint128).max;
    bytes32 private constant OUTPUTID_DEFAULT_CONTEXT = bytes32(type(uint256).max);
    address private constant SENDER_DEFAULT_CONTEXT = address(type(uint160).max);

    uint128 public constant OUTBOX_VERSION = 2;

    function initialize(IBridge _bridge) external onlyDelegated {
        if (address(_bridge) == address(0)) revert HadZeroInit();
        if (address(bridge) != address(0)) revert AlreadyInit();
        // address zero is returned if no context is set, but the values used in storage
        // are non-zero to save users some gas (as storage refunds are usually maxed out)
        // EIP-1153 would help here
        context = L2ToL1Context({
            l2Block: L2BLOCK_DEFAULT_CONTEXT,
            l1Block: L1BLOCK_DEFAULT_CONTEXT,
            timestamp: TIMESTAMP_DEFAULT_CONTEXT,
            outputId: OUTPUTID_DEFAULT_CONTEXT,
            sender: SENDER_DEFAULT_CONTEXT,
            withdrawalAmount: _defaultContextAmount()
        });
        bridge = _bridge;
        rollup = address(_bridge.rollup());
    }

    function postUpgradeInit() external onlyDelegated onlyProxyOwner {
        // prevent postUpgradeInit within a withdrawal
        if (context.l2Block != L2BLOCK_DEFAULT_CONTEXT) revert BadPostUpgradeInit();
        context = L2ToL1Context({
            l2Block: L2BLOCK_DEFAULT_CONTEXT,
            l1Block: L1BLOCK_DEFAULT_CONTEXT,
            timestamp: TIMESTAMP_DEFAULT_CONTEXT,
            outputId: OUTPUTID_DEFAULT_CONTEXT,
            sender: SENDER_DEFAULT_CONTEXT,
            withdrawalAmount: _defaultContextAmount()
        });
    }

    /// @notice Allows the rollup owner to sync the rollup address
    function updateRollupAddress() external {
        if (msg.sender != IOwnable(rollup).owner())
            revert NotOwner(msg.sender, IOwnable(rollup).owner());
        address newRollup = address(bridge.rollup());
        if (rollup == newRollup) revert RollupNotChanged();
        rollup = newRollup;
    }

    function updateSendRoot(bytes32 root, bytes32 l2BlockHash) external {
        if (msg.sender != rollup) revert NotRollup(msg.sender, rollup);
        roots[root] = l2BlockHash;
        emit SendRootUpdated(root, l2BlockHash);
    }

    /// @inheritdoc IOutbox
    function l2ToL1Sender() external view returns (address) {
        address sender = context.sender;
        // we don't return the default context value to avoid a breaking change in the API
        if (sender == SENDER_DEFAULT_CONTEXT) return address(0);
        return sender;
    }

    /// @inheritdoc IOutbox
    function l2ToL1Block() external view returns (uint256) {
        uint128 l2Block = context.l2Block;
        // we don't return the default context value to avoid a breaking change in the API
        if (l2Block == L2BLOCK_DEFAULT_CONTEXT) return uint256(0);
        return uint256(l2Block);
    }

    /// @inheritdoc IOutbox
    function l2ToL1EthBlock() external view returns (uint256) {
        uint96 l1Block = context.l1Block;
        // we don't return the default context value to avoid a breaking change in the API
        if (l1Block == L1BLOCK_DEFAULT_CONTEXT) return uint256(0);
        return uint256(l1Block);
    }

    /// @inheritdoc IOutbox
    function l2ToL1Timestamp() external view returns (uint256) {
        uint128 timestamp = context.timestamp;
        // we don't return the default context value to avoid a breaking change in the API
        if (timestamp == TIMESTAMP_DEFAULT_CONTEXT) return uint256(0);
        return uint256(timestamp);
    }

    /// @notice batch number is deprecated and now always returns 0
    function l2ToL1BatchNum() external pure returns (uint256) {
        return 0;
    }

    /// @inheritdoc IOutbox
    function l2ToL1OutputId() external view returns (bytes32) {
        bytes32 outputId = context.outputId;
        // we don't return the default context value to avoid a breaking change in the API
        if (outputId == OUTPUTID_DEFAULT_CONTEXT) return bytes32(0);
        return outputId;
    }

    /// @inheritdoc IOutbox
    function executeTransaction(
        bytes32[] calldata proof,
        uint256 index,
        address l2Sender,
        address to,
        uint256 l2Block,
        uint256 l1Block,
        uint256 l2Timestamp,
        uint256 value,
        bytes calldata data
    ) external {
        bytes32 userTx = calculateItemHash(
            l2Sender,
            to,
            l2Block,
            l1Block,
            l2Timestamp,
            value,
            data
        );

        recordOutputAsSpent(proof, index, userTx);

        executeTransactionImpl(index, l2Sender, to, l2Block, l1Block, l2Timestamp, value, data);
    }

    /// @inheritdoc IOutbox
    function executeTransactionSimulation(
        uint256 index,
        address l2Sender,
        address to,
        uint256 l2Block,
        uint256 l1Block,
        uint256 l2Timestamp,
        uint256 value,
        bytes calldata data
    ) external {
        if (msg.sender != address(0)) revert SimulationOnlyEntrypoint();
        executeTransactionImpl(index, l2Sender, to, l2Block, l1Block, l2Timestamp, value, data);
    }

    function executeTransactionImpl(
        uint256 outputId,
        address l2Sender,
        address to,
        uint256 l2Block,
        uint256 l1Block,
        uint256 l2Timestamp,
        uint256 value,
        bytes calldata data
    ) internal {
        emit OutBoxTransactionExecuted(to, l2Sender, 0, outputId);

        // we temporarily store the previous values so the outbox can naturally
        // unwind itself when there are nested calls to `executeTransaction`
        L2ToL1Context memory prevContext = context;

        context = L2ToL1Context({
            sender: l2Sender,
            l2Block: uint128(l2Block),
            l1Block: uint96(l1Block),
            timestamp: uint128(l2Timestamp),
            outputId: bytes32(outputId),
            withdrawalAmount: _amountToSetInContext(value)
        });

        // set and reset vars around execution so they remain valid during call
        executeBridgeCall(to, value, data);

        context = prevContext;
    }

    function _calcSpentIndexOffset(uint256 index)
        internal
        view
        returns (
            uint256,
            uint256,
            bytes32
        )
    {
        uint256 spentIndex = index / 255; // Note: Reserves the MSB.
        uint256 bitOffset = index % 255;
        bytes32 replay = spent[spentIndex];
        return (spentIndex, bitOffset, replay);
    }

    function _isSpent(uint256 bitOffset, bytes32 replay) internal pure returns (bool) {
        return ((replay >> bitOffset) & bytes32(uint256(1))) != bytes32(0);
    }

    /// @inheritdoc IOutbox
    function isSpent(uint256 index) external view returns (bool) {
        (, uint256 bitOffset, bytes32 replay) = _calcSpentIndexOffset(index);
        return _isSpent(bitOffset, replay);
    }

    function recordOutputAsSpent(
        bytes32[] memory proof,
        uint256 index,
        bytes32 item
    ) internal {
        if (proof.length >= 256) revert ProofTooLong(proof.length);
        if (index >= 2**proof.length) revert PathNotMinimal(index, 2**proof.length);

        // Hash the leaf an extra time to prove it's a leaf
        bytes32 calcRoot = calculateMerkleRoot(proof, index, item);
        if (roots[calcRoot] == bytes32(0)) revert UnknownRoot(calcRoot);

        (uint256 spentIndex, uint256 bitOffset, bytes32 replay) = _calcSpentIndexOffset(index);

        if (_isSpent(bitOffset, replay)) revert AlreadySpent(index);
        spent[spentIndex] = (replay | bytes32(1 << bitOffset));
    }

    function executeBridgeCall(
        address to,
        uint256 value,
        bytes memory data
    ) internal {
        (bool success, bytes memory returndata) = bridge.executeCall(to, value, data);
        if (!success) {
            if (returndata.length > 0) {
                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert BridgeCallFailed();
            }
        }
    }

    function calculateItemHash(
        address l2Sender,
        address to,
        uint256 l2Block,
        uint256 l1Block,
        uint256 l2Timestamp,
        uint256 value,
        bytes calldata data
    ) public pure returns (bytes32) {
        return
            keccak256(abi.encodePacked(l2Sender, to, l2Block, l1Block, l2Timestamp, value, data));
    }

    function calculateMerkleRoot(
        bytes32[] memory proof,
        uint256 path,
        bytes32 item
    ) public pure returns (bytes32) {
        return MerkleLib.calculateRoot(proof, path, keccak256(abi.encodePacked(item)));
    }

    /// @notice default value to be used for 'amount' field in L2ToL1Context outside of transaction execution.
    /// @return default 'amount' in case of ERC20-based rollup is type(uint256).max, or 0 in case of ETH-based rollup
    function _defaultContextAmount() internal pure virtual returns (uint256);

    /// @notice value to be set for 'amount' field in L2ToL1Context during L2 to L1 transaction execution.
    ///         In case of ERC20-based rollup this is the amount of native token being withdrawn. In case of standard ETH-based
    ///         rollup this amount shall always be 0, because amount of ETH being withdrawn can be read from msg.value.
    /// @return amount of native token being withdrawn in case of ERC20-based rollup, or 0 in case of ETH-based rollup
    function _amountToSetInContext(uint256 value) internal pure virtual returns (uint256);

    /**
     * @dev This empty reserved space is put in place to allow future versions to add new
     * variables without shifting down storage in the inheritance chain.
     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
     */
    uint256[42] private __gap;
}

File 3 of 8 : IBridge.sol
// 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 {
    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;
}

File 4 of 8 : IOutbox.sol
// 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;
}

File 5 of 8 : IOwnable.sol
// 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);
}

File 6 of 8 : DelegateCallAware.sol
// 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 {NotOwner} from "./Error.sol";

/// @dev A stateless contract that allows you to infer if the current call has been delegated or not
/// Pattern used here is from UUPS implementation by the OpenZeppelin team
abstract contract DelegateCallAware {
    address private immutable __self = address(this);

    /**
     * @dev Check that the execution is being performed through a delegate call. This allows a function to be
     * callable on the proxy contract but not on the logic contract.
     */
    modifier onlyDelegated() {
        require(address(this) != __self, "Function must be called through delegatecall");
        _;
    }

    /**
     * @dev Check that the execution is not being performed through a delegate call. This allows a function to be
     * callable on the implementing contract but not through proxies.
     */
    modifier notDelegated() {
        require(address(this) == __self, "Function must not be called through delegatecall");
        _;
    }

    /// @dev Check that msg.sender is the current EIP 1967 proxy admin
    modifier onlyProxyOwner() {
        // Storage slot with the admin of the proxy contract
        // This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1
        bytes32 slot = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
        address admin;
        assembly {
            admin := sload(slot)
        }
        if (msg.sender != admin) revert NotOwner(msg.sender, admin);
        _;
    }
}

File 7 of 8 : Error.sol
// 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;

/// @dev Init was already called
error AlreadyInit();

/// @dev Init was called with param set to zero that must be nonzero
error HadZeroInit();

/// @dev Thrown when post upgrade init validation fails
error BadPostUpgradeInit();

/// @dev Thrown when non owner tries to access an only-owner function
/// @param sender The msg.sender who is not the owner
/// @param owner The owner address
error NotOwner(address sender, address owner);

/// @dev Thrown when an address that is not the rollup tries to call an only-rollup function
/// @param sender The sender who is not the rollup
/// @param rollup The rollup address authorized to call this function
error NotRollup(address sender, address rollup);

/// @dev Thrown when the contract was not called directly from the origin ie msg.sender != tx.origin
error NotOrigin();

/// @dev Provided data was too large
/// @param dataLength The length of the data that is too large
/// @param maxDataLength The max length the data can be
error DataTooLarge(uint256 dataLength, uint256 maxDataLength);

/// @dev The provided is not a contract and was expected to be
/// @param addr The adddress in question
error NotContract(address addr);

/// @dev The merkle proof provided was too long
/// @param actualLength The length of the merkle proof provided
/// @param maxProofLength The max length a merkle proof can have
error MerkleProofTooLong(uint256 actualLength, uint256 maxProofLength);

/// @dev Thrown when an un-authorized address tries to access an admin function
/// @param sender The un-authorized sender
/// @param rollup The rollup, which would be authorized
/// @param owner The rollup's owner, which would be authorized
error NotRollupOrOwner(address sender, address rollup, address owner);

// Bridge Errors

/// @dev Thrown when an un-authorized address tries to access an only-inbox function
/// @param sender The un-authorized sender
error NotDelayedInbox(address sender);

/// @dev Thrown when an un-authorized address tries to access an only-sequencer-inbox function
/// @param sender The un-authorized sender
error NotSequencerInbox(address sender);

/// @dev Thrown when an un-authorized address tries to access an only-outbox function
/// @param sender The un-authorized sender
error NotOutbox(address sender);

/// @dev the provided outbox address isn't valid
/// @param outbox address of outbox being set
error InvalidOutboxSet(address outbox);

/// @dev The provided token address isn't valid
/// @param token address of token being set
error InvalidTokenSet(address token);

/// @dev Call to this specific address is not allowed
/// @param target address of the call receiver
error CallTargetNotAllowed(address target);

/// @dev Call that changes the balance of ERC20Bridge is not allowed
error CallNotAllowed();

// Inbox Errors

/// @dev The contract is paused, so cannot be paused
error AlreadyPaused();

/// @dev The contract is unpaused, so cannot be unpaused
error AlreadyUnpaused();

/// @dev The contract is paused
error Paused();

/// @dev msg.value sent to the inbox isn't high enough
error InsufficientValue(uint256 expected, uint256 actual);

/// @dev submission cost provided isn't enough to create retryable ticket
error InsufficientSubmissionCost(uint256 expected, uint256 actual);

/// @dev address not allowed to interact with the given contract
error NotAllowedOrigin(address origin);

/// @dev used to convey retryable tx data in eth calls without requiring a tx trace
/// this follows a pattern similar to EIP-3668 where reverts surface call information
error RetryableData(
    address from,
    address to,
    uint256 l2CallValue,
    uint256 deposit,
    uint256 maxSubmissionCost,
    address excessFeeRefundAddress,
    address callValueRefundAddress,
    uint256 gasLimit,
    uint256 maxFeePerGas,
    bytes data
);

/// @dev Thrown when a L1 chainId fork is detected
error L1Forked();

/// @dev Thrown when a L1 chainId fork is not detected
error NotForked();

/// @dev The provided gasLimit is larger than uint64
error GasLimitTooLarge();

// Outbox Errors

/// @dev The provided proof was too long
/// @param proofLength The length of the too-long proof
error ProofTooLong(uint256 proofLength);

/// @dev The output index was greater than the maximum
/// @param index The output index
/// @param maxIndex The max the index could be
error PathNotMinimal(uint256 index, uint256 maxIndex);

/// @dev The calculated root does not exist
/// @param root The calculated root
error UnknownRoot(bytes32 root);

/// @dev The record has already been spent
/// @param index The index of the spent record
error AlreadySpent(uint256 index);

/// @dev A call to the bridge failed with no return data
error BridgeCallFailed();

// Sequencer Inbox Errors

/// @dev Thrown when someone attempts to read fewer messages than have already been read
error DelayedBackwards();

/// @dev Thrown when someone attempts to read more messages than exist
error DelayedTooFar();

/// @dev Force include can only read messages more blocks old than the delay period
error ForceIncludeBlockTooSoon();

/// @dev Force include can only read messages more seconds old than the delay period
error ForceIncludeTimeTooSoon();

/// @dev The message provided did not match the hash in the delayed inbox
error IncorrectMessagePreimage();

/// @dev This can only be called by the batch poster
error NotBatchPoster();

/// @dev The sequence number provided to this message was inconsistent with the number of batches already included
error BadSequencerNumber(uint256 stored, uint256 received);

/// @dev The sequence message number provided to this message was inconsistent with the previous one
error BadSequencerMessageNumber(uint256 stored, uint256 received);

/// @dev The batch data has the inbox authenticated bit set, but the batch data was not authenticated by the inbox
error DataNotAuthenticated();

/// @dev Tried to create an already valid Data Availability Service keyset
error AlreadyValidDASKeyset(bytes32);

/// @dev Tried to use or invalidate an already invalid Data Availability Service keyset
error NoSuchKeyset(bytes32);

/// @dev Thrown when rollup is not updated with updateRollupAddress
error RollupNotChanged();

File 8 of 8 : MerkleLib.sol
// 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;

import {MerkleProofTooLong} from "./Error.sol";

library MerkleLib {
    function generateRoot(bytes32[] memory _hashes) internal pure returns (bytes32) {
        bytes32[] memory prevLayer = _hashes;
        while (prevLayer.length > 1) {
            bytes32[] memory nextLayer = new bytes32[]((prevLayer.length + 1) / 2);
            for (uint256 i = 0; i < nextLayer.length; i++) {
                if (2 * i + 1 < prevLayer.length) {
                    nextLayer[i] = keccak256(
                        abi.encodePacked(prevLayer[2 * i], prevLayer[2 * i + 1])
                    );
                } else {
                    nextLayer[i] = prevLayer[2 * i];
                }
            }
            prevLayer = nextLayer;
        }
        return prevLayer[0];
    }

    function calculateRoot(
        bytes32[] memory nodes,
        uint256 route,
        bytes32 item
    ) internal pure returns (bytes32) {
        uint256 proofItems = nodes.length;
        if (proofItems > 256) revert MerkleProofTooLong(proofItems, 256);
        bytes32 h = item;
        for (uint256 i = 0; i < proofItems; ) {
            bytes32 node = nodes[i];
            if ((route & (1 << i)) == 0) {
                assembly {
                    mstore(0x00, h)
                    mstore(0x20, node)
                    h := keccak256(0x00, 0x40)
                }
            } else {
                assembly {
                    mstore(0x00, node)
                    mstore(0x20, h)
                    h := keccak256(0x00, 0x40)
                }
            }
            unchecked {
                ++i;
            }
        }
        return h;
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 100
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "metadata": {
    "useLiteralContent": true
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[],"name":"AlreadyInit","type":"error"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"AlreadySpent","type":"error"},{"inputs":[],"name":"BadPostUpgradeInit","type":"error"},{"inputs":[],"name":"BridgeCallFailed","type":"error"},{"inputs":[],"name":"HadZeroInit","type":"error"},{"inputs":[{"internalType":"uint256","name":"actualLength","type":"uint256"},{"internalType":"uint256","name":"maxProofLength","type":"uint256"}],"name":"MerkleProofTooLong","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"NotOwner","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"rollup","type":"address"}],"name":"NotRollup","type":"error"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"maxIndex","type":"uint256"}],"name":"PathNotMinimal","type":"error"},{"inputs":[{"internalType":"uint256","name":"proofLength","type":"uint256"}],"name":"ProofTooLong","type":"error"},{"inputs":[],"name":"RollupNotChanged","type":"error"},{"inputs":[],"name":"SimulationOnlyEntrypoint","type":"error"},{"inputs":[{"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"UnknownRoot","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"address","name":"l2Sender","type":"address"},{"indexed":true,"internalType":"uint256","name":"zero","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"transactionIndex","type":"uint256"}],"name":"OutBoxTransactionExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"outputRoot","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"l2BlockHash","type":"bytes32"}],"name":"SendRootUpdated","type":"event"},{"inputs":[],"name":"OUTBOX_VERSION","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bridge","outputs":[{"internalType":"contract IBridge","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"l2Sender","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"l2Block","type":"uint256"},{"internalType":"uint256","name":"l1Block","type":"uint256"},{"internalType":"uint256","name":"l2Timestamp","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"calculateItemHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"uint256","name":"path","type":"uint256"},{"internalType":"bytes32","name":"item","type":"bytes32"}],"name":"calculateMerkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"address","name":"l2Sender","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"l2Block","type":"uint256"},{"internalType":"uint256","name":"l1Block","type":"uint256"},{"internalType":"uint256","name":"l2Timestamp","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"executeTransaction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"address","name":"l2Sender","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"l2Block","type":"uint256"},{"internalType":"uint256","name":"l1Block","type":"uint256"},{"internalType":"uint256","name":"l2Timestamp","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"executeTransactionSimulation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IBridge","name":"_bridge","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"isSpent","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l2ToL1BatchNum","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"l2ToL1Block","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l2ToL1EthBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l2ToL1OutputId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l2ToL1Sender","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l2ToL1Timestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"postUpgradeInit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rollup","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"roots","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"spent","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updateRollupAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"root","type":"bytes32"},{"internalType":"bytes32","name":"l2BlockHash","type":"bytes32"}],"name":"updateSendRoot","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60a06040523060805234801561001457600080fd5b506080516116cd6100376000396000818161067a015261088501526116cd6000f3fe608060405234801561001057600080fd5b506004361061012b5760003560e01c806395fcea78116100ad578063c4d66de811610071578063c4d66de81461023e578063c75184df14610251578063cb23bcb514610271578063d5b5cc2314610284578063e78cea92146102a457600080fd5b806395fcea78146101e85780639f0c04bf146101f0578063a04cee6014610203578063ae6dead714610216578063b0f305371461023657600080fd5b80635a129efe116100f45780635a129efe1461018d5780636ae71f12146101b057806372f2a8c7146101b857806380648b02146101c05780638515bc6a146101e057600080fd5b80627436d31461013057806308635a9514610156578063119852711461016b578063288e5b10146101725780634654779014610185575b600080fd5b61014361013e366004610fa3565b6102b7565b6040519081526020015b60405180910390f35b6101696101643660046110c3565b6102f4565b005b6000610143565b6101696101803660046111b7565b610367565b6101436103a2565b6101a061019b366004611252565b6103d1565b604051901515815260200161014d565b6101696103ee565b6101436105fb565b6101c8610618565b6040516001600160a01b03909116815260200161014d565b610143610639565b61016961066f565b6101436101fe36600461126b565b610792565b6101696102113660046112f9565b6107d7565b610143610224366004611252565b60036020526000908152604090205481565b610143610852565b61016961024c36600461131b565b61087a565b610259600281565b6040516001600160801b03909116815260200161014d565b6000546101c8906001600160a01b031681565b610143610292366004611252565b60026020526000908152604090205481565b6001546101c8906001600160a01b031681565b60006102ec8484846040516020016102d191815260200190565b60405160208183030381529060405280519060200120610a19565b949350505050565b60006103068989898989898989610792565b90506103488c8c808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508e9250859150610abc9050565b6103598a8a8a8a8a8a8a8a8a610bc5565b505050505050505050505050565b331561038657604051630e13b69d60e01b815260040160405180910390fd5b610397898989898989898989610bc5565b505050505050505050565b6004546000906001600160801b03908116908114156103c357600091505090565b6001600160801b0316919050565b60008060006103df84610e49565b92509250506102ec8282610e86565b60008054906101000a90046001600160a01b03166001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561043a57600080fd5b505afa15801561044e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610472919061133f565b6001600160a01b0316336001600160a01b03161461052a5760005460408051638da5cb5b60e01b8152905133926001600160a01b031691638da5cb5b916004808301926020929190829003018186803b1580156104ce57600080fd5b505afa1580156104e2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610506919061133f565b604051631194af8760e11b815260040161052192919061135c565b60405180910390fd5b6001546040805163cb23bcb560e01b815290516000926001600160a01b03169163cb23bcb5916004808301926020929190829003018186803b15801561056f57600080fd5b505afa158015610583573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105a7919061133f565b6000549091506001600160a01b03808316911614156105d95760405163d054909f60e01b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b0392909216919091179055565b60055460009060001981141561061357506000919050565b919050565b6006546000906001600160a01b039081169081141561061357600091505090565b6006546000906001600160601b03600160a01b90910481169081141561066157600091505090565b6001600160601b0316919050565b306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614156106b85760405162461bcd60e51b815260040161052190611376565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038054336001600160a01b03821614610708573381604051631194af8760e11b815260040161052192919061135c565b6004546001600160801b03908116146107345760405163d0afb66160e01b815260040160405180910390fd5b50506040805160c0810182526001600160801b0380825260208201526000199181018290526001600160a01b0360608201526001600160601b036080820152600060a090910181905260048290556005829055600691909155600755565b600088888888888888886040516020016107b39897969594939291906113c2565b60405160208183030381529060405280519060200120905098975050505050505050565b6000546001600160a01b0316331461081357600054604051630e4cf1bf60e21b81526105219133916001600160a01b039091169060040161135c565b60008281526003602052604080822083905551829184917fb4df3847300f076a369cd76d2314b470a1194d9e8a6bb97f1860aee88a5f67489190a35050565b6004546000906001600160801b03600160801b9091048116908114156103c357600091505090565b306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614156108c35760405162461bcd60e51b815260040161052190611376565b6001600160a01b0381166108ea57604051631ad0f74360e01b815260040160405180910390fd5b6001546001600160a01b03161561091457604051633bcd329760e21b815260040160405180910390fd5b6040805160c0810182526001600160801b038082526020808301919091526000198284018190526001600160a01b03606084018190526001600160601b036080850152600060a090940184905260048281556005839055600692909255600793909355600180546001600160a01b0319169386169384179055835163cb23bcb560e01b81529351929363cb23bcb59381830193929091829003018186803b1580156109be57600080fd5b505afa1580156109d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109f6919061133f565b600080546001600160a01b0319166001600160a01b039290921691909117905550565b8251600090610100811115610a4c57604051637ed6198f60e11b8152600481018290526101006024820152604401610521565b8260005b82811015610ab2576000878281518110610a6c57610a6c611416565b60200260200101519050816001901b871660001415610a9957826000528060205260406000209250610aa9565b8060005282602052604060002092505b50600101610a50565b5095945050505050565b610100835110610ae457825160405163ab6a068360e01b815260040161052191815260200190565b8251610af1906002611526565b8210610b28578183516002610b069190611526565b604051630b8a724b60e01b815260048101929092526024820152604401610521565b6000610b358484846102b7565b600081815260036020526040902054909150610b67576040516310e61af960e31b815260048101829052602401610521565b6000806000610b7586610e49565b925092509250610b858282610e86565b15610ba657604051639715b8d360e01b815260048101879052602401610521565b600092835260026020526040909220600190911b909117905550505050565b6000886001600160a01b0316886001600160a01b03167f20af7f3bbfe38132b8900ae295cd9c8d1914be7052d061a511f3f728dab189648c604051610c0c91815260200190565b60405180910390a4600060046040518060c00160405290816000820160009054906101000a90046001600160801b03166001600160801b03166001600160801b031681526020016000820160109054906101000a90046001600160801b03166001600160801b03166001600160801b03168152602001600182015481526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016002820160149054906101000a90046001600160601b03166001600160601b03166001600160601b0316815260200160038201548152505090506040518060c00160405280886001600160801b03168152602001866001600160801b031681526020018b60001b81526020018a6001600160a01b03168152602001876001600160601b03168152602001610d4d600090565b905280516020808301516001600160801b03908116600160801b02921691909117600455604080830151600555606083015160808401516001600160601b0316600160a01b026001600160a01b039091161760065560a0909201516007558151601f8501829004820281018201909252838252610de9918a918791908790879081908401838280828437600092019190915250610e9592505050565b805160208201516001600160801b03908116600160801b029116176004556040810151600555606081015160808201516001600160601b0316600160a01b026001600160a01b039091161760065560a00151600755505050505050505050565b6000808080610e5960ff86611548565b90506000610e6860ff8761155c565b60008381526002602052604090205492979096509194509092505050565b80821c60011615155b92915050565b600154604051639e5d4c4960e01b815260009182916001600160a01b0390911690639e5d4c4990610ece908890889088906004016115a0565b600060405180830381600087803b158015610ee857600080fd5b505af1158015610efc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610f2491908101906115e9565b9150915081610f5657805115610f3d5780518082602001fd5b604051631bb7daad60e11b815260040160405180910390fd5b5050505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715610f9b57610f9b610f5d565b604052919050565b600080600060608486031215610fb857600080fd5b83356001600160401b0380821115610fcf57600080fd5b818601915086601f830112610fe357600080fd5b8135602082821115610ff757610ff7610f5d565b8160051b9250611008818401610f73565b828152928401810192818101908a85111561102257600080fd5b948201945b8486101561104057853582529482019490820190611027565b9a918901359950506040909701359695505050505050565b6001600160a01b038116811461106d57600080fd5b50565b803561061381611058565b60008083601f84011261108d57600080fd5b5081356001600160401b038111156110a457600080fd5b6020830191508360208285010111156110bc57600080fd5b9250929050565b60008060008060008060008060008060006101208c8e0312156110e557600080fd5b8b356001600160401b03808211156110fc57600080fd5b818e0191508e601f83011261111057600080fd5b81358181111561111f57600080fd5b8f60208260051b850101111561113457600080fd5b60208381019e50909c508e01359a5061114f60408f01611070565b995061115d60608f01611070565b985060808e0135975060a08e0135965060c08e0135955060e08e013594506101008e013591508082111561119057600080fd5b5061119d8e828f0161107b565b915080935050809150509295989b509295989b9093969950565b60008060008060008060008060006101008a8c0312156111d657600080fd5b8935985060208a01356111e881611058565b975060408a01356111f881611058565b965060608a0135955060808a0135945060a08a0135935060c08a0135925060e08a01356001600160401b0381111561122f57600080fd5b61123b8c828d0161107b565b915080935050809150509295985092959850929598565b60006020828403121561126457600080fd5b5035919050565b60008060008060008060008060e0898b03121561128757600080fd5b883561129281611058565b975060208901356112a281611058565b965060408901359550606089013594506080890135935060a0890135925060c08901356001600160401b038111156112d957600080fd5b6112e58b828c0161107b565b999c989b5096995094979396929594505050565b6000806040838503121561130c57600080fd5b50508035926020909101359150565b60006020828403121561132d57600080fd5b813561133881611058565b9392505050565b60006020828403121561135157600080fd5b815161133881611058565b6001600160a01b0392831681529116602082015260400190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b60006001600160601b0319808b60601b168352808a60601b16601484015250876028830152866048830152856068830152846088830152828460a8840137506000910160a801908152979650505050505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600181815b8085111561147d5781600019048211156114635761146361142c565b8085161561147057918102915b93841c9390800290611447565b509250929050565b60008261149457506001610e8f565b816114a157506000610e8f565b81600181146114b757600281146114c1576114dd565b6001915050610e8f565b60ff8411156114d2576114d261142c565b50506001821b610e8f565b5060208310610133831016604e8410600b8410161715611500575081810a610e8f565b61150a8383611442565b806000190482111561151e5761151e61142c565b029392505050565b60006113388383611485565b634e487b7160e01b600052601260045260246000fd5b60008261155757611557611532565b500490565b60008261156b5761156b611532565b500690565b60005b8381101561158b578181015183820152602001611573565b8381111561159a576000848401525b50505050565b60018060a01b038416815282602082015260606040820152600082518060608401526115d3816080850160208701611570565b601f01601f191691909101608001949350505050565b600080604083850312156115fc57600080fd5b8251801515811461160c57600080fd5b60208401519092506001600160401b038082111561162957600080fd5b818501915085601f83011261163d57600080fd5b81518181111561164f5761164f610f5d565b611662601f8201601f1916602001610f73565b915080825286602082850101111561167957600080fd5b61168a816020840160208601611570565b508092505050925092905056fea26469706673582212201d864fde4d3fe778dfcfa436cd8c3f70afcdc0a4b262612322c379ba38ffea5164736f6c63430008090033

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061012b5760003560e01c806395fcea78116100ad578063c4d66de811610071578063c4d66de81461023e578063c75184df14610251578063cb23bcb514610271578063d5b5cc2314610284578063e78cea92146102a457600080fd5b806395fcea78146101e85780639f0c04bf146101f0578063a04cee6014610203578063ae6dead714610216578063b0f305371461023657600080fd5b80635a129efe116100f45780635a129efe1461018d5780636ae71f12146101b057806372f2a8c7146101b857806380648b02146101c05780638515bc6a146101e057600080fd5b80627436d31461013057806308635a9514610156578063119852711461016b578063288e5b10146101725780634654779014610185575b600080fd5b61014361013e366004610fa3565b6102b7565b6040519081526020015b60405180910390f35b6101696101643660046110c3565b6102f4565b005b6000610143565b6101696101803660046111b7565b610367565b6101436103a2565b6101a061019b366004611252565b6103d1565b604051901515815260200161014d565b6101696103ee565b6101436105fb565b6101c8610618565b6040516001600160a01b03909116815260200161014d565b610143610639565b61016961066f565b6101436101fe36600461126b565b610792565b6101696102113660046112f9565b6107d7565b610143610224366004611252565b60036020526000908152604090205481565b610143610852565b61016961024c36600461131b565b61087a565b610259600281565b6040516001600160801b03909116815260200161014d565b6000546101c8906001600160a01b031681565b610143610292366004611252565b60026020526000908152604090205481565b6001546101c8906001600160a01b031681565b60006102ec8484846040516020016102d191815260200190565b60405160208183030381529060405280519060200120610a19565b949350505050565b60006103068989898989898989610792565b90506103488c8c808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508e9250859150610abc9050565b6103598a8a8a8a8a8a8a8a8a610bc5565b505050505050505050505050565b331561038657604051630e13b69d60e01b815260040160405180910390fd5b610397898989898989898989610bc5565b505050505050505050565b6004546000906001600160801b03908116908114156103c357600091505090565b6001600160801b0316919050565b60008060006103df84610e49565b92509250506102ec8282610e86565b60008054906101000a90046001600160a01b03166001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561043a57600080fd5b505afa15801561044e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610472919061133f565b6001600160a01b0316336001600160a01b03161461052a5760005460408051638da5cb5b60e01b8152905133926001600160a01b031691638da5cb5b916004808301926020929190829003018186803b1580156104ce57600080fd5b505afa1580156104e2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610506919061133f565b604051631194af8760e11b815260040161052192919061135c565b60405180910390fd5b6001546040805163cb23bcb560e01b815290516000926001600160a01b03169163cb23bcb5916004808301926020929190829003018186803b15801561056f57600080fd5b505afa158015610583573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105a7919061133f565b6000549091506001600160a01b03808316911614156105d95760405163d054909f60e01b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b0392909216919091179055565b60055460009060001981141561061357506000919050565b919050565b6006546000906001600160a01b039081169081141561061357600091505090565b6006546000906001600160601b03600160a01b90910481169081141561066157600091505090565b6001600160601b0316919050565b306001600160a01b037f0000000000000000000000002a6dd4433ffa96dc1755814fc0d9cc83a5f68dec1614156106b85760405162461bcd60e51b815260040161052190611376565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038054336001600160a01b03821614610708573381604051631194af8760e11b815260040161052192919061135c565b6004546001600160801b03908116146107345760405163d0afb66160e01b815260040160405180910390fd5b50506040805160c0810182526001600160801b0380825260208201526000199181018290526001600160a01b0360608201526001600160601b036080820152600060a090910181905260048290556005829055600691909155600755565b600088888888888888886040516020016107b39897969594939291906113c2565b60405160208183030381529060405280519060200120905098975050505050505050565b6000546001600160a01b0316331461081357600054604051630e4cf1bf60e21b81526105219133916001600160a01b039091169060040161135c565b60008281526003602052604080822083905551829184917fb4df3847300f076a369cd76d2314b470a1194d9e8a6bb97f1860aee88a5f67489190a35050565b6004546000906001600160801b03600160801b9091048116908114156103c357600091505090565b306001600160a01b037f0000000000000000000000002a6dd4433ffa96dc1755814fc0d9cc83a5f68dec1614156108c35760405162461bcd60e51b815260040161052190611376565b6001600160a01b0381166108ea57604051631ad0f74360e01b815260040160405180910390fd5b6001546001600160a01b03161561091457604051633bcd329760e21b815260040160405180910390fd5b6040805160c0810182526001600160801b038082526020808301919091526000198284018190526001600160a01b03606084018190526001600160601b036080850152600060a090940184905260048281556005839055600692909255600793909355600180546001600160a01b0319169386169384179055835163cb23bcb560e01b81529351929363cb23bcb59381830193929091829003018186803b1580156109be57600080fd5b505afa1580156109d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109f6919061133f565b600080546001600160a01b0319166001600160a01b039290921691909117905550565b8251600090610100811115610a4c57604051637ed6198f60e11b8152600481018290526101006024820152604401610521565b8260005b82811015610ab2576000878281518110610a6c57610a6c611416565b60200260200101519050816001901b871660001415610a9957826000528060205260406000209250610aa9565b8060005282602052604060002092505b50600101610a50565b5095945050505050565b610100835110610ae457825160405163ab6a068360e01b815260040161052191815260200190565b8251610af1906002611526565b8210610b28578183516002610b069190611526565b604051630b8a724b60e01b815260048101929092526024820152604401610521565b6000610b358484846102b7565b600081815260036020526040902054909150610b67576040516310e61af960e31b815260048101829052602401610521565b6000806000610b7586610e49565b925092509250610b858282610e86565b15610ba657604051639715b8d360e01b815260048101879052602401610521565b600092835260026020526040909220600190911b909117905550505050565b6000886001600160a01b0316886001600160a01b03167f20af7f3bbfe38132b8900ae295cd9c8d1914be7052d061a511f3f728dab189648c604051610c0c91815260200190565b60405180910390a4600060046040518060c00160405290816000820160009054906101000a90046001600160801b03166001600160801b03166001600160801b031681526020016000820160109054906101000a90046001600160801b03166001600160801b03166001600160801b03168152602001600182015481526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016002820160149054906101000a90046001600160601b03166001600160601b03166001600160601b0316815260200160038201548152505090506040518060c00160405280886001600160801b03168152602001866001600160801b031681526020018b60001b81526020018a6001600160a01b03168152602001876001600160601b03168152602001610d4d600090565b905280516020808301516001600160801b03908116600160801b02921691909117600455604080830151600555606083015160808401516001600160601b0316600160a01b026001600160a01b039091161760065560a0909201516007558151601f8501829004820281018201909252838252610de9918a918791908790879081908401838280828437600092019190915250610e9592505050565b805160208201516001600160801b03908116600160801b029116176004556040810151600555606081015160808201516001600160601b0316600160a01b026001600160a01b039091161760065560a00151600755505050505050505050565b6000808080610e5960ff86611548565b90506000610e6860ff8761155c565b60008381526002602052604090205492979096509194509092505050565b80821c60011615155b92915050565b600154604051639e5d4c4960e01b815260009182916001600160a01b0390911690639e5d4c4990610ece908890889088906004016115a0565b600060405180830381600087803b158015610ee857600080fd5b505af1158015610efc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610f2491908101906115e9565b9150915081610f5657805115610f3d5780518082602001fd5b604051631bb7daad60e11b815260040160405180910390fd5b5050505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715610f9b57610f9b610f5d565b604052919050565b600080600060608486031215610fb857600080fd5b83356001600160401b0380821115610fcf57600080fd5b818601915086601f830112610fe357600080fd5b8135602082821115610ff757610ff7610f5d565b8160051b9250611008818401610f73565b828152928401810192818101908a85111561102257600080fd5b948201945b8486101561104057853582529482019490820190611027565b9a918901359950506040909701359695505050505050565b6001600160a01b038116811461106d57600080fd5b50565b803561061381611058565b60008083601f84011261108d57600080fd5b5081356001600160401b038111156110a457600080fd5b6020830191508360208285010111156110bc57600080fd5b9250929050565b60008060008060008060008060008060006101208c8e0312156110e557600080fd5b8b356001600160401b03808211156110fc57600080fd5b818e0191508e601f83011261111057600080fd5b81358181111561111f57600080fd5b8f60208260051b850101111561113457600080fd5b60208381019e50909c508e01359a5061114f60408f01611070565b995061115d60608f01611070565b985060808e0135975060a08e0135965060c08e0135955060e08e013594506101008e013591508082111561119057600080fd5b5061119d8e828f0161107b565b915080935050809150509295989b509295989b9093969950565b60008060008060008060008060006101008a8c0312156111d657600080fd5b8935985060208a01356111e881611058565b975060408a01356111f881611058565b965060608a0135955060808a0135945060a08a0135935060c08a0135925060e08a01356001600160401b0381111561122f57600080fd5b61123b8c828d0161107b565b915080935050809150509295985092959850929598565b60006020828403121561126457600080fd5b5035919050565b60008060008060008060008060e0898b03121561128757600080fd5b883561129281611058565b975060208901356112a281611058565b965060408901359550606089013594506080890135935060a0890135925060c08901356001600160401b038111156112d957600080fd5b6112e58b828c0161107b565b999c989b5096995094979396929594505050565b6000806040838503121561130c57600080fd5b50508035926020909101359150565b60006020828403121561132d57600080fd5b813561133881611058565b9392505050565b60006020828403121561135157600080fd5b815161133881611058565b6001600160a01b0392831681529116602082015260400190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b60006001600160601b0319808b60601b168352808a60601b16601484015250876028830152866048830152856068830152846088830152828460a8840137506000910160a801908152979650505050505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600181815b8085111561147d5781600019048211156114635761146361142c565b8085161561147057918102915b93841c9390800290611447565b509250929050565b60008261149457506001610e8f565b816114a157506000610e8f565b81600181146114b757600281146114c1576114dd565b6001915050610e8f565b60ff8411156114d2576114d261142c565b50506001821b610e8f565b5060208310610133831016604e8410600b8410161715611500575081810a610e8f565b61150a8383611442565b806000190482111561151e5761151e61142c565b029392505050565b60006113388383611485565b634e487b7160e01b600052601260045260246000fd5b60008261155757611557611532565b500490565b60008261156b5761156b611532565b500690565b60005b8381101561158b578181015183820152602001611573565b8381111561159a576000848401525b50505050565b60018060a01b038416815282602082015260606040820152600082518060608401526115d3816080850160208701611570565b601f01601f191691909101608001949350505050565b600080604083850312156115fc57600080fd5b8251801515811461160c57600080fd5b60208401519092506001600160401b038082111561162957600080fd5b818501915085601f83011261163d57600080fd5b81518181111561164f5761164f610f5d565b611662601f8201601f1916602001610f73565b915080825286602082850101111561167957600080fd5b61168a816020840160208601611570565b508092505050925092905056fea26469706673582212201d864fde4d3fe778dfcfa436cd8c3f70afcdc0a4b262612322c379ba38ffea5164736f6c63430008090033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

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.