false
false
0
The new Blockscout UI is now open source! Learn how to deploy it here

Contract Address Details

0x2Fa4805846C3a81563E4b34c9F91115532Aaeec4

Contract Name
EtnaInbox
Creator
0x4779d1–4df7b8 at 0x13d73c–ba3d8d
Balance
0 ETH
Tokens
Fetching tokens...
Transactions
Fetching transactions...
Transfers
Fetching transfers...
Gas Used
Fetching gas used...
Last Balance Update
2959
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
EtnaInbox




Optimization enabled
true
Compiler version
v0.8.30+commit.73712a01




Optimization runs
200
EVM Version
prague




Verified at
2026-10-12T09:09:02.271237Z

Constructor Arguments

0x000000000000000000000000044c2e53e9edddd1353a9d923fa39c1fa821e88e0000000000000000000000009a3a019b2820ae3d396120fb9b2782d37be4799c000000000000000000000000b261c6facc0707b674c7491338412fdf44733a4b0000000000000000000000000000000000000000000000000000000000028c590000000000000000000000000000000000000000000000000000000000000080
              

contracts/layer1/etna/impl/EtnaInbox.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

import { IEtnaInbox } from "../iface/IEtnaInbox.sol";
import { IEtnaStakingRegistry } from "../iface/IEtnaStakingRegistry.sol";
import { IProofVerifier } from "src/layer1/verifiers/IProofVerifier.sol";
import { EssentialContract } from "src/shared/common/EssentialContract.sol";
import { ICheckpointStore } from "src/shared/signal/ICheckpointStore.sol";
import { ISignalService } from "src/shared/signal/ISignalService.sol";

import "./EtnaInbox_Layout.sol"; // DO NOT DELETE

/// @title EtnaInbox
/// @notice The L1 anchor of an Etna PoS chain starting at L2 block 0. A fresh proxy records its
/// genesis checkpoint and initial committee in one initialization, then lands proven batches.
/// @dev Uses the existing ABCI storage interface without any Shasta state or migration logic.
/// Slots 251–257, 259–267 and 275–277 are reserved to keep the node-facing slots unchanged.
/// @custom:security-contact security@taiko.xyz
contract EtnaInbox is IEtnaInbox, EssentialContract {
    // ---------------------------------------------------------------
    // Structs
    // ---------------------------------------------------------------

    /// @dev The V5 statement in wire order. All fields are static, so abi.encode of this
    /// memory-only struct is the same fifteen-word encoding as the flat field list. Building
    /// it one field at a time keeps the non-IR compiler within its stack limit.
    struct LandStatement {
        bytes32 domain;
        uint256 l1ChainId;
        uint64 l2ChainId;
        address inbox;
        address stakingRegistry;
        uint64 generation;
        uint64 parentHeight;
        bytes32 parentHash;
        bytes32 committeeConfigHash;
        uint64 lastHeight;
        bytes32 lastBlockHash;
        bytes32 lastStateRoot;
        uint64 l1ReferenceBlockNumber;
        bytes32 l1ReferenceBlockHash;
        bytes32 blobHashesHash;
    }

    // ---------------------------------------------------------------
    // Constants
    // ---------------------------------------------------------------

    /// @dev The initialized status value expected by the ABCI node.
    uint8 private constant _ETNA_ACTIVE = 3;

    /// @dev The smallest epoch length in L2 blocks.
    uint64 private constant _MIN_EPOCH_LEN_L2 = 3;

    /// @dev The domain tag of the landing statement.
    bytes32 private constant _LAND_STATEMENT_TAG = bytes32("TAIKO_ETNA_LAND_V5");

    /// @dev The number of most recent L1 blocks whose hash `blockhash` returns.
    uint256 private constant _BLOCKHASH_WINDOW = 256;

    /// @dev The EIP-2935 history storage contract.
    address private constant _HISTORY_STORAGE_ADDRESS = 0x0000F90827F1C53a10cb7A02335B175320002935;

    /// @dev The number of most recent L1 blocks whose hash the EIP-2935 contract serves.
    uint256 private constant _HISTORY_SERVE_WINDOW = 8191;

    // ---------------------------------------------------------------
    // Immutable Variables
    // ---------------------------------------------------------------

    /// @dev The verifier of `land` proofs.
    IProofVerifier internal immutable _proofVerifier;

    /// @dev The L1 signal service that stores the L2 checkpoints.
    ISignalService internal immutable _signalService;

    /// @dev The Etna staking registry.
    IEtnaStakingRegistry internal immutable _stakingRegistry;

    /// @dev The chain id of the Etna L2.
    uint64 internal immutable _l2ChainId;

    /// @dev The maximum number of L2 blocks one `land` call may cover.
    uint64 internal immutable _maxBatchBlocks;

    // ---------------------------------------------------------------
    // State Variables
    // ---------------------------------------------------------------

    /// @dev Slots 251–257: reserved to preserve the existing ABCI storage interface.
    uint256[7] private __reservedBeforeStatus;

    /// @dev Slot 258: 3 once initialized; zero before initialization.
    uint8 private _status;

    /// @dev Slots 259–267: reserved to preserve the ABCI storage interface.
    uint256[9] private __reservedSpec;

    /// @dev Slot 268: the recovery generation (bits 0–63; the rest is reserved for GOV-04).
    uint64 private _recoveryGeneration;

    /// @dev Slot 269: the authenticated parent-anchor committee derivation configuration.
    bytes32 private _committeeConfigHash;

    /// @dev Slots 270–271: the latest landed L2 block.
    LandedCheckpoint private _lastCheckpoint;

    /// @dev Slots 272–274: the genesis record at the existing activation-record slots.
    Activation private _activation;

    /// @dev Slots 275–277: reserved (#22262 publication register).
    uint256[3] private __reservedPublications;

    /// @dev Slot 278: the genesis committee record commitment; no future epoch mapping.
    bytes32 private _genesisCommitteeRecordHash;

    /// @dev Slot 279: the L1 block of the epoch-0 committee snapshot.
    uint64 private _genesisCutoff;

    uint256[21] private __gap;

    // ---------------------------------------------------------------
    // Constructor
    // ---------------------------------------------------------------

    /// @notice Sets the implementation's immutable parameters.
    /// @param _config The configuration; addresses, `l2ChainId` and `maxBatchBlocks` must be
    /// non-zero.
    constructor(Config memory _config) {
        require(_config.proofVerifier != address(0), ZERO_ADDRESS());
        require(_config.signalService != address(0), ZERO_ADDRESS());
        require(_config.stakingRegistry != address(0), ZERO_ADDRESS());
        require(_config.l2ChainId != 0, ZERO_VALUE());
        require(_config.maxBatchBlocks != 0, ZERO_VALUE());

        _proofVerifier = IProofVerifier(_config.proofVerifier);
        _signalService = ISignalService(_config.signalService);
        _stakingRegistry = IEtnaStakingRegistry(_config.stakingRegistry);
        _l2ChainId = _config.l2ChainId;
        _maxBatchBlocks = _config.maxBatchBlocks;
    }

    // ---------------------------------------------------------------
    // External & Public Functions
    // ---------------------------------------------------------------

    /// @inheritdoc IEtnaInbox
    function init(address _owner, GenesisParams calldata _params) external initializer {
        require(_params.genesisBlockHash != 0 && _params.genesisStateRoot != 0, InvalidGenesis());
        require(
            _params.epochLenL2 >= _MIN_EPOCH_LEN_L2 && _params.epochLenL1 != 0, InvalidEpochLength()
        );
        require(_isValidGenesisCutoff(_params.genesisCutoff), InvalidGenesisCutoff());
        require(_params.committeeRecordHash != 0, ZeroCommitteeRecord());
        require(_params.committeeConfigHash != 0, ZeroCommitteeConfigHash());

        __Essential_init(_owner);
        uint64 l1Block = uint64(block.number);
        _status = _ETNA_ACTIVE;
        _activation = Activation({
            genesisHeight: 0,
            l1Block: l1Block,
            epochLenL2: _params.epochLenL2,
            epochLenL1: _params.epochLenL1,
            genesisBlockHash: _params.genesisBlockHash,
            genesisStateRoot: _params.genesisStateRoot
        });
        _genesisCutoff = _params.genesisCutoff;
        _genesisCommitteeRecordHash = _params.committeeRecordHash;
        _committeeConfigHash = _params.committeeConfigHash;
        _lastCheckpoint = LandedCheckpoint({ height: 0, blockHash: _params.genesisBlockHash });
        _signalService.saveCheckpoint(
            ICheckpointStore.Checkpoint({
                blockNumber: 0,
                blockHash: _params.genesisBlockHash,
                stateRoot: _params.genesisStateRoot
            })
        );

        emit EtnaInitialized(
            _params.genesisBlockHash,
            _params.genesisStateRoot,
            l1Block,
            _params.epochLenL2,
            _params.epochLenL1,
            _params.genesisCutoff,
            _params.committeeRecordHash
        );
    }

    /// @inheritdoc IEtnaInbox
    function land(LandInput calldata _input, bytes calldata _proof) external nonReentrant {
        require(_status == _ETNA_ACTIVE, EtnaNotActive());

        LandedCheckpoint memory parent = _lastCheckpoint;
        uint64 lastHeight = _input.lastHeight;
        require(lastHeight > parent.height, NoProgress());
        require(lastHeight - parent.height <= _maxBatchBlocks, BatchTooLarge());
        require(lastHeight <= type(uint48).max, HeightOverflow());

        bytes32 statementHash = _hashLandStatement(
            _recoveryGeneration,
            parent.height,
            parent.blockHash,
            _input,
            _readL1ReferenceBlockHash(_input.l1ReferenceBlockNumber),
            _readBlobHashes()
        );

        _lastCheckpoint = LandedCheckpoint({ height: lastHeight, blockHash: _input.lastBlockHash });
        _signalService.saveCheckpoint(
            ICheckpointStore.Checkpoint({
                blockNumber: uint48(lastHeight),
                blockHash: _input.lastBlockHash,
                stateRoot: _input.lastStateRoot
            })
        );
        emit BatchLanded(
            parent.height + 1,
            lastHeight,
            _input.lastBlockHash,
            _input.lastStateRoot,
            _input.l1ReferenceBlockNumber,
            statementHash,
            msg.sender
        );

        _proofVerifier.verifyProof(0, statementHash, _proof);
    }

    /// @inheritdoc IEtnaInbox
    function hashLandStatement(
        uint64 _generation,
        uint64 _parentHeight,
        bytes32 _parentHash,
        LandInput calldata _input,
        bytes32 _l1ReferenceBlockHash,
        bytes32[] calldata _blobHashes
    )
        external
        view
        returns (bytes32 statementHash_)
    {
        return _hashLandStatement(
            _generation, _parentHeight, _parentHash, _input, _l1ReferenceBlockHash, _blobHashes
        );
    }

    /// @inheritdoc IEtnaInbox
    function lastCheckpoint() external view returns (LandedCheckpoint memory) {
        return _lastCheckpoint;
    }

    /// @inheritdoc IEtnaInbox
    function committeeConfigHash() external view returns (bytes32 configHash_) {
        return _committeeConfigHash;
    }

    /// @inheritdoc IEtnaInbox
    function genesisCommitteeRecordHash() external view returns (bytes32 recordHash_) {
        return _genesisCommitteeRecordHash;
    }

    /// @inheritdoc IEtnaInbox
    function activation() external view returns (Activation memory) {
        return _activation;
    }

    /// @inheritdoc IEtnaInbox
    function genesisCutoff() external view returns (uint64) {
        return _genesisCutoff;
    }

    /// @inheritdoc IEtnaInbox
    function migrationState() external view returns (uint8) {
        return _status;
    }

    /// @inheritdoc IEtnaInbox
    function recoveryGeneration() external view returns (uint64) {
        return _recoveryGeneration;
    }

    // ---------------------------------------------------------------
    // Internal Functions
    // ---------------------------------------------------------------

    /// @dev Computes the landing statement hash; the single encoding behind `land` and
    /// `hashLandStatement`. The execution address is the Inbox proxy under delegatecall, and
    /// the registry address comes from this implementation's immutable configuration. The guest
    /// and the lander reproduce this encoding byte for byte.
    /// @param _generation The recovery generation.
    /// @param _parentHeight The height of the block the batch builds on.
    /// @param _parentHash The hash of the block the batch builds on.
    /// @param _input The batch.
    /// @param _l1ReferenceBlockHash The L1 block hash of `_input.l1ReferenceBlockNumber`.
    /// @param _blobHashes The versioned hashes of the batch's blobs.
    /// @return The landing statement hash.
    function _hashLandStatement(
        uint64 _generation,
        uint64 _parentHeight,
        bytes32 _parentHash,
        LandInput calldata _input,
        bytes32 _l1ReferenceBlockHash,
        bytes32[] memory _blobHashes
    )
        internal
        view
        returns (bytes32)
    {
        LandStatement memory statement;
        statement.domain = _LAND_STATEMENT_TAG;
        statement.l1ChainId = block.chainid;
        statement.l2ChainId = _l2ChainId;
        statement.inbox = address(this);
        statement.stakingRegistry = address(_stakingRegistry);
        statement.generation = _generation;
        statement.parentHeight = _parentHeight;
        statement.parentHash = _parentHash;
        statement.committeeConfigHash = _committeeConfigHash;
        statement.lastHeight = _input.lastHeight;
        statement.lastBlockHash = _input.lastBlockHash;
        statement.lastStateRoot = _input.lastStateRoot;
        statement.l1ReferenceBlockNumber = _input.l1ReferenceBlockNumber;
        statement.l1ReferenceBlockHash = _l1ReferenceBlockHash;
        statement.blobHashesHash = keccak256(abi.encodePacked(_blobHashes));
        return keccak256(abi.encode(statement));
    }

    // ---------------------------------------------------------------
    // Private Functions
    // ---------------------------------------------------------------

    /// @dev Returns the hash of L1 block `_l1ReferenceBlockNumber`: from `blockhash` for the last 256
    /// blocks, from the EIP-2935 history contract for the last 8191; reverts otherwise or if the
    /// hash is zero.
    /// @param _l1ReferenceBlockNumber The L1 block number.
    /// @return l1ReferenceBlockHash_ The L1 block hash.
    function _readL1ReferenceBlockHash(uint64 _l1ReferenceBlockNumber)
        private
        view
        returns (bytes32 l1ReferenceBlockHash_)
    {
        require(_l1ReferenceBlockNumber < block.number, AnchorUnavailable());
        uint256 age = block.number - _l1ReferenceBlockNumber;
        if (age <= _BLOCKHASH_WINDOW) {
            l1ReferenceBlockHash_ = blockhash(_l1ReferenceBlockNumber);
        } else {
            require(age <= _HISTORY_SERVE_WINDOW, AnchorUnavailable());
            (bool success, bytes memory data) =
                _HISTORY_STORAGE_ADDRESS.staticcall(abi.encode(uint256(_l1ReferenceBlockNumber)));
            require(success && data.length == 32, AnchorUnavailable());
            l1ReferenceBlockHash_ = abi.decode(data, (bytes32));
        }
        require(l1ReferenceBlockHash_ != 0, AnchorUnavailable());
    }

    /// @dev Returns the versioned hashes of the transaction's blobs; reverts if there are none.
    /// @return blobHashes_ `blobhash(0)`, `blobhash(1)`, ... up to the first zero.
    function _readBlobHashes() private view returns (bytes32[] memory blobHashes_) {
        uint256 count;
        while (blobhash(count) != 0) {
            ++count;
        }
        require(count != 0, BlobsRequired());

        blobHashes_ = new bytes32[](count);
        for (uint256 i; i < count; ++i) {
            blobHashes_[i] = blobhash(i);
        }
    }

    /// @dev Returns whether `_cutoff` is a past L1 block at or after the registry's first
    /// checkpoint, so the epoch-0 snapshot exists.
    /// @param _cutoff The genesis cutoff.
    /// @return Whether the cutoff is valid.
    function _isValidGenesisCutoff(uint64 _cutoff) private view returns (bool) {
        if (_cutoff >= block.number) return false;
        if (_stakingRegistry.checkpointCount() == 0) return false;
        return _stakingRegistry.checkpointAt(0).l1Block <= _cutoff;
    }

    // ---------------------------------------------------------------
    // Custom Errors
    // ---------------------------------------------------------------

    error AnchorUnavailable();
    error BatchTooLarge();
    error BlobsRequired();
    error EtnaNotActive();
    error InvalidGenesis();
    error HeightOverflow();
    error InvalidEpochLength();
    error InvalidGenesisCutoff();
    error NoProgress();
    error ZeroCommitteeRecord();
    error ZeroCommitteeConfigHash();
}
        

contracts/layer1/etna/iface/IEtnaInbox.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

/// @title IEtnaInbox
/// @notice The L1 anchor of an Etna PoS chain that starts from L2 genesis.
/// @dev A fresh proxy is initialized with the L2 block-0 hash and state root, epoch parameters,
/// and the initial committee record and derivation configuration hash. The node authenticates
/// genesis and checkpoint storage with EIP-1186 proofs. Future committees derive from the
/// committed switch-parent anchor and are never published by landing transactions.
/// @custom:security-contact security@taiko.xyz
interface IEtnaInbox {
    // ---------------------------------------------------------------
    // Structs
    // ---------------------------------------------------------------

    /// @notice The constructor parameters of the Etna Inbox implementation.
    struct Config {
        /// @notice The verifier of `land` proofs.
        address proofVerifier;
        /// @notice The L1 signal service that stores the L2 checkpoints.
        address signalService;
        /// @notice The Etna staking registry the committees derive from.
        address stakingRegistry;
        /// @notice The chain id of the Etna L2.
        uint64 l2ChainId;
        /// @notice The maximum number of L2 blocks one `land` call may cover.
        uint64 maxBatchBlocks;
    }

    /// @notice The genesis parameters of a new Etna chain.
    struct GenesisParams {
        /// @notice The hash of L2 block 0.
        bytes32 genesisBlockHash;
        /// @notice The state root of L2 block 0.
        bytes32 genesisStateRoot;
        /// @notice The epoch length in L2 blocks.
        uint64 epochLenL2;
        /// @notice The epoch length in L1 blocks.
        uint64 epochLenL1;
        /// @notice A past L1 block whose registry snapshot defines committee 0.
        uint64 genesisCutoff;
        /// @notice The initial committee record hash, computed from that snapshot.
        bytes32 committeeRecordHash;
        /// @notice The non-zero commitment to the parent-anchor committee derivation configuration.
        bytes32 committeeConfigHash;
    }

    /// @notice The genesis record; named activation for the existing node storage interface.
    /// @dev Three storage words: `genesisHeight` (bits 0–63), `l1Block` (bits 64–127),
    /// `epochLenL2` (bits 128–191) and `epochLenL1` (bits 192–255), then `genesisBlockHash`, then
    /// `genesisStateRoot`.
    struct Activation {
        /// @notice The Etna genesis height, always 0.
        uint64 genesisHeight;
        /// @notice `L1_0`: the L1 block in which the proxy was initialized.
        uint64 l1Block;
        /// @notice `L`: the epoch length in L2 blocks.
        uint64 epochLenL2;
        /// @notice The epoch length in L1 blocks.
        uint64 epochLenL1;
        /// @notice `H*`: the block hash of `B*`.
        bytes32 genesisBlockHash;
        /// @notice `S*`: the state root of `B*`.
        bytes32 genesisStateRoot;
    }

    /// @notice The latest L2 block landed on L1 (block 0 after initialization).
    /// @dev Two storage words: `height` (bits 0–63), then `blockHash`.
    struct LandedCheckpoint {
        /// @notice The L2 block height.
        uint64 height;
        /// @notice The L2 block hash.
        bytes32 blockHash;
    }

    /// @notice The batch of `land`: the L2 blocks after the last checkpoint up to `lastHeight`.
    struct LandInput {
        /// @notice The height of the batch's last block.
        uint64 lastHeight;
        /// @notice The hash of the batch's last block.
        bytes32 lastBlockHash;
        /// @notice The state root of the batch's last block.
        bytes32 lastStateRoot;
        /// @notice The L1 reference block authenticating the batch's anchor header chain.
        /// @dev Every L2 block may have its own anchor; all must be on the L1 header chain ending
        /// at this reference block, whose number is at least the last block's anchor number.
        /// A lander picks a recent L1 block, so a landing outage longer than the EIP-2935
        /// window does not strand the batch.
        uint64 l1ReferenceBlockNumber;
    }

    // ---------------------------------------------------------------
    // Events
    // ---------------------------------------------------------------

    /// @notice Emitted when a fresh Etna proxy is initialized from L2 genesis.
    /// @param genesisBlockHash The hash of L2 block 0.
    /// @param genesisStateRoot The state root of L2 block 0.
    /// @param l1Block The L1 initialization block.
    /// @param epochLenL2 The epoch length in L2 blocks.
    /// @param epochLenL1 The epoch length in L1 blocks.
    /// @param genesisCutoff The initial committee's registry snapshot block.
    /// @param committeeRecordHash The initial committee record hash.
    event EtnaInitialized(
        bytes32 genesisBlockHash,
        bytes32 genesisStateRoot,
        uint64 l1Block,
        uint64 epochLenL2,
        uint64 epochLenL1,
        uint64 genesisCutoff,
        bytes32 committeeRecordHash
    );

    /// @notice Emitted when a batch is landed.
    /// @param firstHeight The height of the batch's first block.
    /// @param lastHeight The height of the batch's last block, the new checkpoint.
    /// @param lastBlockHash The hash of the batch's last block.
    /// @param lastStateRoot The state root of the batch's last block.
    /// @param l1ReferenceBlockNumber The L1 block whose header chain holds every block's anchor.
    /// @param statementHash The landing statement hash the proof was verified against.
    /// @param lander The caller.
    event BatchLanded(
        uint64 firstHeight,
        uint64 lastHeight,
        bytes32 lastBlockHash,
        bytes32 lastStateRoot,
        uint64 l1ReferenceBlockNumber,
        bytes32 statementHash,
        address indexed lander
    );

    // ---------------------------------------------------------------
    // External Functions
    // ---------------------------------------------------------------

    /// @notice Initializes a fresh Etna proxy and its L2 block-0 checkpoint.
    /// @dev Call atomically in the proxy constructor. Requires non-zero genesis hash, state root,
    /// committee record and derivation configuration hash, epochLenL2 >= 3, epochLenL1 > 0, and
    /// a past genesis cutoff at or after the registry's first checkpoint. The SignalService must
    /// authorize this proxy as its
    /// syncer: initialization saves its block-0 checkpoint too, and any failure rolls back all
    /// state. The owner supplies the trusted genesis values and the committee record computed
    /// from the registry snapshot. The node also requires L >= D_MAX - MARGIN_V + 3.
    /// @param _owner The owner; the proxy deployer if zero.
    /// @param _params The genesis parameters.
    function init(address _owner, GenesisParams calldata _params) external;

    /// @notice Lands the L2 blocks after the last checkpoint up to `_input.lastHeight`.
    /// @dev Permissionless. Requires active status, progress, at most `maxBatchBlocks` blocks,
    /// and a last height at or below `type(uint48).max`. The reference is a past L1 block with
    /// a non-zero hash available through blockhash (256 blocks) or EIP-2935 (8191 blocks).
    /// At least one blob is required, and every actual transaction blob hash is bound in order.
    /// Saves the terminal checkpoint in the Inbox and SignalService, emits BatchLanded, then
    /// verifies the V5 statement with proposal age 0; verifier failure rolls back every write.
    /// No future committee record is an input or output of landing.
    ///
    /// A valid Etna proof must authenticate every Inbox/registry account and storage proof under
    /// the respective bound address and authenticated L1 state root. It must open the stored
    /// committeeConfigHash using the exact nine-word encoding (288 bytes):
    /// abi.encode(bytes32("ETNA_PARENT_ANCHOR_V1"), uint256(l2ChainId), address(stakingRegistry),
    /// uint256(vpUnit), uint256(sMin), uint64(nMax), uint64(heartbeatWindow), uint64(2), uint8(1)).
    /// The final words bind heartbeat lookahead 2 and retained membership algorithm version 1.
    /// Authenticate the genesis schedule and explicit genesisCutoff from Inbox storage.
    /// Committee 0 opens the plain slot-278 bootstrap record at genesisCutoff (slot 279).
    ///
    /// For t >= 1, H(t) = 1 + t * epochLenL2, S(t) = H(t) - 2 and D(t) = H(t) - 3, with
    /// checked arithmetic. At S(t), derive the incoming set at exactly the committed parent's
    /// anchor number, under that parent's authenticated L1 root; never the candidate's anchor.
    /// Authenticate complete registry entries/count/root and evaluate active/exit eligibility at
    /// that snapshot number. Preserve effective stake, earliest eligible bondId per pubkey,
    /// nMax ranking, MEM-08 ordering/root, voting-power division and overflow caps. Heartbeats
    /// retain target-epoch evaluation with lookahead 2 and exemptions for epochs 0, 1 and 2.
    /// Non-switch blocks forbid runtime committee witnesses. No empty-set fallback is implied.
    ///
    /// For arbitrary batch starts, authenticate the checkpoint EL header against the public
    /// parent hash, then consecutive descending parentHash links through each required D(t).
    /// Read the snapshot number only from D(t)'s generation-checked Etna anchor extraData;
    /// a separate derivation hint or the checkpoint's newer anchor cannot select the set.
    /// At nonzero checkpoint heights also authenticate the preceding EL header for the base-fee
    /// grandparent timestamp. Current/next starting epochs differ by at most one; checked
    /// history bounds require at most epochLenL2 + 2 links, without replaying old transactions.
    /// A later authenticated proving root whose number covers the snapshot may prove the last
    /// immutable registry checkpoint at/before it, the successor after it (when present), array
    /// length and complete entries/root. Recompute all parent/current/pending sets. In-batch
    /// switches still require the actual committed parent's exact root and snapshot number.
    ///
    /// Apply CometBFT H+2 timing: updates returned at S(t) and persisted at Commit activate at
    /// H(t). Verify the parent certificate, every current/pending certificate and current/next
    /// validator hash across S/S+1/H and arbitrary cuts, with strictly more than 2/3 distinct
    /// signer voting power under taiko-etna-<l2ChainId>-g<generation>. Anchor progress, status,
    /// generation and back-pressure rules still apply; deterministic Finalize/replay makes no
    /// new L1 calls. Epoch-first blocks need no publication witness.
    ///
    /// Prove contiguous execution from the parent hash to the terminal hash/state root, every
    /// anchor and actual proving L1 root on the header chain ending at the reference hash, and
    /// block data in the bound blobs. A batch may start/end at any valid height without a previous
    /// batch's committee output. Envelope version 3 and journal schema 3 reject former V2/V4
    /// histories/jobs; never discard or replace a signed nonce. The verifier must pin a guest
    /// enforcing these V5 rules. Dummy proof 0x00 is for development only; no real guest exists
    /// here and the dummy verifier does not establish consensus validity or ZK soundness.
    /// @param _input The four-field batch terminal checkpoint and reference block.
    /// @param _proof The proof of the V5 landing statement.
    function land(LandInput calldata _input, bytes calldata _proof) external;

    /// @notice Encodes the V5 landing statement for supplied batch public inputs.
    /// @dev Fifteen static ABI words (480 bytes): bytes32("TAIKO_ETNA_LAND_V5"), block.chainid,
    /// l2ChainId, address(this), address(stakingRegistry), _generation, _parentHeight, _parentHash,
    /// committeeConfigHash, lastHeight, lastBlockHash, lastStateRoot, l1ReferenceBlockNumber,
    /// _l1ReferenceBlockHash, keccak256(abi.encodePacked(_blobHashes)). Chain id is uint256;
    /// generation/heights are uint64, identities address and hashes bytes32. Identities and the
    /// config hash are read internally; call through the Inbox proxy to bind its address.
    /// This helper does not authenticate supplied batch values. land reads the stored parent
    /// and generation, resolves the reference hash and reads the actual transaction blob hashes.
    /// @param _generation The recovery generation.
    /// @param _parentHeight The parent checkpoint height.
    /// @param _parentHash The parent checkpoint block hash.
    /// @param _input The four-field batch.
    /// @param _l1ReferenceBlockHash The hash of `_input.l1ReferenceBlockNumber`.
    /// @param _blobHashes The versioned blob hashes in transaction order.
    /// @return statementHash_ The V5 statement hash.
    function hashLandStatement(
        uint64 _generation,
        uint64 _parentHeight,
        bytes32 _parentHash,
        LandInput calldata _input,
        bytes32 _l1ReferenceBlockHash,
        bytes32[] calldata _blobHashes
    )
        external
        view
        returns (bytes32 statementHash_);

    /// @notice Returns the latest landed L2 block.
    /// @dev The initialized checkpoint is L2 block 0.
    /// @return The latest landed checkpoint; zero before initialization.
    function lastCheckpoint() external view returns (LandedCheckpoint memory);

    /// @notice Returns the authenticated committee derivation configuration commitment.
    /// @dev Stored at slot 269; installed once from the trusted genesis deployment input.
    /// @return configHash_ The configuration hash; zero before initialization.
    function committeeConfigHash() external view returns (bytes32 configHash_);

    /// @notice Returns the initial committee record commitment.
    /// @dev Stored directly at slot 278; no future epoch committee mapping exists.
    /// @return recordHash_ The genesis committee record hash; zero before initialization.
    function genesisCommitteeRecordHash() external view returns (bytes32 recordHash_);

    /// @notice Returns the genesis record at the existing activation-record slots.
    /// @dev The schedule and hashes are installed once during initialization.
    /// @return The genesis record; zero before initialization.
    function activation() external view returns (Activation memory);

    /// @notice Returns the L1 block of the epoch-0 committee snapshot.
    /// @dev Committee 0 alone uses this explicit snapshot; runtime sets use switch-parent anchors.
    /// @return The genesis cutoff; zero before initialization.
    function genesisCutoff() external view returns (uint64);

    /// @notice Returns the status word consumed by the existing ABCI node.
    /// @dev The name is retained for node compatibility; there is no migration state machine.
    /// @return 3 after initialization, 0 before initialization.
    function migrationState() external view returns (uint8);

    /// @notice Returns the recovery generation bound into every landing statement.
    /// @dev Stays 0 until stall recovery (GOV-04) exists.
    /// @return The recovery generation.
    function recoveryGeneration() external view returns (uint64);
}
          

contracts/layer1/etna/iface/IEtnaStakingRegistry.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

/// @title IEtnaStakingRegistry
/// @notice The TAIKO staking registry the Etna PoS node derives its committees from.
/// @dev Validators register an Ed25519 consensus key with a TAIKO stake, heartbeat once per
/// heartbeat window, request an exit and withdraw after the withdrawal delay. Entries are
/// append-only and indexed by bond id. Every L1 block that changes an entry ends with one
/// checkpoint holding the entry count and the entries Merkle root at the end of that block.
///
/// The node reads `checkpoints` and `entries` straight from storage with EIP-1186 proofs, so the
/// field order and packing of both structs, and their ERC-7201 location, are part of the
/// node-facing layout (taiko-client-rs `crates/abci/src/l1/layout.rs`).
/// @custom:security-contact security@taiko.xyz
interface IEtnaStakingRegistry {
    // ---------------------------------------------------------------
    // Structs
    // ---------------------------------------------------------------

    /// @notice The registry as it stands at the end of one L1 block that changed an entry.
    /// @dev Two storage words: `l1Block` (bits 0–63) and `count` (bits 64–95), then
    /// `entriesRoot`.
    struct Checkpoint {
        /// @notice The L1 block whose entry changes this checkpoint captures.
        uint64 l1Block;
        /// @notice The number of entries (exited ones included) at the end of `l1Block`.
        uint32 count;
        /// @notice The entries Merkle root over the first `count` entries.
        bytes32 entriesRoot;
    }

    /// @notice One registration, indexed by its bond id.
    /// @dev Three storage words: `pubkey`, `effStake`, then `activeFromL1` (bits 0–63),
    /// `exitEffectiveL1` (bits 64–127), `lastHeartbeatAt` (bits 128–191) and
    /// `lastHeartbeatSeq` (bits 192–255).
    struct Entry {
        /// @notice The Ed25519 consensus public key.
        bytes32 pubkey;
        /// @notice The effective stake in TAIKO base units.
        uint256 effStake;
        /// @notice The first L1 block at which the entry may be selected.
        uint64 activeFromL1;
        /// @notice The L1 block at which the exit takes effect; `type(uint64).max` if none was
        /// requested.
        uint64 exitEffectiveL1;
        /// @notice The start L1 block of the heartbeat window of the last accepted heartbeat
        /// (MEM-13(2b)); 0 until the first heartbeat (registration is not one).
        uint64 lastHeartbeatAt;
        /// @notice The number of accepted heartbeats; 0 means none. A first heartbeat in window
        /// 0 leaves `lastHeartbeatAt` at 0, so this, not `lastHeartbeatAt`, tells whether the
        /// entry has a heartbeat (MEM-13(3)).
        uint64 lastHeartbeatSeq;
    }

    // ---------------------------------------------------------------
    // Events
    // ---------------------------------------------------------------

    /// @notice Emitted when a validator registers.
    /// @param bondId The new entry's bond id.
    /// @param owner The bond owner (the caller).
    /// @param pubkey The Ed25519 consensus public key.
    /// @param amount The TAIKO stake pulled from the owner.
    /// @param activeFromL1 The first L1 block at which the entry may be selected.
    event Registered(
        uint256 indexed bondId,
        address indexed owner,
        bytes32 pubkey,
        uint256 amount,
        uint64 activeFromL1
    );

    /// @notice Emitted when a heartbeat is accepted.
    /// @param bondId The entry's bond id.
    /// @param windowStart The start L1 block of the heartbeat window, now the entry's
    /// `lastHeartbeatAt`.
    /// @param seq The entry's new `lastHeartbeatSeq`, the number of heartbeats accepted so far.
    event HeartbeatRecorded(uint256 indexed bondId, uint64 windowStart, uint64 seq);

    /// @notice Emitted when the bond owner requests an exit.
    /// @param bondId The entry's bond id.
    /// @param exitEffectiveL1 The L1 block at which the exit takes effect.
    event ExitRequested(uint256 indexed bondId, uint64 exitEffectiveL1);

    /// @notice Emitted when an exited entry's stake is withdrawn.
    /// @param bondId The entry's bond id.
    /// @param to The recipient of the stake.
    /// @param amount The TAIKO amount transferred.
    event StakeWithdrawn(uint256 indexed bondId, address indexed to, uint256 amount);

    /// @notice Emitted when the current block's checkpoint is appended or overwritten.
    /// @param index The checkpoint's index.
    /// @param l1Block The L1 block the checkpoint captures (the current block).
    /// @param count The number of entries at this point of the block.
    /// @param entriesRoot The entries Merkle root at this point of the block.
    event CheckpointWritten(
        uint256 indexed index, uint64 l1Block, uint32 count, bytes32 entriesRoot
    );

    // ---------------------------------------------------------------
    // External Functions
    // ---------------------------------------------------------------

    /// @notice Registers `_pubkey` with a stake of `_amount` TAIKO pulled from the caller, who
    /// becomes the bond owner.
    /// @dev Reverts if `_amount` is below the minimum stake, `_pubkey` is zero, the registry
    /// holds `MAX_ENTRIES` entries, or another entry holds `_pubkey` and its exit is not yet
    /// effective. The entry becomes active `activationDelay` blocks later, has no exit and no
    /// heartbeat (`lastHeartbeatAt = 0`, `lastHeartbeatSeq = 0`). Writes the current block's
    /// checkpoint.
    /// @param _pubkey The Ed25519 consensus public key.
    /// @param _amount The TAIKO stake; the caller must have approved it.
    /// @return bondId_ The new entry's bond id (its index).
    function register(bytes32 _pubkey, uint256 _amount) external returns (uint256 bondId_);

    /// @notice Records a heartbeat for `_bondId` in the current heartbeat window.
    /// @dev Only the bond owner, and only before the exit takes effect. With
    /// `windowStart = floor(block.number / heartbeatWindow) * heartbeatWindow`, the heartbeat
    /// is accepted if the entry has none yet (`lastHeartbeatSeq == 0`) or `windowStart` exceeds
    /// `lastHeartbeatAt`: at most one heartbeat per window, and `lastHeartbeatAt` never
    /// decreases. It then sets `lastHeartbeatAt = windowStart`, increments `lastHeartbeatSeq`
    /// and writes the current block's checkpoint.
    ///
    /// A first heartbeat in window 0 is valid and leaves `lastHeartbeatAt` at 0, so
    /// `lastHeartbeatAt` alone cannot tell "heartbeat in window 0" from "no heartbeat". The
    /// sequence is MEM-13(3)'s "has a heartbeat" guard: the node counts an entry as live only
    /// if `lastHeartbeatSeq > 0 && lastHeartbeatAt >= floor`, where `floor` is the start of
    /// the oldest window it still accepts.
    ///
    /// The bond owner's address heartbeats directly; MEM-13's ECDSA heartbeat key and relayed
    /// signed heartbeats are a follow-up.
    /// @param _bondId The entry's bond id.
    function heartbeat(uint256 _bondId) external;

    /// @notice Requests the exit of `_bondId`.
    /// @dev Only the bond owner, once. The exit takes effect at
    /// `max(block.number, activeFromL1) + exitDelay`. Writes the current block's checkpoint.
    /// @param _bondId The entry's bond id.
    function requestExit(uint256 _bondId) external;

    /// @notice Transfers the stake of `_bondId` to `_to`.
    /// @dev Only the bond owner, once, and only from `exitEffectiveL1 + withdrawalDelay` on. The
    /// entry itself is left unchanged, so no checkpoint is written.
    /// @param _bondId The entry's bond id.
    /// @param _to The recipient of the stake.
    function withdraw(uint256 _bondId, address _to) external;

    /// @notice Returns the number of checkpoints.
    /// @return The number of checkpoints.
    function checkpointCount() external view returns (uint256);

    /// @notice Returns checkpoint `_index`; reverts if it does not exist.
    /// @param _index The checkpoint index.
    /// @return The checkpoint.
    function checkpointAt(uint256 _index) external view returns (Checkpoint memory);

    /// @notice Returns the number of entries (exited ones included), which is the next bond id.
    /// @return The number of entries.
    function entryCount() external view returns (uint256);

    /// @notice Returns entry `_bondId`; reverts if it does not exist.
    /// @param _bondId The bond id.
    /// @return The entry.
    function entryAt(uint256 _bondId) external view returns (Entry memory);

    /// @notice Returns the entries Merkle root over all current entries.
    /// @dev Equals the latest checkpoint's `entriesRoot` (`bytes32(0)` before the first entry).
    /// @return The entries Merkle root.
    function entriesRoot() external view returns (bytes32);

    /// @notice Returns the owner of `_bondId`, or `address(0)` if it does not exist.
    /// @param _bondId The bond id.
    /// @return The bond owner.
    function bondOwnerOf(uint256 _bondId) external view returns (address);

    /// @notice Returns whether the stake of `_bondId` was withdrawn (false if it does not
    /// exist).
    /// @param _bondId The bond id.
    /// @return Whether the stake was withdrawn.
    function isWithdrawn(uint256 _bondId) external view returns (bool);
}
          

contracts/layer1/etna/impl/EtnaInbox_Layout.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

/// @title EtnaInboxLayout
/// @notice Storage layout documentation for EtnaInbox
/// @dev This file is auto-generated by gen-layouts.sh. DO NOT EDIT MANUALLY.
/// @custom:security-contact security@taiko.xyz

// solhint-disable max-line-length
//   _initialized                   | uint8                                              | Slot: 0    | Offset: 0    | Bytes: 1
//   _initializing                  | bool                                               | Slot: 0    | Offset: 1    | Bytes: 1
//   __gap                          | uint256[50]                                        | Slot: 1    | Offset: 0    | Bytes: 1600
//   _owner                         | address                                            | Slot: 51   | Offset: 0    | Bytes: 20
//   __gap                          | uint256[49]                                        | Slot: 52   | Offset: 0    | Bytes: 1568
//   _pendingOwner                  | address                                            | Slot: 101  | Offset: 0    | Bytes: 20
//   __gap                          | uint256[49]                                        | Slot: 102  | Offset: 0    | Bytes: 1568
//   __gapFromOldAddressResolver    | uint256[50]                                        | Slot: 151  | Offset: 0    | Bytes: 1600
//   __reentry                      | uint8                                              | Slot: 201  | Offset: 0    | Bytes: 1
//   __paused                       | uint8                                              | Slot: 201  | Offset: 1    | Bytes: 1
//   __gap                          | uint256[49]                                        | Slot: 202  | Offset: 0    | Bytes: 1568
//   __reservedBeforeStatus         | uint256[7]                                         | Slot: 251  | Offset: 0    | Bytes: 224
//   _status                        | uint8                                              | Slot: 258  | Offset: 0    | Bytes: 1
//   __reservedSpec                 | uint256[9]                                         | Slot: 259  | Offset: 0    | Bytes: 288
//   _recoveryGeneration            | uint64                                             | Slot: 268  | Offset: 0    | Bytes: 8
//   _committeeConfigHash           | bytes32                                            | Slot: 269  | Offset: 0    | Bytes: 32
//   _lastCheckpoint                | struct IEtnaInbox.LandedCheckpoint                 | Slot: 270  | Offset: 0    | Bytes: 64
//   _activation                    | struct IEtnaInbox.Activation                       | Slot: 272  | Offset: 0    | Bytes: 96
//   __reservedPublications         | uint256[3]                                         | Slot: 275  | Offset: 0    | Bytes: 96
//   _genesisCommitteeRecordHash    | bytes32                                            | Slot: 278  | Offset: 0    | Bytes: 32
//   _genesisCutoff                 | uint64                                             | Slot: 279  | Offset: 0    | Bytes: 8
//   __gap                          | uint256[21]                                        | Slot: 280  | Offset: 0    | Bytes: 672
          

contracts/layer1/verifiers/IProofVerifier.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

/// @title IProofVerifier
/// @notice Interface for verifying validity proofs for state transitions
/// @custom:security-contact security@taiko.xyz
interface IProofVerifier {
    /// @notice Verifies a validity proof for a state transition
    /// @dev This function must revert if the proof is invalid
    /// @param _proposalAge The age in seconds of the proposal being proven. Only set for
    ///        single-proposal proofs (calculated as block.timestamp - proposal.timestamp).
    ///        For multi-proposal batches, this is always 0, meaning "not applicable".
    ///        Verifiers should interpret _proposalAge == 0 as "not applicable" rather than
    ///        "instant proof". This parameter enables age-based verification logic, such as
    ///        detecting and handling prover-killer proposals differently.
    /// @param _commitmentHash Hash of the last proposal hash and commitment data
    /// @param _proof The proof data
    function verifyProof(
        uint256 _proposalAge,
        bytes32 _commitmentHash,
        bytes calldata _proof
    )
        external
        view;
}
          

contracts/shared/common/EssentialContract.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

import "./IResolver.sol";
import "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol";
import "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol";

/// @title EssentialContract
/// @custom:security-contact security@taiko.xyz
abstract contract EssentialContract is UUPSUpgradeable, Ownable2StepUpgradeable {
    // ---------------------------------------------------------------
    // Constants and Immutable Variables
    // ---------------------------------------------------------------
    uint8 internal constant _FALSE = 1;
    uint8 internal constant _TRUE = 2;

    /// @dev Transient-storage slot for the reentry lock: keccak256("ownerUUPS.reentry_slot") + 1.
    /// The addition prevents collisions with EIP-1967-style slots (derived as keccak256(x) - 1)
    /// and SignalService slots (derived directly as keccak256(x)).
    bytes32 private constant _REENTRY_SLOT =
        0xa5054f728453d3dbe953bdc43e4d0cb97e662ea32d7958190f3dc2da31d9721b;

    address internal immutable __resolver;

    // ---------------------------------------------------------------
    // State Variables
    // ---------------------------------------------------------------

    uint256[50] private __gapFromOldAddressResolver;

    /// @dev Slot 1. __reentry is deprecated: the reentry lock lives in transient storage
    /// (_REENTRY_SLOT); the storage slot is retained only for layout compatibility.
    uint8 private __reentry;
    uint8 internal __paused;

    uint256[49] private __gap;

    // ---------------------------------------------------------------
    // Events
    // ---------------------------------------------------------------

    /// @notice Emitted when the contract is paused.
    /// @param account The account that paused the contract.
    event Paused(address account);

    /// @notice Emitted when the contract is unpaused.
    /// @param account The account that unpaused the contract.
    event Unpaused(address account);

    error INVALID_PAUSE_STATUS();
    error FUNC_NOT_IMPLEMENTED();
    error REENTRANT_CALL();
    error ACCESS_DENIED();
    error ZERO_ADDRESS();
    error ZERO_VALUE();

    // ---------------------------------------------------------------
    // Modifiers
    // ---------------------------------------------------------------

    /// @dev Modifier that ensures the caller is either the owner or a specified address.
    /// @param _addr The address to check against.
    modifier onlyFromOwnerOr(address _addr) {
        _checkOwnerOr(_addr);
        _;
    }

    /// @dev Modifier that reverts the function call, indicating it is not implemented.
    modifier notImplemented() {
        revert FUNC_NOT_IMPLEMENTED();
        _;
    }

    /// @dev Modifier that prevents reentrant calls to a function.
    modifier nonReentrant() {
        _checkReentrancy();
        _storeReentryLock(_TRUE);
        _;
        _storeReentryLock(_FALSE);
    }

    /// @dev Modifier that allows function execution only when the contract is paused.
    modifier whenPaused() {
        _checkPaused();
        _;
    }

    /// @dev Modifier that allows function execution only when the contract is not paused.
    modifier whenNotPaused() {
        _checkNotPaused();
        _;
    }

    /// @dev Modifier that ensures the provided address is not the zero address.
    /// @param _addr The address to check.
    modifier nonZeroAddr(address _addr) {
        _checkNonZeroAddr(_addr);
        _;
    }

    /// @dev Modifier that ensures the provided value is not zero.
    /// @param _value The value to check.
    modifier nonZeroValue(uint256 _value) {
        _checkNonZeroValue(_value);
        _;
    }

    /// @dev Modifier that ensures the provided bytes32 value is not zero.
    /// @param _value The bytes32 value to check.
    modifier nonZeroBytes32(bytes32 _value) {
        _checkNonZeroBytes32(_value);
        _;
    }

    /// @dev Modifier that ensures the caller is either of the two specified addresses.
    /// @param _addr1 The first address to check against.
    /// @param _addr2 The second address to check against.
    modifier onlyFromEither(address _addr1, address _addr2) {
        _checkFromEither(_addr1, _addr2);
        _;
    }

    /// @dev Modifier that ensures the caller is the specified address.
    /// @param _addr The address to check against.
    modifier onlyFrom(address _addr) {
        _checkFrom(_addr);
        _;
    }

    /// @dev Modifier that ensures the caller is the specified address.
    /// @param _addr The address to check against.
    modifier onlyFromOptional(address _addr) {
        _checkFromOptional(_addr);
        _;
    }

    // ---------------------------------------------------------------
    // Constructor
    // ---------------------------------------------------------------

    constructor() {
        _disableInitializers();
    }

    // ---------------------------------------------------------------
    // External & Public Functions
    // ---------------------------------------------------------------

    /// @notice Pauses the contract.
    function pause() public whenNotPaused {
        _pause();
        emit Paused(msg.sender);
        // We call the authorize function here to avoid:
        // Warning (5740): Unreachable code.
        _authorizePause(msg.sender, true);
    }

    /// @notice Unpauses the contract.
    function unpause() public whenPaused {
        _unpause();
        emit Unpaused(msg.sender);
        // We call the authorize function here to avoid:
        // Warning (5740): Unreachable code.
        _authorizePause(msg.sender, false);
    }

    function impl() public view returns (address) {
        return _getImplementation();
    }

    /// @notice Returns true if the contract is paused, and false otherwise.
    /// @return true if paused, false otherwise.
    function paused() public view virtual returns (bool) {
        return __paused == _TRUE;
    }

    function inNonReentrant() public view returns (bool) {
        return _loadReentryLock() == _TRUE;
    }

    /// @notice Returns the address of this contract.
    /// @return The address of this contract.
    function resolver() public view virtual returns (address) {
        return __resolver;
    }

    // ---------------------------------------------------------------
    // Internal Functions
    // ---------------------------------------------------------------

    /// @notice Initializes the contract.
    /// @param _owner The owner of this contract. msg.sender will be used if this value is zero.
    function __Essential_init(address _owner) internal virtual onlyInitializing {
        __Context_init();
        _transferOwnership(_owner == address(0) ? msg.sender : _owner);
        __paused = _FALSE;
    }

    function _pause() internal virtual {
        __paused = _TRUE;
    }

    function _unpause() internal virtual {
        __paused = _FALSE;
    }

    function _authorizeUpgrade(address) internal virtual override onlyOwner { }

    function _authorizePause(address, bool) internal virtual onlyOwner { }

    // Stores the reentry lock in transient storage (EIP-1153). This is deliberately not virtual:
    // L1 and L2 run the same EVM version, so the transient-storage lock is the single reentrancy
    // guard implementation.
    function _storeReentryLock(uint8 _reentry) internal {
        assembly {
            tstore(_REENTRY_SLOT, _reentry)
        }
    }

    // Loads the reentry lock
    function _loadReentryLock() internal view returns (uint8 reentry_) {
        assembly {
            reentry_ := tload(_REENTRY_SLOT)
        }
    }

    // ---------------------------------------------------------------
    // Private Functions
    // ---------------------------------------------------------------

    function _checkOwnerOr(address _addr) private view {
        require(msg.sender == owner() || msg.sender == _addr, ACCESS_DENIED());
    }

    function _checkReentrancy() private view {
        require(_loadReentryLock() != _TRUE, REENTRANT_CALL());
    }

    function _checkPaused() private view {
        require(paused(), INVALID_PAUSE_STATUS());
    }

    function _checkNotPaused() private view {
        require(!paused(), INVALID_PAUSE_STATUS());
    }

    function _checkNonZeroAddr(address _addr) private pure {
        require(_addr != address(0), ZERO_ADDRESS());
    }

    function _checkNonZeroValue(uint256 _value) private pure {
        require(_value != 0, ZERO_VALUE());
    }

    function _checkNonZeroBytes32(bytes32 _value) private pure {
        require(_value != 0, ZERO_VALUE());
    }

    function _checkFromEither(address _addr1, address _addr2) private view {
        require(msg.sender == _addr1 || msg.sender == _addr2, ACCESS_DENIED());
    }

    function _checkFrom(address _addr) private view {
        require(msg.sender == _addr, ACCESS_DENIED());
    }

    function _checkFromOptional(address _addr) private view {
        require(_addr == address(0) || msg.sender == _addr, ACCESS_DENIED());
    }
}
          

contracts/shared/common/IResolver.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

/// @title IResolver
/// @notice This contract acts as a bridge for name-to-address resolution.
/// @custom:security-contact security@taiko.xyz
interface IResolver {
    error RESOLVED_TO_ZERO_ADDRESS();

    /// @notice Resolves a name to its address deployed on a specified chain.
    /// @param _chainId The chainId of interest.
    /// @param _name Name whose address is to be resolved.
    /// @param _allowZeroAddress If set to true, does not throw if the resolved
    /// address is `address(0)`.
    /// @return Address associated with the given name on the specified
    /// chain.
    function resolve(
        uint256 _chainId,
        bytes32 _name,
        bool _allowZeroAddress
    )
        external
        view
        returns (address);
}
          

contracts/shared/signal/ICheckpointStore.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

/// @title ICheckpointStore
/// @notice Interface for storing and retrieving checkpoints
/// @custom:security-contact security@taiko.xyz
interface ICheckpointStore {
    // ---------------------------------------------------------------
    // Structs
    // ---------------------------------------------------------------

    /// @notice Represents a synced checkpoint
    struct Checkpoint {
        /// @notice The block number associated with the checkpoint.
        uint48 blockNumber;
        /// @notice The block hash for the referenced block.
        bytes32 blockHash;
        /// @notice The state root for the referenced block.
        bytes32 stateRoot;
    }

    // ---------------------------------------------------------------
    // Events
    // ---------------------------------------------------------------

    /// @notice Emitted when a checkpoint is saved
    /// @param blockNumber The block number
    /// @param blockHash The block hash
    /// @param stateRoot The state root
    event CheckpointSaved(uint48 indexed blockNumber, bytes32 blockHash, bytes32 stateRoot);

    // ---------------------------------------------------------------
    // External Functions
    // ---------------------------------------------------------------

    /// @notice Saves a checkpoint
    /// @param _checkpoint The checkpoint data to persist
    function saveCheckpoint(Checkpoint calldata _checkpoint) external;

    /// @notice Gets a checkpoint by its block number
    /// @param _blockNumber The block number associated with the checkpoint
    /// @return _ The checkpoint
    function getCheckpoint(uint48 _blockNumber) external view returns (Checkpoint memory);
}
          

contracts/shared/signal/ISignalService.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import "./ICheckpointStore.sol";

/// @title ISignalService
/// @notice The SignalService contract serves as a secure cross-chain message
/// passing system. It defines methods for sending and verifying signals with
/// merkle proofs. The trust assumption is that the target chain has secure
/// access to the merkle root (such as Taiko injects it in the anchor
/// transaction). With this, verifying a signal is reduced to simply verifying
/// a merkle proof.
/// @custom:security-contact security@taiko.xyz
interface ISignalService is ICheckpointStore {
    /// @dev DEPRECATED
    /// @dev Caching is no longer supported
    enum CacheOption {
        CACHE_NOTHING,
        CACHE_SIGNAL_ROOT,
        CACHE_STATE_ROOT,
        CACHE_BOTH
    }

    struct HopProof {
        /// @notice This hop's destination chain ID. If there is a next hop, this ID is the next
        /// hop's source chain ID.
        uint64 chainId;
        /// @notice The ID of a source chain block whose state root has been synced to the hop's
        /// destination chain.
        /// Note that this block ID must be greater than or equal to the block ID where the signal
        /// was sent on the source chain.
        uint64 blockId;
        /// @notice The state root or signal root of the source chain at the above blockId. This
        /// value has been synced to the destination chain.
        /// @dev To get both the blockId and the rootHash, apps should subscribe to the
        /// ChainDataSynced event or query `topBlockId` first using the source chain's ID and
        /// LibStrings.H_STATE_ROOT to get the most recent block ID synced, then call
        /// `getSyncedChainData` to read the synchronized data.
        bytes32 rootHash;
        /// @notice Options to cache either the state roots or signal roots of middle-hops to the
        /// current chain.
        /// @dev DEPRECATED - this value will be ignored
        CacheOption cacheOption;
        /// @notice The signal service's account proof. If this value is empty, then `rootHash` will
        /// be used as the signal root, otherwise, `rootHash` will be used as the state root.
        bytes[] accountProof;
        /// @notice The signal service's storage proof.
        bytes[] storageProof;
    }

    /// @notice Emitted when a signal is sent.
    /// @param app The address that initiated the signal.
    /// @param signal The signal (message) that was sent.
    /// @param slot The location in storage where this signal is stored.
    /// @param value The value of the signal.
    event SignalSent(address app, bytes32 signal, bytes32 slot, bytes32 value);

    /// @notice Send a signal (message) by setting the storage slot to the same value as the signal
    /// itself.
    /// @param _signal The signal (message) to send.
    /// @return slot_ The location in storage where this signal is stored.
    function sendSignal(bytes32 _signal) external returns (bytes32 slot_);

    /// @notice Checks whether a signal has been received on the target chain and caches the result if successful.
    /// @param _chainId The identifier for the source chain from which the
    /// signal originated.
    /// @param _app The address that initiated the signal.
    /// @param _signal The signal (message) to send.
    /// @param _proof Merkle proof that the signal was persisted on the
    /// source chain. If this proof is empty, then we check if this signal has been marked as
    /// received by TaikoL2.
    /// @return numCacheOps_ The number of newly cached items.
    function proveSignalReceived(
        uint64 _chainId,
        address _app,
        bytes32 _signal,
        bytes calldata _proof
    )
        external
        returns (uint256 numCacheOps_);

    /// @notice Verifies if a signal has been received on the target chain.
    /// This is the "readonly" version of proveSignalReceived.
    /// @param _chainId The identifier for the source chain from which the
    /// signal originated.
    /// @param _app The address that initiated the signal.
    /// @param _signal The signal (message) to send.
    /// @param _proof Merkle proof that the signal was persisted on the
    /// source chain. If this proof is empty, then we check if this signal has been marked as
    /// received by TaikoL2.
    function verifySignalReceived(
        uint64 _chainId,
        address _app,
        bytes32 _signal,
        bytes calldata _proof
    )
        external
        view;

    /// @notice Verifies if a particular signal has already been sent.
    /// @param _app The address that initiated the signal.
    /// @param _signal The signal (message) that was sent.
    /// @return true if the signal has been sent, otherwise false.
    function isSignalSent(address _app, bytes32 _signal) external view returns (bool);

    /// @notice Verifies if a particular signal has already been sent.
    /// @param _signalSlot The location in storage where this signal is stored.
    function isSignalSent(bytes32 _signalSlot) external view returns (bool);
}
          

node_modules/@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)

pragma solidity ^0.8.0;

import "./OwnableUpgradeable.sol";
import {Initializable} from "../proxy/utils/Initializable.sol";

/**
 * @dev Contract module which provides access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership} and {acceptOwnership}.
 *
 * This module is used through inheritance. It will make available all functions
 * from parent (Ownable).
 */
abstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {
    address private _pendingOwner;

    event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);

    function __Ownable2Step_init() internal onlyInitializing {
        __Ownable_init_unchained();
    }

    function __Ownable2Step_init_unchained() internal onlyInitializing {
    }
    /**
     * @dev Returns the address of the pending owner.
     */
    function pendingOwner() public view virtual returns (address) {
        return _pendingOwner;
    }

    /**
     * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual override onlyOwner {
        _pendingOwner = newOwner;
        emit OwnershipTransferStarted(owner(), newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual override {
        delete _pendingOwner;
        super._transferOwnership(newOwner);
    }

    /**
     * @dev The new owner accepts the ownership transfer.
     */
    function acceptOwnership() public virtual {
        address sender = _msgSender();
        require(pendingOwner() == sender, "Ownable2Step: caller is not the new owner");
        _transferOwnership(sender);
    }

    /**
     * @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[49] private __gap;
}
          

node_modules/@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/ContextUpgradeable.sol";
import {Initializable} from "../proxy/utils/Initializable.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    function __Ownable_init() internal onlyInitializing {
        __Ownable_init_unchained();
    }

    function __Ownable_init_unchained() internal onlyInitializing {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }

    /**
     * @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[49] private __gap;
}
          

node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)

pragma solidity ^0.8.2;

import "../../utils/AddressUpgradeable.sol";

/**
 * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
 * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
 * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
 * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
 *
 * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
 * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
 * case an upgrade adds a module that needs to be initialized.
 *
 * For example:
 *
 * [.hljs-theme-light.nopadding]
 * ```solidity
 * contract MyToken is ERC20Upgradeable {
 *     function initialize() initializer public {
 *         __ERC20_init("MyToken", "MTK");
 *     }
 * }
 *
 * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
 *     function initializeV2() reinitializer(2) public {
 *         __ERC20Permit_init("MyToken");
 *     }
 * }
 * ```
 *
 * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
 * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
 *
 * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
 * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
 *
 * [CAUTION]
 * ====
 * Avoid leaving a contract uninitialized.
 *
 * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
 * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
 * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
 *
 * [.hljs-theme-light.nopadding]
 * ```
 * /// @custom:oz-upgrades-unsafe-allow constructor
 * constructor() {
 *     _disableInitializers();
 * }
 * ```
 * ====
 */
abstract contract Initializable {
    /**
     * @dev Indicates that the contract has been initialized.
     * @custom:oz-retyped-from bool
     */
    uint8 private _initialized;

    /**
     * @dev Indicates that the contract is in the process of being initialized.
     */
    bool private _initializing;

    /**
     * @dev Triggered when the contract has been initialized or reinitialized.
     */
    event Initialized(uint8 version);

    /**
     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
     * `onlyInitializing` functions can be used to initialize parent contracts.
     *
     * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a
     * constructor.
     *
     * Emits an {Initialized} event.
     */
    modifier initializer() {
        bool isTopLevelCall = !_initializing;
        require(
            (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),
            "Initializable: contract is already initialized"
        );
        _initialized = 1;
        if (isTopLevelCall) {
            _initializing = true;
        }
        _;
        if (isTopLevelCall) {
            _initializing = false;
            emit Initialized(1);
        }
    }

    /**
     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
     * used to initialize parent contracts.
     *
     * A reinitializer may be used after the original initialization step. This is essential to configure modules that
     * are added through upgrades and that require initialization.
     *
     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
     * cannot be nested. If one is invoked in the context of another, execution will revert.
     *
     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
     * a contract, executing them in the right order is up to the developer or operator.
     *
     * WARNING: setting the version to 255 will prevent any future reinitialization.
     *
     * Emits an {Initialized} event.
     */
    modifier reinitializer(uint8 version) {
        require(!_initializing && _initialized < version, "Initializable: contract is already initialized");
        _initialized = version;
        _initializing = true;
        _;
        _initializing = false;
        emit Initialized(version);
    }

    /**
     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
     * {initializer} and {reinitializer} modifiers, directly or indirectly.
     */
    modifier onlyInitializing() {
        require(_initializing, "Initializable: contract is not initializing");
        _;
    }

    /**
     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called
     * through proxies.
     *
     * Emits an {Initialized} event the first time it is successfully executed.
     */
    function _disableInitializers() internal virtual {
        require(!_initializing, "Initializable: contract is initializing");
        if (_initialized != type(uint8).max) {
            _initialized = type(uint8).max;
            emit Initialized(type(uint8).max);
        }
    }

    /**
     * @dev Returns the highest version that has been initialized. See {reinitializer}.
     */
    function _getInitializedVersion() internal view returns (uint8) {
        return _initialized;
    }

    /**
     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
     */
    function _isInitializing() internal view returns (bool) {
        return _initializing;
    }
}
          

node_modules/@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library AddressUpgradeable {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     *
     * Furthermore, `isContract` will also return true if the target contract within
     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
     * which only has an effect at the end of a transaction.
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}
          

node_modules/@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)

pragma solidity ^0.8.0;
import {Initializable} from "../proxy/utils/Initializable.sol";

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract ContextUpgradeable is Initializable {
    function __Context_init() internal onlyInitializing {
    }

    function __Context_init_unchained() internal onlyInitializing {
    }
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }

    /**
     * @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[50] private __gap;
}
          

node_modules/@openzeppelin/contracts/interfaces/IERC1967.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol)

pragma solidity ^0.8.0;

/**
 * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.
 *
 * _Available since v4.8.3._
 */
interface IERC1967 {
    /**
     * @dev Emitted when the implementation is upgraded.
     */
    event Upgraded(address indexed implementation);

    /**
     * @dev Emitted when the admin account has changed.
     */
    event AdminChanged(address previousAdmin, address newAdmin);

    /**
     * @dev Emitted when the beacon is changed.
     */
    event BeaconUpgraded(address indexed beacon);
}
          

node_modules/@openzeppelin/contracts/interfaces/draft-IERC1822.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)

pragma solidity ^0.8.0;

/**
 * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified
 * proxy whose upgrades are fully controlled by the current implementation.
 */
interface IERC1822Proxiable {
    /**
     * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation
     * address.
     *
     * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
     * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
     * function revert if invoked through a proxy.
     */
    function proxiableUUID() external view returns (bytes32);
}
          

node_modules/@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)

pragma solidity ^0.8.2;

import "../beacon/IBeacon.sol";
import "../../interfaces/IERC1967.sol";
import "../../interfaces/draft-IERC1822.sol";
import "../../utils/Address.sol";
import "../../utils/StorageSlot.sol";

/**
 * @dev This abstract contract provides getters and event emitting update functions for
 * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.
 *
 * _Available since v4.1._
 */
abstract contract ERC1967Upgrade is IERC1967 {
    // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1
    bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;

    /**
     * @dev Storage slot with the address of the current implementation.
     * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
     * validated in the constructor.
     */
    bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;

    /**
     * @dev Returns the current implementation address.
     */
    function _getImplementation() internal view returns (address) {
        return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
    }

    /**
     * @dev Stores a new address in the EIP1967 implementation slot.
     */
    function _setImplementation(address newImplementation) private {
        require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
        StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
    }

    /**
     * @dev Perform implementation upgrade
     *
     * Emits an {Upgraded} event.
     */
    function _upgradeTo(address newImplementation) internal {
        _setImplementation(newImplementation);
        emit Upgraded(newImplementation);
    }

    /**
     * @dev Perform implementation upgrade with additional setup call.
     *
     * Emits an {Upgraded} event.
     */
    function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal {
        _upgradeTo(newImplementation);
        if (data.length > 0 || forceCall) {
            Address.functionDelegateCall(newImplementation, data);
        }
    }

    /**
     * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.
     *
     * Emits an {Upgraded} event.
     */
    function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal {
        // Upgrades from old implementations will perform a rollback test. This test requires the new
        // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing
        // this special case will break upgrade paths from old UUPS implementation to new ones.
        if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {
            _setImplementation(newImplementation);
        } else {
            try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {
                require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID");
            } catch {
                revert("ERC1967Upgrade: new implementation is not UUPS");
            }
            _upgradeToAndCall(newImplementation, data, forceCall);
        }
    }

    /**
     * @dev Storage slot with the admin of the contract.
     * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is
     * validated in the constructor.
     */
    bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;

    /**
     * @dev Returns the current admin.
     */
    function _getAdmin() internal view returns (address) {
        return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;
    }

    /**
     * @dev Stores a new address in the EIP1967 admin slot.
     */
    function _setAdmin(address newAdmin) private {
        require(newAdmin != address(0), "ERC1967: new admin is the zero address");
        StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;
    }

    /**
     * @dev Changes the admin of the proxy.
     *
     * Emits an {AdminChanged} event.
     */
    function _changeAdmin(address newAdmin) internal {
        emit AdminChanged(_getAdmin(), newAdmin);
        _setAdmin(newAdmin);
    }

    /**
     * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.
     * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.
     */
    bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;

    /**
     * @dev Returns the current beacon.
     */
    function _getBeacon() internal view returns (address) {
        return StorageSlot.getAddressSlot(_BEACON_SLOT).value;
    }

    /**
     * @dev Stores a new beacon in the EIP1967 beacon slot.
     */
    function _setBeacon(address newBeacon) private {
        require(Address.isContract(newBeacon), "ERC1967: new beacon is not a contract");
        require(
            Address.isContract(IBeacon(newBeacon).implementation()),
            "ERC1967: beacon implementation is not a contract"
        );
        StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;
    }

    /**
     * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does
     * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).
     *
     * Emits a {BeaconUpgraded} event.
     */
    function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal {
        _setBeacon(newBeacon);
        emit BeaconUpgraded(newBeacon);
        if (data.length > 0 || forceCall) {
            Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);
        }
    }
}
          

node_modules/@openzeppelin/contracts/proxy/beacon/IBeacon.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)

pragma solidity ^0.8.0;

/**
 * @dev This is the interface that {BeaconProxy} expects of its beacon.
 */
interface IBeacon {
    /**
     * @dev Must return an address that can be used as a delegate call target.
     *
     * {BeaconProxy} will check that this address is a contract.
     */
    function implementation() external view returns (address);
}
          

node_modules/@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol)

pragma solidity ^0.8.0;

import "../../interfaces/draft-IERC1822.sol";
import "../ERC1967/ERC1967Upgrade.sol";

/**
 * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an
 * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.
 *
 * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is
 * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing
 * `UUPSUpgradeable` with a custom implementation of upgrades.
 *
 * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.
 *
 * _Available since v4.1._
 */
abstract contract UUPSUpgradeable is IERC1822Proxiable, ERC1967Upgrade {
    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment
    address private immutable __self = address(this);

    /**
     * @dev Check that the execution is being performed through a delegatecall call and that the execution context is
     * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case
     * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a
     * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to
     * fail.
     */
    modifier onlyProxy() {
        require(address(this) != __self, "Function must be called through delegatecall");
        require(_getImplementation() == __self, "Function must be called through active proxy");
        _;
    }

    /**
     * @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, "UUPSUpgradeable: must not be called through delegatecall");
        _;
    }

    /**
     * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the
     * implementation. It is used to validate the implementation's compatibility when performing an upgrade.
     *
     * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
     * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
     * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.
     */
    function proxiableUUID() external view virtual override notDelegated returns (bytes32) {
        return _IMPLEMENTATION_SLOT;
    }

    /**
     * @dev Upgrade the implementation of the proxy to `newImplementation`.
     *
     * Calls {_authorizeUpgrade}.
     *
     * Emits an {Upgraded} event.
     *
     * @custom:oz-upgrades-unsafe-allow-reachable delegatecall
     */
    function upgradeTo(address newImplementation) public virtual onlyProxy {
        _authorizeUpgrade(newImplementation);
        _upgradeToAndCallUUPS(newImplementation, new bytes(0), false);
    }

    /**
     * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call
     * encoded in `data`.
     *
     * Calls {_authorizeUpgrade}.
     *
     * Emits an {Upgraded} event.
     *
     * @custom:oz-upgrades-unsafe-allow-reachable delegatecall
     */
    function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {
        _authorizeUpgrade(newImplementation);
        _upgradeToAndCallUUPS(newImplementation, data, true);
    }

    /**
     * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by
     * {upgradeTo} and {upgradeToAndCall}.
     *
     * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.
     *
     * ```solidity
     * function _authorizeUpgrade(address) internal override onlyOwner {}
     * ```
     */
    function _authorizeUpgrade(address newImplementation) internal virtual;
}
          

node_modules/@openzeppelin/contracts/utils/Address.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     *
     * Furthermore, `isContract` will also return true if the target contract within
     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
     * which only has an effect at the end of a transaction.
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}
          

node_modules/@openzeppelin/contracts/utils/StorageSlot.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)
// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.

pragma solidity ^0.8.0;

/**
 * @dev Library for reading and writing primitive types to specific storage slots.
 *
 * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
 * This library helps with reading and writing to such slots without the need for inline assembly.
 *
 * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
 *
 * Example usage to set ERC1967 implementation slot:
 * ```solidity
 * contract ERC1967 {
 *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
 *
 *     function _getImplementation() internal view returns (address) {
 *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
 *     }
 *
 *     function _setImplementation(address newImplementation) internal {
 *         require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
 *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
 *     }
 * }
 * ```
 *
 * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._
 * _Available since v4.9 for `string`, `bytes`._
 */
library StorageSlot {
    struct AddressSlot {
        address value;
    }

    struct BooleanSlot {
        bool value;
    }

    struct Bytes32Slot {
        bytes32 value;
    }

    struct Uint256Slot {
        uint256 value;
    }

    struct StringSlot {
        string value;
    }

    struct BytesSlot {
        bytes value;
    }

    /**
     * @dev Returns an `AddressSlot` with member `value` located at `slot`.
     */
    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `BooleanSlot` with member `value` located at `slot`.
     */
    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
     */
    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `Uint256Slot` with member `value` located at `slot`.
     */
    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `StringSlot` with member `value` located at `slot`.
     */
    function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `StringSlot` representation of the string storage pointer `store`.
     */
    function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := store.slot
        }
    }

    /**
     * @dev Returns an `BytesSlot` with member `value` located at `slot`.
     */
    function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
     */
    function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := store.slot
        }
    }
}
          

Compiler Settings

{"viaIR":false,"remappings":["openzeppelin/=node_modules/@openzeppelin/","@openzeppelin/=node_modules/@openzeppelin/","@openzeppelin-upgrades/contracts/=node_modules/@openzeppelin/contracts-upgradeable/","@risc0/contracts/=node_modules/risc0-ethereum/contracts/src/","@solady/=node_modules/solady/","solady/src/=node_modules/solady/src/","solady/utils/=node_modules/solady/src/utils/","solady/auth/=node_modules/solady/src/auth/","@optimism/=node_modules/optimism/","@sp1-contracts/=node_modules/sp1-contracts/contracts/src/","forge-std/=node_modules/forge-std/","@p256-verifier/contracts/=node_modules/p256-verifier/src/","@eth-fabric/urc/=node_modules/urc/src/","@automata-network/on-chain-pccs/=node_modules/@automata-network/on-chain-pccs/src/","@automata-network/automata-dcap-attestation/=node_modules/@automata-network/automata-dcap-attestation/","risc0/=node_modules/risc0-ethereum/contracts/src/","ds-test/=node_modules/ds-test/","src/=contracts/","test/=test/","script/=script/","optimism/=node_modules/optimism/","p256-verifier/=node_modules/p256-verifier/","risc0-ethereum/=node_modules/risc0-ethereum/","sp1-contracts/=node_modules/sp1-contracts/","urc/=node_modules/urc/"],"outputSelection":{"*":{"*":["*"],"":["*"]}},"optimizer":{"runs":200,"enabled":true},"metadata":{"useLiteralContent":false,"bytecodeHash":"ipfs","appendCBOR":true},"libraries":{},"evmVersion":"prague"}
              

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"tuple","name":"_config","internalType":"struct IEtnaInbox.Config","components":[{"type":"address","name":"proofVerifier","internalType":"address"},{"type":"address","name":"signalService","internalType":"address"},{"type":"address","name":"stakingRegistry","internalType":"address"},{"type":"uint64","name":"l2ChainId","internalType":"uint64"},{"type":"uint64","name":"maxBatchBlocks","internalType":"uint64"}]}]},{"type":"error","name":"ACCESS_DENIED","inputs":[]},{"type":"error","name":"AnchorUnavailable","inputs":[]},{"type":"error","name":"BatchTooLarge","inputs":[]},{"type":"error","name":"BlobsRequired","inputs":[]},{"type":"error","name":"EtnaNotActive","inputs":[]},{"type":"error","name":"FUNC_NOT_IMPLEMENTED","inputs":[]},{"type":"error","name":"HeightOverflow","inputs":[]},{"type":"error","name":"INVALID_PAUSE_STATUS","inputs":[]},{"type":"error","name":"InvalidEpochLength","inputs":[]},{"type":"error","name":"InvalidGenesis","inputs":[]},{"type":"error","name":"InvalidGenesisCutoff","inputs":[]},{"type":"error","name":"NoProgress","inputs":[]},{"type":"error","name":"REENTRANT_CALL","inputs":[]},{"type":"error","name":"ZERO_ADDRESS","inputs":[]},{"type":"error","name":"ZERO_VALUE","inputs":[]},{"type":"error","name":"ZeroCommitteeConfigHash","inputs":[]},{"type":"error","name":"ZeroCommitteeRecord","inputs":[]},{"type":"event","name":"AdminChanged","inputs":[{"type":"address","name":"previousAdmin","internalType":"address","indexed":false},{"type":"address","name":"newAdmin","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"BatchLanded","inputs":[{"type":"uint64","name":"firstHeight","internalType":"uint64","indexed":false},{"type":"uint64","name":"lastHeight","internalType":"uint64","indexed":false},{"type":"bytes32","name":"lastBlockHash","internalType":"bytes32","indexed":false},{"type":"bytes32","name":"lastStateRoot","internalType":"bytes32","indexed":false},{"type":"uint64","name":"l1ReferenceBlockNumber","internalType":"uint64","indexed":false},{"type":"bytes32","name":"statementHash","internalType":"bytes32","indexed":false},{"type":"address","name":"lander","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"BeaconUpgraded","inputs":[{"type":"address","name":"beacon","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"EtnaInitialized","inputs":[{"type":"bytes32","name":"genesisBlockHash","internalType":"bytes32","indexed":false},{"type":"bytes32","name":"genesisStateRoot","internalType":"bytes32","indexed":false},{"type":"uint64","name":"l1Block","internalType":"uint64","indexed":false},{"type":"uint64","name":"epochLenL2","internalType":"uint64","indexed":false},{"type":"uint64","name":"epochLenL1","internalType":"uint64","indexed":false},{"type":"uint64","name":"genesisCutoff","internalType":"uint64","indexed":false},{"type":"bytes32","name":"committeeRecordHash","internalType":"bytes32","indexed":false}],"anonymous":false},{"type":"event","name":"Initialized","inputs":[{"type":"uint8","name":"version","internalType":"uint8","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferStarted","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"Paused","inputs":[{"type":"address","name":"account","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"Unpaused","inputs":[{"type":"address","name":"account","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"Upgraded","inputs":[{"type":"address","name":"implementation","internalType":"address","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"acceptOwnership","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct IEtnaInbox.Activation","components":[{"type":"uint64","name":"genesisHeight","internalType":"uint64"},{"type":"uint64","name":"l1Block","internalType":"uint64"},{"type":"uint64","name":"epochLenL2","internalType":"uint64"},{"type":"uint64","name":"epochLenL1","internalType":"uint64"},{"type":"bytes32","name":"genesisBlockHash","internalType":"bytes32"},{"type":"bytes32","name":"genesisStateRoot","internalType":"bytes32"}]}],"name":"activation","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"configHash_","internalType":"bytes32"}],"name":"committeeConfigHash","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"recordHash_","internalType":"bytes32"}],"name":"genesisCommitteeRecordHash","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint64","name":"","internalType":"uint64"}],"name":"genesisCutoff","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"statementHash_","internalType":"bytes32"}],"name":"hashLandStatement","inputs":[{"type":"uint64","name":"_generation","internalType":"uint64"},{"type":"uint64","name":"_parentHeight","internalType":"uint64"},{"type":"bytes32","name":"_parentHash","internalType":"bytes32"},{"type":"tuple","name":"_input","internalType":"struct IEtnaInbox.LandInput","components":[{"type":"uint64","name":"lastHeight","internalType":"uint64"},{"type":"bytes32","name":"lastBlockHash","internalType":"bytes32"},{"type":"bytes32","name":"lastStateRoot","internalType":"bytes32"},{"type":"uint64","name":"l1ReferenceBlockNumber","internalType":"uint64"}]},{"type":"bytes32","name":"_l1ReferenceBlockHash","internalType":"bytes32"},{"type":"bytes32[]","name":"_blobHashes","internalType":"bytes32[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"impl","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"inNonReentrant","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"init","inputs":[{"type":"address","name":"_owner","internalType":"address"},{"type":"tuple","name":"_params","internalType":"struct IEtnaInbox.GenesisParams","components":[{"type":"bytes32","name":"genesisBlockHash","internalType":"bytes32"},{"type":"bytes32","name":"genesisStateRoot","internalType":"bytes32"},{"type":"uint64","name":"epochLenL2","internalType":"uint64"},{"type":"uint64","name":"epochLenL1","internalType":"uint64"},{"type":"uint64","name":"genesisCutoff","internalType":"uint64"},{"type":"bytes32","name":"committeeRecordHash","internalType":"bytes32"},{"type":"bytes32","name":"committeeConfigHash","internalType":"bytes32"}]}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"land","inputs":[{"type":"tuple","name":"_input","internalType":"struct IEtnaInbox.LandInput","components":[{"type":"uint64","name":"lastHeight","internalType":"uint64"},{"type":"bytes32","name":"lastBlockHash","internalType":"bytes32"},{"type":"bytes32","name":"lastStateRoot","internalType":"bytes32"},{"type":"uint64","name":"l1ReferenceBlockNumber","internalType":"uint64"}]},{"type":"bytes","name":"_proof","internalType":"bytes"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct IEtnaInbox.LandedCheckpoint","components":[{"type":"uint64","name":"height","internalType":"uint64"},{"type":"bytes32","name":"blockHash","internalType":"bytes32"}]}],"name":"lastCheckpoint","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"migrationState","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"pause","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"paused","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"pendingOwner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"proxiableUUID","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint64","name":"","internalType":"uint64"}],"name":"recoveryGeneration","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"resolver","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unpause","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"upgradeTo","inputs":[{"type":"address","name":"newImplementation","internalType":"address"}]},{"type":"function","stateMutability":"payable","outputs":[],"name":"upgradeToAndCall","inputs":[{"type":"address","name":"newImplementation","internalType":"address"},{"type":"bytes","name":"data","internalType":"bytes"}]}]
              

Contract Creation Code

Verify & Publish
0x61016060405230608052348015610014575f5ffd5b5060405161278838038061278883398101604081905261003391610248565b61003b61015b565b80516001600160a01b03166100635760405163538ba4f960e01b815260040160405180910390fd5b60208101516001600160a01b031661008e5760405163538ba4f960e01b815260040160405180910390fd5b60408101516001600160a01b03166100b95760405163538ba4f960e01b815260040160405180910390fd5b80606001516001600160401b03165f036100e65760405163ec73295960e01b815260040160405180910390fd5b80608001516001600160401b03165f036101135760405163ec73295960e01b815260040160405180910390fd5b80516001600160a01b0390811660c0526020820151811660e0526040820151166101005260608101516001600160401b039081166101205260809091015116610140526102e1565b5f54610100900460ff16156101c65760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b5f5460ff90811614610215575f805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b80516001600160a01b038116811461022d575f5ffd5b919050565b80516001600160401b038116811461022d575f5ffd5b5f60a0828403128015610259575f5ffd5b5060405160a081016001600160401b038111828210171561028857634e487b7160e01b5f52604160045260245ffd5b60405261029483610217565b81526102a260208401610217565b60208201526102b360408401610217565b60408201526102c460608401610232565b60608201526102d560808401610232565b60808201529392505050565b60805160a05160c05160e0516101005161012051610140516124256103635f395f610eb701525f61141b01525f818161144b0152818161156b015261161901525f8181610bd6015261100801525f61110801525f61015901525f818161056e015281816105b701528181610699015281816106d901526107a101526124255ff3fe608060405260043610610147575f3560e01c80636b495f55116100b357806395806bd81161006d57806395806bd814610482578063cf4a9bc3146104a0578063d32e81a5146104b5578063dcf47eb014610509578063e30c397814610528578063f2fde38b14610545575f5ffd5b80636b495f55146103f6578063715018a61461041557806379ba5097146104295780638456cb591461043d5780638abf6077146104515780638da5cb5b14610465575f5ffd5b80633659cfe6116101045780633659cfe61461035b5780633f4ba83a1461037c5780634f1ef2861461039057806350a5f8fd146103a357806352d1902d146103c25780635c975abb146103d6575f5ffd5b806304f3bcec1461014b57806312a2f792146101965780631497a7de146101b857806320d0ac9f146101d75780633075db56146102095780633629c8de1461024e575b5f5ffd5b348015610156575f5ffd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040516001600160a01b0390911681526020015b60405180910390f35b3480156101a1575f5ffd5b506101025460405160ff909116815260200161018d565b3480156101c3575f5ffd5b50610116545b60405190815260200161018d565b3480156101e2575f5ffd5b50610117546001600160401b03165b6040516001600160401b03909116815260200161018d565b348015610214575f5ffd5b5060027fa5054f728453d3dbe953bdc43e4d0cb97e662ea32d7958190f3dc2da31d9721b5c60ff16145b604051901515815260200161018d565b348015610259575f5ffd5b506102ec6040805160c0810182525f80825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c081018252610110546001600160401b038082168352600160401b820481166020840152600160801b8204811693830193909352600160c01b900490911660608201526101115460808201526101125460a082015290565b60405161018d91905f60c0820190506001600160401b0383511682526001600160401b0360208401511660208301526001600160401b0360408401511660408301526001600160401b0360608401511660608301526080830151608083015260a083015160a083015292915050565b348015610366575f5ffd5b5061037a610375366004611d12565b610564565b005b348015610387575f5ffd5b5061037a610634565b61037a61039e366004611d6f565b61068f565b3480156103ae575f5ffd5b506101c96103bd366004611e36565b610748565b3480156103cd575f5ffd5b506101c9610795565b3480156103e1575f5ffd5b5061023e60c954610100900460ff1660021490565b348015610401575f5ffd5b5061037a610410366004611ef0565b610846565b348015610420575f5ffd5b5061037a610d1c565b348015610434575f5ffd5b5061037a610d2d565b348015610448575f5ffd5b5061037a610da4565b34801561045c575f5ffd5b50610179610df9565b348015610470575f5ffd5b506033546001600160a01b0316610179565b34801561048d575f5ffd5b5061010c546001600160401b03166101f1565b3480156104ab575f5ffd5b5061010d546101c9565b3480156104c0575f5ffd5b506040805180820182525f8082526020918201528151808301835261010e546001600160401b031680825261010f5491830191825283519081529051918101919091520161018d565b348015610514575f5ffd5b5061037a610523366004611f2d565b610e07565b348015610533575f5ffd5b506065546001600160a01b0316610179565b348015610550575f5ffd5b5061037a61055f366004611d12565b61117c565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036105b55760405162461bcd60e51b81526004016105ac90611faa565b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166105e76111ed565b6001600160a01b03161461060d5760405162461bcd60e51b81526004016105ac90611ff6565b61061681611208565b604080515f8082526020820190925261063191839190611210565b50565b61063c61137a565b61065060c9805461ff001916610100179055565b6040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa9060200160405180910390a161068d335f6113ab565b565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036106d75760405162461bcd60e51b81526004016105ac90611faa565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166107096111ed565b6001600160a01b03161461072f5760405162461bcd60e51b81526004016105ac90611ff6565b61073882611208565b61074482826001611210565b5050565b5f61078988888888888888808060200260200160405190810160405280939291908181526020018383602002808284375f920191909152506113b392505050565b98975050505050505050565b5f306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146108345760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016105ac565b505f5160206123a95f395f51905f5290565b5f54610100900460ff161580801561086457505f54600160ff909116105b8061087d5750303b15801561087d57505f5460ff166001145b6108e05760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016105ac565b5f805460ff191660011790558015610901575f805461ff0019166101001790555b8135158015906109145750602082013515155b6109315760405163156b26df60e31b815260040160405180910390fd5b60036109436060840160408501612042565b6001600160401b03161015801561097157506109656080830160608401612042565b6001600160401b031615155b61098e576040516388ac089760e01b815260040160405180910390fd5b6109a66109a160a0840160808501612042565b611551565b6109c357604051630377d3e160e61b815260040160405180910390fd5b60a08201355f036109e657604051627bdb0560e71b815260040160405180910390fd5b60c08201355f03610a0a5760405163390d011560e11b815260040160405180910390fd5b610a138361169c565b610102805460ff191660031790556040805160c0810182525f81526001600160401b034390811660208301529181810190610a549060608701908701612042565b6001600160401b03168152602001610a726080860160608701612042565b6001600160401b03908116825285356020808401919091528087013560409384015283516101108054928601519486015160608701519285166fffffffffffffffffffffffffffffffff1990941693909317600160401b95851695909502949094176fffffffffffffffffffffffffffffffff16600160801b928416929092026001600160c01b031691909117600160c01b91909216021790556080808201516101115560a09182015161011255610b2e918501908501612042565b61011780546001600160401b039290921667ffffffffffffffff1992831617905560a08401356101165560c084013561010d556040805180820182525f8082528635602092830181905261010e805490951690945561010f8490558251606081018452908152808201938452908601358183019081529151631934171960e31b8152905165ffffffffffff166004820152915160248301525160448201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c9a0b8c8906064015f604051808303815f87803b158015610c17575f5ffd5b505af1158015610c29573d5f5f3e3d5ffd5b507f2355a92149870da25c55d38f41906ea2e265232f265bd0e4892f5df31197303f92505084359050602085013583610c686060880160408901612042565b610c786080890160608a01612042565b610c8860a08a0160808b01612042565b6040805196875260208701959095526001600160401b03938416868601529183166060860152821660808501521660a08084019190915286013560c0830152519081900360e00190a1508015610d17575f805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b610d246116fa565b61068d5f611754565b60655433906001600160a01b03168114610d9b5760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084016105ac565b61063181611754565b610dac61176d565b60c9805461ff0019166102001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2589060200160405180910390a161068d3360016113ab565b5f610e026111ed565b905090565b610e0f61179f565b610e1960026117e4565b6101025460ff16600314610e40576040516383c575ff60e01b815260040160405180910390fd5b6040805180820190915261010e546001600160401b0316815261010f546020808301919091525f90610e7490860186612042565b9050815f01516001600160401b0316816001600160401b031611610eab57604051638b1075b960e01b815260040160405180910390fd5b81516001600160401b037f00000000000000000000000000000000000000000000000000000000000000001690610ee29083612078565b6001600160401b03161115610f0a576040516305beb17160e11b815260040160405180910390fd5b65ffffffffffff6001600160401b0382161115610f3a57604051633485a4d160e21b815260040160405180910390fd5b61010c54825160208401515f92610f7d926001600160401b039091169189610f70610f6b6080830160608401612042565b61180a565b610f7861197b565b6113b3565b6040805180820182526001600160401b03851680825260208a81013592810183905261010e805467ffffffffffffffff191690921790915561010f829055825160608101845265ffffffffffff80881682529181019283528a8401358185019081529351631934171960e31b81529051909116600482015290516024820152905160448201529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063c9a0b8c8906064015f604051808303815f87803b158015611051575f5ffd5b505af1158015611063573d5f5f3e3d5ffd5b505084513392507ff7748b2706521bf000553f53937ffbe593fa277d618ee71a4e2df74bed99eceb9150611098906001612097565b8460208a013560408b01356110b360808d0160608e01612042565b604080516001600160401b03968716815294861660208601528401929092526060830152909116608082015260a0810184905260c00160405180910390a26040516314bcf3dd60e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906314bcf3dd90611143905f9085908a908a906004016120b6565b5f6040518083038186803b158015611159575f5ffd5b505afa15801561116b573d5f5f3e3d5ffd5b50505050505050610d1760016117e4565b6111846116fa565b606580546001600160a01b0383166001600160a01b031990911681179091556111b56033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b5f5160206123a95f395f51905f52546001600160a01b031690565b6106316116fa565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561124357610d1783611a30565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561129d575060408051601f3d908101601f1916820190925261129a918101906120f2565b60015b6113005760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016105ac565b5f5160206123a95f395f51905f52811461136e5760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016105ac565b50610d17838383611acb565b61138e60c954610100900460ff1660021490565b61068d5760405163bae6e2a960e01b815260040160405180910390fd5b6107446116fa565b604080516101e0810182525f61012082018190526101408201819052610160820181905261018082018190526101a082018190526101c08201819052715441494b4f5f45544e415f4c414e445f563560701b8252466020808401919091526001600160401b037f00000000000000000000000000000000000000000000000000000000000000008116948401949094523060608401527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316608084015289841660a084015292881660c083015260e0820187905261010d54610100830152916114a690860186612042565b6001600160401b0316610120820152602085013561014082015260408501356101608201526114db6080860160608701612042565b6001600160401b03166101808201526101a08101849052604051611503908490602001612109565b60408051601f1981840301815291815281516020928301206101c08401525161152e9183910161213e565b604051602081830303815290604052805190602001209150509695505050505050565b5f43826001600160401b03161061156957505f919050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631f618cd26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115c5573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115e991906120f2565b5f036115f657505f919050565b6040516001626ac92560e01b031981525f60048201526001600160401b038316907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063ff9536db90602401606060405180830381865afa158015611666573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061168a9190612261565b516001600160401b0316111592915050565b5f54610100900460ff166116c25760405162461bcd60e51b81526004016105ac906122d3565b6116ca611af5565b6116e86001600160a01b038216156116e25781611754565b33611754565b5060c9805461ff001916610100179055565b6033546001600160a01b0316331461068d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105ac565b606580546001600160a01b031916905561063181611b1b565b61178160c954610100900460ff1660021490565b1561068d5760405163bae6e2a960e01b815260040160405180910390fd5b60027fa5054f728453d3dbe953bdc43e4d0cb97e662ea32d7958190f3dc2da31d9721b5c60ff160361068d5760405163dfc60d8560e01b815260040160405180910390fd5b807fa5054f728453d3dbe953bdc43e4d0cb97e662ea32d7958190f3dc2da31d9721b5d50565b5f43826001600160401b031610611834576040516360776ed360e01b815260040160405180910390fd5b5f6118486001600160401b0384164361231e565b9050610100811161186557826001600160401b0316409150611954565b611fff811115611888576040516360776ed360e01b815260040160405180910390fd5b604080516001600160401b03851660208201525f91829171f90827f1c53a10cb7a02335b175320002935910160408051601f19818403018152908290526118ce91612331565b5f60405180830381855afa9150503d805f8114611906576040519150601f19603f3d011682016040523d82523d5f602084013e61190b565b606091505b509150915081801561191e575080516020145b61193b576040516360776ed360e01b815260040160405180910390fd5b8080602001905181019061194f91906120f2565b935050505b5f829003611975576040516360776ed360e01b815260040160405180910390fd5b50919050565b60605f5b8049156119965761198f81612347565b905061197f565b805f036119b65760405163595f3be960e11b815260040160405180910390fd5b806001600160401b038111156119ce576119ce611d2b565b6040519080825280602002602001820160405280156119f7578160200160208202803683370190505b5091505f5b81811015611a2b578049838281518110611a1857611a1861235f565b60209081029190910101526001016119fc565b505090565b6001600160a01b0381163b611a9d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016105ac565b5f5160206123a95f395f51905f5280546001600160a01b0319166001600160a01b0392909216919091179055565b611ad483611b6c565b5f82511180611ae05750805b15610d1757611aef8383611bab565b50505050565b5f54610100900460ff1661068d5760405162461bcd60e51b81526004016105ac906122d3565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b611b7581611a30565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a250565b6060611bd083836040518060600160405280602781526020016123c960279139611bd9565b90505b92915050565b60605f5f856001600160a01b031685604051611bf59190612331565b5f60405180830381855af49150503d805f8114611c2d576040519150601f19603f3d011682016040523d82523d5f602084013e611c32565b606091505b5091509150611c4386838387611c4d565b9695505050505050565b60608315611cbb5782515f03611cb4576001600160a01b0385163b611cb45760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016105ac565b5081611cc5565b611cc58383611ccd565b949350505050565b815115611cdd5781518083602001fd5b8060405162461bcd60e51b81526004016105ac9190612373565b80356001600160a01b0381168114611d0d575f5ffd5b919050565b5f60208284031215611d22575f5ffd5b611bd082611cf7565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b0381118282101715611d6757611d67611d2b565b604052919050565b5f5f60408385031215611d80575f5ffd5b611d8983611cf7565b915060208301356001600160401b03811115611da3575f5ffd5b8301601f81018513611db3575f5ffd5b80356001600160401b03811115611dcc57611dcc611d2b565b611ddf601f8201601f1916602001611d3f565b818152866020838501011115611df3575f5ffd5b816020840160208301375f602083830101528093505050509250929050565b6001600160401b0381168114610631575f5ffd5b5f60808284031215611975575f5ffd5b5f5f5f5f5f5f5f610120888a031215611e4d575f5ffd5b8735611e5881611e12565b96506020880135611e6881611e12565b955060408801359450611e7e8960608a01611e26565b935060e088013592506101008801356001600160401b03811115611ea0575f5ffd5b8801601f81018a13611eb0575f5ffd5b80356001600160401b03811115611ec5575f5ffd5b8a60208260051b8401011115611ed9575f5ffd5b602082019350809250505092959891949750929550565b5f5f828403610100811215611f03575f5ffd5b611f0c84611cf7565b925060e0601f1982011215611f1f575f5ffd5b506020830190509250929050565b5f5f5f60a08486031215611f3f575f5ffd5b611f498585611e26565b925060808401356001600160401b03811115611f63575f5ffd5b8401601f81018613611f73575f5ffd5b80356001600160401b03811115611f88575f5ffd5b866020828401011115611f99575f5ffd5b939660209190910195509293505050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b5f60208284031215612052575f5ffd5b813561205d81611e12565b9392505050565b634e487b7160e01b5f52601160045260245ffd5b6001600160401b038281168282160390811115611bd357611bd3612064565b6001600160401b038181168382160190811115611bd357611bd3612064565b84815283602082015260606040820152816060820152818360808301375f818301608090810191909152601f909201601f191601019392505050565b5f60208284031215612102575f5ffd5b5051919050565b81515f90829060208501835b82811015612133578151845260209384019390910190600101612115565b509195945050505050565b5f6101e0820190508251825260208301516020830152604083015161216e60408401826001600160401b03169052565b50606083015161218960608401826001600160a01b03169052565b5060808301516121a460808401826001600160a01b03169052565b5060a08301516121bf60a08401826001600160401b03169052565b5060c08301516121da60c08401826001600160401b03169052565b5060e083015160e083015261010083015161010083015261012083015161220d6101208401826001600160401b03169052565b506101408301516101408301526101608301516101608301526101808301516122426101808401826001600160401b03169052565b506101a08301516101a08301526101c08301516101c083015292915050565b5f6060828403128015612272575f5ffd5b50604051606081016001600160401b038111828210171561229557612295611d2b565b60405282516122a381611e12565b8152602083015163ffffffff811681146122bb575f5ffd5b60208201526040928301519281019290925250919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b81810381811115611bd357611bd3612064565b5f82518060208501845e5f920191825250919050565b5f6001820161235857612358612064565b5060010190565b634e487b7160e01b5f52603260045260245ffd5b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f8301168401019150509291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212202399a769353d7bb4b4db6feb272cff380be1383a8fb873237ce53fbbac69c69364736f6c634300081e0033000000000000000000000000044c2e53e9edddd1353a9d923fa39c1fa821e88e0000000000000000000000009a3a019b2820ae3d396120fb9b2782d37be4799c000000000000000000000000b261c6facc0707b674c7491338412fdf44733a4b0000000000000000000000000000000000000000000000000000000000028c590000000000000000000000000000000000000000000000000000000000000080

Deployed ByteCode

0x608060405260043610610147575f3560e01c80636b495f55116100b357806395806bd81161006d57806395806bd814610482578063cf4a9bc3146104a0578063d32e81a5146104b5578063dcf47eb014610509578063e30c397814610528578063f2fde38b14610545575f5ffd5b80636b495f55146103f6578063715018a61461041557806379ba5097146104295780638456cb591461043d5780638abf6077146104515780638da5cb5b14610465575f5ffd5b80633659cfe6116101045780633659cfe61461035b5780633f4ba83a1461037c5780634f1ef2861461039057806350a5f8fd146103a357806352d1902d146103c25780635c975abb146103d6575f5ffd5b806304f3bcec1461014b57806312a2f792146101965780631497a7de146101b857806320d0ac9f146101d75780633075db56146102095780633629c8de1461024e575b5f5ffd5b348015610156575f5ffd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040516001600160a01b0390911681526020015b60405180910390f35b3480156101a1575f5ffd5b506101025460405160ff909116815260200161018d565b3480156101c3575f5ffd5b50610116545b60405190815260200161018d565b3480156101e2575f5ffd5b50610117546001600160401b03165b6040516001600160401b03909116815260200161018d565b348015610214575f5ffd5b5060027fa5054f728453d3dbe953bdc43e4d0cb97e662ea32d7958190f3dc2da31d9721b5c60ff16145b604051901515815260200161018d565b348015610259575f5ffd5b506102ec6040805160c0810182525f80825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c081018252610110546001600160401b038082168352600160401b820481166020840152600160801b8204811693830193909352600160c01b900490911660608201526101115460808201526101125460a082015290565b60405161018d91905f60c0820190506001600160401b0383511682526001600160401b0360208401511660208301526001600160401b0360408401511660408301526001600160401b0360608401511660608301526080830151608083015260a083015160a083015292915050565b348015610366575f5ffd5b5061037a610375366004611d12565b610564565b005b348015610387575f5ffd5b5061037a610634565b61037a61039e366004611d6f565b61068f565b3480156103ae575f5ffd5b506101c96103bd366004611e36565b610748565b3480156103cd575f5ffd5b506101c9610795565b3480156103e1575f5ffd5b5061023e60c954610100900460ff1660021490565b348015610401575f5ffd5b5061037a610410366004611ef0565b610846565b348015610420575f5ffd5b5061037a610d1c565b348015610434575f5ffd5b5061037a610d2d565b348015610448575f5ffd5b5061037a610da4565b34801561045c575f5ffd5b50610179610df9565b348015610470575f5ffd5b506033546001600160a01b0316610179565b34801561048d575f5ffd5b5061010c546001600160401b03166101f1565b3480156104ab575f5ffd5b5061010d546101c9565b3480156104c0575f5ffd5b506040805180820182525f8082526020918201528151808301835261010e546001600160401b031680825261010f5491830191825283519081529051918101919091520161018d565b348015610514575f5ffd5b5061037a610523366004611f2d565b610e07565b348015610533575f5ffd5b506065546001600160a01b0316610179565b348015610550575f5ffd5b5061037a61055f366004611d12565b61117c565b6001600160a01b037f0000000000000000000000002fa4805846c3a81563e4b34c9f91115532aaeec41630036105b55760405162461bcd60e51b81526004016105ac90611faa565b60405180910390fd5b7f0000000000000000000000002fa4805846c3a81563e4b34c9f91115532aaeec46001600160a01b03166105e76111ed565b6001600160a01b03161461060d5760405162461bcd60e51b81526004016105ac90611ff6565b61061681611208565b604080515f8082526020820190925261063191839190611210565b50565b61063c61137a565b61065060c9805461ff001916610100179055565b6040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa9060200160405180910390a161068d335f6113ab565b565b6001600160a01b037f0000000000000000000000002fa4805846c3a81563e4b34c9f91115532aaeec41630036106d75760405162461bcd60e51b81526004016105ac90611faa565b7f0000000000000000000000002fa4805846c3a81563e4b34c9f91115532aaeec46001600160a01b03166107096111ed565b6001600160a01b03161461072f5760405162461bcd60e51b81526004016105ac90611ff6565b61073882611208565b61074482826001611210565b5050565b5f61078988888888888888808060200260200160405190810160405280939291908181526020018383602002808284375f920191909152506113b392505050565b98975050505050505050565b5f306001600160a01b037f0000000000000000000000002fa4805846c3a81563e4b34c9f91115532aaeec416146108345760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016105ac565b505f5160206123a95f395f51905f5290565b5f54610100900460ff161580801561086457505f54600160ff909116105b8061087d5750303b15801561087d57505f5460ff166001145b6108e05760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016105ac565b5f805460ff191660011790558015610901575f805461ff0019166101001790555b8135158015906109145750602082013515155b6109315760405163156b26df60e31b815260040160405180910390fd5b60036109436060840160408501612042565b6001600160401b03161015801561097157506109656080830160608401612042565b6001600160401b031615155b61098e576040516388ac089760e01b815260040160405180910390fd5b6109a66109a160a0840160808501612042565b611551565b6109c357604051630377d3e160e61b815260040160405180910390fd5b60a08201355f036109e657604051627bdb0560e71b815260040160405180910390fd5b60c08201355f03610a0a5760405163390d011560e11b815260040160405180910390fd5b610a138361169c565b610102805460ff191660031790556040805160c0810182525f81526001600160401b034390811660208301529181810190610a549060608701908701612042565b6001600160401b03168152602001610a726080860160608701612042565b6001600160401b03908116825285356020808401919091528087013560409384015283516101108054928601519486015160608701519285166fffffffffffffffffffffffffffffffff1990941693909317600160401b95851695909502949094176fffffffffffffffffffffffffffffffff16600160801b928416929092026001600160c01b031691909117600160c01b91909216021790556080808201516101115560a09182015161011255610b2e918501908501612042565b61011780546001600160401b039290921667ffffffffffffffff1992831617905560a08401356101165560c084013561010d556040805180820182525f8082528635602092830181905261010e805490951690945561010f8490558251606081018452908152808201938452908601358183019081529151631934171960e31b8152905165ffffffffffff166004820152915160248301525160448201526001600160a01b037f0000000000000000000000009a3a019b2820ae3d396120fb9b2782d37be4799c169063c9a0b8c8906064015f604051808303815f87803b158015610c17575f5ffd5b505af1158015610c29573d5f5f3e3d5ffd5b507f2355a92149870da25c55d38f41906ea2e265232f265bd0e4892f5df31197303f92505084359050602085013583610c686060880160408901612042565b610c786080890160608a01612042565b610c8860a08a0160808b01612042565b6040805196875260208701959095526001600160401b03938416868601529183166060860152821660808501521660a08084019190915286013560c0830152519081900360e00190a1508015610d17575f805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b610d246116fa565b61068d5f611754565b60655433906001600160a01b03168114610d9b5760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084016105ac565b61063181611754565b610dac61176d565b60c9805461ff0019166102001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2589060200160405180910390a161068d3360016113ab565b5f610e026111ed565b905090565b610e0f61179f565b610e1960026117e4565b6101025460ff16600314610e40576040516383c575ff60e01b815260040160405180910390fd5b6040805180820190915261010e546001600160401b0316815261010f546020808301919091525f90610e7490860186612042565b9050815f01516001600160401b0316816001600160401b031611610eab57604051638b1075b960e01b815260040160405180910390fd5b81516001600160401b037f00000000000000000000000000000000000000000000000000000000000000801690610ee29083612078565b6001600160401b03161115610f0a576040516305beb17160e11b815260040160405180910390fd5b65ffffffffffff6001600160401b0382161115610f3a57604051633485a4d160e21b815260040160405180910390fd5b61010c54825160208401515f92610f7d926001600160401b039091169189610f70610f6b6080830160608401612042565b61180a565b610f7861197b565b6113b3565b6040805180820182526001600160401b03851680825260208a81013592810183905261010e805467ffffffffffffffff191690921790915561010f829055825160608101845265ffffffffffff80881682529181019283528a8401358185019081529351631934171960e31b81529051909116600482015290516024820152905160448201529091507f0000000000000000000000009a3a019b2820ae3d396120fb9b2782d37be4799c6001600160a01b03169063c9a0b8c8906064015f604051808303815f87803b158015611051575f5ffd5b505af1158015611063573d5f5f3e3d5ffd5b505084513392507ff7748b2706521bf000553f53937ffbe593fa277d618ee71a4e2df74bed99eceb9150611098906001612097565b8460208a013560408b01356110b360808d0160608e01612042565b604080516001600160401b03968716815294861660208601528401929092526060830152909116608082015260a0810184905260c00160405180910390a26040516314bcf3dd60e01b81526001600160a01b037f000000000000000000000000044c2e53e9edddd1353a9d923fa39c1fa821e88e16906314bcf3dd90611143905f9085908a908a906004016120b6565b5f6040518083038186803b158015611159575f5ffd5b505afa15801561116b573d5f5f3e3d5ffd5b50505050505050610d1760016117e4565b6111846116fa565b606580546001600160a01b0383166001600160a01b031990911681179091556111b56033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b5f5160206123a95f395f51905f52546001600160a01b031690565b6106316116fa565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561124357610d1783611a30565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561129d575060408051601f3d908101601f1916820190925261129a918101906120f2565b60015b6113005760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016105ac565b5f5160206123a95f395f51905f52811461136e5760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016105ac565b50610d17838383611acb565b61138e60c954610100900460ff1660021490565b61068d5760405163bae6e2a960e01b815260040160405180910390fd5b6107446116fa565b604080516101e0810182525f61012082018190526101408201819052610160820181905261018082018190526101a082018190526101c08201819052715441494b4f5f45544e415f4c414e445f563560701b8252466020808401919091526001600160401b037f0000000000000000000000000000000000000000000000000000000000028c598116948401949094523060608401527f000000000000000000000000b261c6facc0707b674c7491338412fdf44733a4b6001600160a01b0316608084015289841660a084015292881660c083015260e0820187905261010d54610100830152916114a690860186612042565b6001600160401b0316610120820152602085013561014082015260408501356101608201526114db6080860160608701612042565b6001600160401b03166101808201526101a08101849052604051611503908490602001612109565b60408051601f1981840301815291815281516020928301206101c08401525161152e9183910161213e565b604051602081830303815290604052805190602001209150509695505050505050565b5f43826001600160401b03161061156957505f919050565b7f000000000000000000000000b261c6facc0707b674c7491338412fdf44733a4b6001600160a01b0316631f618cd26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115c5573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115e991906120f2565b5f036115f657505f919050565b6040516001626ac92560e01b031981525f60048201526001600160401b038316907f000000000000000000000000b261c6facc0707b674c7491338412fdf44733a4b6001600160a01b03169063ff9536db90602401606060405180830381865afa158015611666573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061168a9190612261565b516001600160401b0316111592915050565b5f54610100900460ff166116c25760405162461bcd60e51b81526004016105ac906122d3565b6116ca611af5565b6116e86001600160a01b038216156116e25781611754565b33611754565b5060c9805461ff001916610100179055565b6033546001600160a01b0316331461068d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105ac565b606580546001600160a01b031916905561063181611b1b565b61178160c954610100900460ff1660021490565b1561068d5760405163bae6e2a960e01b815260040160405180910390fd5b60027fa5054f728453d3dbe953bdc43e4d0cb97e662ea32d7958190f3dc2da31d9721b5c60ff160361068d5760405163dfc60d8560e01b815260040160405180910390fd5b807fa5054f728453d3dbe953bdc43e4d0cb97e662ea32d7958190f3dc2da31d9721b5d50565b5f43826001600160401b031610611834576040516360776ed360e01b815260040160405180910390fd5b5f6118486001600160401b0384164361231e565b9050610100811161186557826001600160401b0316409150611954565b611fff811115611888576040516360776ed360e01b815260040160405180910390fd5b604080516001600160401b03851660208201525f91829171f90827f1c53a10cb7a02335b175320002935910160408051601f19818403018152908290526118ce91612331565b5f60405180830381855afa9150503d805f8114611906576040519150601f19603f3d011682016040523d82523d5f602084013e61190b565b606091505b509150915081801561191e575080516020145b61193b576040516360776ed360e01b815260040160405180910390fd5b8080602001905181019061194f91906120f2565b935050505b5f829003611975576040516360776ed360e01b815260040160405180910390fd5b50919050565b60605f5b8049156119965761198f81612347565b905061197f565b805f036119b65760405163595f3be960e11b815260040160405180910390fd5b806001600160401b038111156119ce576119ce611d2b565b6040519080825280602002602001820160405280156119f7578160200160208202803683370190505b5091505f5b81811015611a2b578049838281518110611a1857611a1861235f565b60209081029190910101526001016119fc565b505090565b6001600160a01b0381163b611a9d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016105ac565b5f5160206123a95f395f51905f5280546001600160a01b0319166001600160a01b0392909216919091179055565b611ad483611b6c565b5f82511180611ae05750805b15610d1757611aef8383611bab565b50505050565b5f54610100900460ff1661068d5760405162461bcd60e51b81526004016105ac906122d3565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b611b7581611a30565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a250565b6060611bd083836040518060600160405280602781526020016123c960279139611bd9565b90505b92915050565b60605f5f856001600160a01b031685604051611bf59190612331565b5f60405180830381855af49150503d805f8114611c2d576040519150601f19603f3d011682016040523d82523d5f602084013e611c32565b606091505b5091509150611c4386838387611c4d565b9695505050505050565b60608315611cbb5782515f03611cb4576001600160a01b0385163b611cb45760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016105ac565b5081611cc5565b611cc58383611ccd565b949350505050565b815115611cdd5781518083602001fd5b8060405162461bcd60e51b81526004016105ac9190612373565b80356001600160a01b0381168114611d0d575f5ffd5b919050565b5f60208284031215611d22575f5ffd5b611bd082611cf7565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b0381118282101715611d6757611d67611d2b565b604052919050565b5f5f60408385031215611d80575f5ffd5b611d8983611cf7565b915060208301356001600160401b03811115611da3575f5ffd5b8301601f81018513611db3575f5ffd5b80356001600160401b03811115611dcc57611dcc611d2b565b611ddf601f8201601f1916602001611d3f565b818152866020838501011115611df3575f5ffd5b816020840160208301375f602083830101528093505050509250929050565b6001600160401b0381168114610631575f5ffd5b5f60808284031215611975575f5ffd5b5f5f5f5f5f5f5f610120888a031215611e4d575f5ffd5b8735611e5881611e12565b96506020880135611e6881611e12565b955060408801359450611e7e8960608a01611e26565b935060e088013592506101008801356001600160401b03811115611ea0575f5ffd5b8801601f81018a13611eb0575f5ffd5b80356001600160401b03811115611ec5575f5ffd5b8a60208260051b8401011115611ed9575f5ffd5b602082019350809250505092959891949750929550565b5f5f828403610100811215611f03575f5ffd5b611f0c84611cf7565b925060e0601f1982011215611f1f575f5ffd5b506020830190509250929050565b5f5f5f60a08486031215611f3f575f5ffd5b611f498585611e26565b925060808401356001600160401b03811115611f63575f5ffd5b8401601f81018613611f73575f5ffd5b80356001600160401b03811115611f88575f5ffd5b866020828401011115611f99575f5ffd5b939660209190910195509293505050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b5f60208284031215612052575f5ffd5b813561205d81611e12565b9392505050565b634e487b7160e01b5f52601160045260245ffd5b6001600160401b038281168282160390811115611bd357611bd3612064565b6001600160401b038181168382160190811115611bd357611bd3612064565b84815283602082015260606040820152816060820152818360808301375f818301608090810191909152601f909201601f191601019392505050565b5f60208284031215612102575f5ffd5b5051919050565b81515f90829060208501835b82811015612133578151845260209384019390910190600101612115565b509195945050505050565b5f6101e0820190508251825260208301516020830152604083015161216e60408401826001600160401b03169052565b50606083015161218960608401826001600160a01b03169052565b5060808301516121a460808401826001600160a01b03169052565b5060a08301516121bf60a08401826001600160401b03169052565b5060c08301516121da60c08401826001600160401b03169052565b5060e083015160e083015261010083015161010083015261012083015161220d6101208401826001600160401b03169052565b506101408301516101408301526101608301516101608301526101808301516122426101808401826001600160401b03169052565b506101a08301516101a08301526101c08301516101c083015292915050565b5f6060828403128015612272575f5ffd5b50604051606081016001600160401b038111828210171561229557612295611d2b565b60405282516122a381611e12565b8152602083015163ffffffff811681146122bb575f5ffd5b60208201526040928301519281019290925250919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b81810381811115611bd357611bd3612064565b5f82518060208501845e5f920191825250919050565b5f6001820161235857612358612064565b5060010190565b634e487b7160e01b5f52603260045260245ffd5b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f8301168401019150509291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212202399a769353d7bb4b4db6feb272cff380be1383a8fb873237ce53fbbac69c69364736f6c634300081e0033