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

Contract Address Details

0xed704FBE2B64436d6A65A3f7b8c128A647Ee97df

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




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




Optimization runs
200
EVM Version
prague




Verified at
2025-12-15T07:41:29.425764Z

Constructor Arguments

0x000000000000000000000000f4c259d287cc39e197b1148a198227472ca50b65000000000000000000000000638f73a482478130bea16ce151e48aec0ab283e0000000000000000000000000bb128fd4942e8143b8dc10f38ccfeadb3254426400000000000000000000000000acc4d239aa05c797e038b7701be8be6940143900000000000000000000000012100faa7b157e9947340b44409fc7e27ec0abef

Arg [0] (address) : 0xf4c259d287cc39e197b1148a198227472ca50b65
Arg [1] (address) : 0x638f73a482478130bea16ce151e48aec0ab283e0
Arg [2] (address) : 0xbb128fd4942e8143b8dc10f38ccfeadb32544264
Arg [3] (address) : 0x00acc4d239aa05c797e038b7701be8be69401439
Arg [4] (address) : 0x12100faa7b157e9947340b44409fc7e27ec0abef

              

contracts/layer1/devnet/DevnetInbox.sol

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

import { Inbox } from "src/layer1/core/impl/Inbox.sol";
import { LibFasterReentryLock } from "src/layer1/mainnet/LibFasterReentryLock.sol";

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

/// @title DevnetInbox
/// @dev This contract extends the base Inbox contract for devnet deployment
/// with optimized reentrancy lock implementation.
/// @custom:security-contact security@taiko.xyz
contract DevnetInbox is Inbox {
    // ---------------------------------------------------------------
    // Constants
    // ---------------------------------------------------------------
    /// @dev Ring buffer size for storing proposal hashes.
    /// Assumptions:
    /// - D = 2: Proposals may continue without finalization for up to 2 days.
    /// - P = 6: On average, 1 proposal is submitted every 6 Ethereum slots (≈72s).
    ///
    /// Calculation:
    ///   _RING_BUFFER_SIZE = (86400 * D) / 12 / P
    ///                     = (86400 * 2) / 12 / 6
    ///                     = 2400
    uint64 private constant _RING_BUFFER_SIZE = 100;

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

    constructor(
        address _proofVerifier,
        address _proposerChecker,
        address _proverWhitelist,
        address _signalService,
        address _codec
    )
        Inbox(Config({
                codec: _codec,
                proofVerifier: _proofVerifier,
                proposerChecker: _proposerChecker,
                proverWhitelist: _proverWhitelist,
                signalService: _signalService,
                provingWindow: 2 hours,
                maxProofSubmissionDelay: 3 minutes, // We want this to be lower than the proposal cadence
                ringBufferSize: _RING_BUFFER_SIZE,
                basefeeSharingPctg: 75,
                minForcedInclusionCount: 1,
                forcedInclusionDelay: 0,
                forcedInclusionFeeInGwei: 10_000_000, // 0.01 ETH base fee
                forcedInclusionFeeDoubleThreshold: 50, // fee doubles at 50 pending
                minCheckpointDelay: 384 seconds, // 1 epoch
                permissionlessInclusionMultiplier: 5
            }))
    { }

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

    function _storeReentryLock(uint8 _reentry) internal override {
        LibFasterReentryLock.storeReentryLock(_reentry);
    }

    function _loadReentryLock() internal view override returns (uint8) {
        return LibFasterReentryLock.loadReentryLock();
    }
}
        

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);
}
          

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
        }
    }
}
          

contracts/layer1/core/iface/IForcedInclusionStore.sol

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

import { LibBlobs } from "../libs/LibBlobs.sol";

/// @title IForcedInclusionStore
/// @custom:security-contact security@taiko.xyz
interface IForcedInclusionStore {
    /// @notice Represents a forced inclusion that will be stored onchain.
    struct ForcedInclusion {
        /// @notice The fee in Gwei that was paid to submit the forced inclusion.
        uint64 feeInGwei;
        /// @notice The proposal's blob slice.
        LibBlobs.BlobSlice blobSlice;
    }

    /// @dev Event emitted when a forced inclusion is stored.
    event ForcedInclusionSaved(ForcedInclusion forcedInclusion);

    /// @notice Saves a forced inclusion request
    /// A priority fee must be paid to the contract
    /// @dev Only one blob reference can be saved per forced inclusion
    /// @param _blobReference The blob locator that contains the transaction data
    function saveForcedInclusion(LibBlobs.BlobReference memory _blobReference) external payable;

    /// @notice Returns the current dynamic forced inclusion fee based on queue size
    /// The fee scales linearly with queue size using the formula:
    /// fee = baseFee × (1 + numPending / threshold)
    /// Examples with threshold = 100 and baseFee = 0.01 ETH:
    /// - 0 pending:   fee = 0.01 × (1 + 0/100)   = 0.01 ETH (1× base)
    /// - 50 pending:  fee = 0.01 × (1 + 50/100)  = 0.015 ETH (1.5× base)
    /// - 100 pending: fee = 0.01 × (1 + 100/100) = 0.02 ETH (2× base, DOUBLED)
    /// - 150 pending: fee = 0.01 × (1 + 150/100) = 0.025 ETH (2.5× base)
    /// - 200 pending: fee = 0.01 × (1 + 200/100) = 0.03 ETH (3× base, TRIPLED)
    /// @return feeInGwei_ The current fee in Gwei
    function getCurrentForcedInclusionFee() external view returns (uint64 feeInGwei_);

    /// @notice Returns forced inclusions stored starting from a given index.
    /// @dev Returns an empty array if `_start` is outside the valid range [head, tail) or if
    ///      `_maxCount` is zero. Otherwise returns actual stored entries from the queue.
    /// @param _start The queue index to start reading from (must be in range [head, tail)).
    /// @param _maxCount Maximum number of inclusions to return. Passing zero returns an empty
    ///        array.
    /// @return inclusions_ Forced inclusions from the queue starting at `_start`. The actual length
    ///         will be `min(_maxCount, tail - _start)`, or zero if `_start` is out of range.
    function getForcedInclusions(
        uint48 _start,
        uint48 _maxCount
    )
        external
        view
        returns (ForcedInclusion[] memory inclusions_);

    /// @notice Returns the queue pointers for the forced inclusion store.
    /// @return head_ Index of the oldest forced inclusion in the queue.
    /// @return tail_ Index of the next free slot in the queue.
    function getForcedInclusionState() external view returns (uint48 head_, uint48 tail_);
}
          

contracts/layer1/core/libs/LibProveInputCodec.sol

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

import { IInbox } from "../iface/IInbox.sol";
import { LibPackUnpack as P } from "./LibPackUnpack.sol";

/// @title LibProveInputCodec
/// @notice Compact encoder/decoder for ProveInput using LibPackUnpack.
/// @custom:security-contact security@taiko.xyz
library LibProveInputCodec {
    /// @notice Encodes ProveInput data using compact packing.
    function encode(IInbox.ProveInput memory _input) internal pure returns (bytes memory encoded_) {
        IInbox.Commitment memory c = _input.commitment;
        uint256 bufferSize = _calculateSize(c.transitions.length);
        encoded_ = new bytes(bufferSize);

        uint256 ptr = P.dataPtr(encoded_);

        ptr = P.packUint48(ptr, c.firstProposalId);
        ptr = P.packBytes32(ptr, c.firstProposalParentBlockHash);
        ptr = P.packBytes32(ptr, c.lastProposalHash);
        ptr = P.packAddress(ptr, c.actualProver);
        ptr = P.packUint48(ptr, c.endBlockNumber);
        ptr = P.packBytes32(ptr, c.endStateRoot);

        P.checkArrayLength(c.transitions.length);
        ptr = P.packUint16(ptr, uint16(c.transitions.length));
        for (uint256 i; i < c.transitions.length; ++i) {
            _encodeTransition(ptr, c.transitions[i]);
            ptr += 78; // Transition size: 20 + 20 + 6 + 32 = 78 bytes
        }

        // Encode forceCheckpointSync
        P.packUint8(ptr, _input.forceCheckpointSync ? 1 : 0);
    }

    /// @notice Decodes ProveInput data using compact packing.
    function decode(bytes memory _data) internal pure returns (IInbox.ProveInput memory input_) {
        uint256 ptr = P.dataPtr(_data);

        (input_.commitment.firstProposalId, ptr) = P.unpackUint48(ptr);
        (input_.commitment.firstProposalParentBlockHash, ptr) = P.unpackBytes32(ptr);
        (input_.commitment.lastProposalHash, ptr) = P.unpackBytes32(ptr);
        (input_.commitment.actualProver, ptr) = P.unpackAddress(ptr);
        (input_.commitment.endBlockNumber, ptr) = P.unpackUint48(ptr);
        (input_.commitment.endStateRoot, ptr) = P.unpackBytes32(ptr);

        uint16 transitionsLength;
        (transitionsLength, ptr) = P.unpackUint16(ptr);
        input_.commitment.transitions = new IInbox.Transition[](transitionsLength);
        for (uint256 i; i < transitionsLength; ++i) {
            (input_.commitment.transitions[i], ptr) = _decodeTransition(ptr);
        }

        // Decode forceCheckpointSync
        uint8 forceCheckpointSyncByte;
        (forceCheckpointSyncByte,) = P.unpackUint8(ptr);
        input_.forceCheckpointSync = forceCheckpointSyncByte != 0;
    }

    /// @dev Calculate the size needed for encoding.
    /// @param _numTransitions Number of transitions in the array.
    /// @return size_ Total byte size needed.
    function _calculateSize(uint256 _numTransitions) private pure returns (uint256 size_) {
        unchecked {
            // Fixed fields:
            //   firstProposalId: 6 bytes
            //   firstProposalParentBlockHash: 32 bytes
            //   lastProposalHash: 32 bytes
            //   actualProver: 20 bytes
            //   endBlockNumber: 6 bytes
            //   endStateRoot: 32 bytes
            //   transitions array length: 2 bytes
            //   forceCheckpointSync: 1 byte
            // Total fixed: 131 bytes
            //
            // Per Transition:
            //   proposer: 20 bytes
            //   designatedProver: 20 bytes
            //   timestamp: 6 bytes
            //   blockHash: 32 bytes
            // Total per transition: 78 bytes
            size_ = 131 + (_numTransitions * 78);
        }
    }

    function _encodeTransition(
        uint256 _ptr,
        IInbox.Transition memory _transition
    )
        private
        pure
        returns (uint256 newPtr_)
    {
        newPtr_ = P.packAddress(_ptr, _transition.proposer);
        newPtr_ = P.packAddress(newPtr_, _transition.designatedProver);
        newPtr_ = P.packUint48(newPtr_, _transition.timestamp);
        newPtr_ = P.packBytes32(newPtr_, _transition.blockHash);
    }

    function _decodeTransition(uint256 _ptr)
        private
        pure
        returns (IInbox.Transition memory transition_, uint256 newPtr_)
    {
        (transition_.proposer, newPtr_) = P.unpackAddress(_ptr);
        (transition_.designatedProver, newPtr_) = P.unpackAddress(newPtr_);
        (transition_.timestamp, newPtr_) = P.unpackUint48(newPtr_);
        (transition_.blockHash, newPtr_) = P.unpackBytes32(newPtr_);
    }
}
          

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;
}
          

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/layer1/core/libs/LibBlobs.sol

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

/// @title LibBlobs
/// @notice Library for handling blobs.
/// @custom:security-contact security@taiko.xyz
library LibBlobs {
    // ---------------------------------------------------------------
    // Constants
    // ---------------------------------------------------------------
    uint256 internal constant FIELD_ELEMENT_BYTES = 32;
    uint256 internal constant BLOB_FIELD_ELEMENTS = 4096;
    uint256 internal constant BLOB_BYTES = BLOB_FIELD_ELEMENTS * FIELD_ELEMENT_BYTES;

    // ---------------------------------------------------------------
    // Structs
    // ---------------------------------------------------------------

    /// @notice Represents a segment of data that is stored in multiple consecutive blobs created
    /// in this transaction.
    struct BlobReference {
        /// @notice The starting index of the blob.
        uint16 blobStartIndex;
        /// @notice The number of blobs.
        uint16 numBlobs;
        /// @notice The field-element offset within the blob data.
        uint24 offset;
    }

    /// @notice Represents a frame of data that is stored in multiple blobs. Note the size is
    /// encoded as a bytes32 at the offset location.
    struct BlobSlice {
        /// @notice The blobs containing the proposal's content.
        bytes32[] blobHashes;
        /// @notice The byte offset of the proposal's content in the containing blobs.
        uint24 offset;
        /// @notice The timestamp when the frame was created.
        uint48 timestamp;
    }

    // ---------------------------------------------------------------
    // Functions
    // ---------------------------------------------------------------

    /// @dev Validates a blob locator and converts it to a blob slice.
    /// @param _blobReference The blob locator to validate.
    /// @return The blob slice.
    function validateBlobReference(BlobReference memory _blobReference)
        internal
        view
        returns (BlobSlice memory)
    {
        require(_blobReference.numBlobs > 0, NoBlobs());

        bytes32[] memory blobHashes = new bytes32[](_blobReference.numBlobs);
        for (uint256 i; i < _blobReference.numBlobs; ++i) {
            blobHashes[i] = blobhash(_blobReference.blobStartIndex + i);
            require(blobHashes[i] != 0, BlobNotFound());
        }

        return BlobSlice({
            blobHashes: blobHashes,
            offset: _blobReference.offset,
            timestamp: uint48(block.timestamp)
        });
    }

    // ---------------------------------------------------------------
    // Errors
    // ---------------------------------------------------------------

    error BlobNotFound();
    error NoBlobs();
}
          

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/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);
        }
    }
}
          

contracts/layer1/core/iface/IProposerChecker.sol

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

/// @title IProposerChecker
/// @notice Interface for checking if an address is authorized to propose blocks
/// @custom:security-contact security@taiko.xyz
interface IProposerChecker {
    error InvalidProposer();

    /// @notice Checks if an address is a valid proposer
    /// @param _proposer The address to check
    /// @param _lookaheadData Encoded lookahead metadata used by preconf-aware proposer checkers.
    /// @return endOfSubmissionWindowTimestamp_ The timestamp of the last slot where the current
    /// preconfer can propose.
    /// @dev This function must revert if the address is not a valid proposer
    function checkProposer(
        address _proposer,
        bytes calldata _lookaheadData
    )
        external
        returns (uint48 endOfSubmissionWindowTimestamp_);
}
          

contracts/layer1/core/libs/LibProvedEventCodec.sol

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

import { IInbox } from "../iface/IInbox.sol";
import { LibPackUnpack as P } from "./LibPackUnpack.sol";

/// @title LibProvedEventCodec
/// @notice Compact encoder/decoder for ProvedEventPayload using LibPackUnpack.
/// @custom:security-contact security@taiko.xyz
library LibProvedEventCodec {
    /// @notice Encodes a ProvedEventPayload into bytes using compact encoding.
    function encode(IInbox.ProvedEventPayload memory _payload)
        internal
        pure
        returns (bytes memory encoded_)
    {
        IInbox.Commitment memory c = _payload.input.commitment;
        uint256 bufferSize = _calculateSize(c.transitions.length);
        encoded_ = new bytes(bufferSize);

        uint256 ptr = P.dataPtr(encoded_);

        // Encode Commitment
        ptr = P.packUint48(ptr, c.firstProposalId);
        ptr = P.packBytes32(ptr, c.firstProposalParentBlockHash);
        ptr = P.packBytes32(ptr, c.lastProposalHash);
        ptr = P.packAddress(ptr, c.actualProver);
        ptr = P.packUint48(ptr, c.endBlockNumber);
        ptr = P.packBytes32(ptr, c.endStateRoot);

        P.checkArrayLength(c.transitions.length);
        ptr = P.packUint16(ptr, uint16(c.transitions.length));
        for (uint256 i; i < c.transitions.length; ++i) {
            ptr = _encodeTransition(ptr, c.transitions[i]);
        }

        // Encode forceCheckpointSync
        P.packUint8(ptr, _payload.input.forceCheckpointSync ? 1 : 0);
    }

    /// @notice Decodes bytes into a ProvedEventPayload using compact encoding.
    function decode(bytes memory _data)
        internal
        pure
        returns (IInbox.ProvedEventPayload memory payload_)
    {
        uint256 ptr = P.dataPtr(_data);

        // Decode Commitment
        (payload_.input.commitment.firstProposalId, ptr) = P.unpackUint48(ptr);
        (payload_.input.commitment.firstProposalParentBlockHash, ptr) = P.unpackBytes32(ptr);
        (payload_.input.commitment.lastProposalHash, ptr) = P.unpackBytes32(ptr);
        (payload_.input.commitment.actualProver, ptr) = P.unpackAddress(ptr);
        (payload_.input.commitment.endBlockNumber, ptr) = P.unpackUint48(ptr);
        (payload_.input.commitment.endStateRoot, ptr) = P.unpackBytes32(ptr);

        uint16 transitionsLength;
        (transitionsLength, ptr) = P.unpackUint16(ptr);
        payload_.input.commitment.transitions = new IInbox.Transition[](transitionsLength);
        for (uint256 i; i < transitionsLength; ++i) {
            (payload_.input.commitment.transitions[i], ptr) = _decodeTransition(ptr);
        }

        // Decode forceCheckpointSync
        uint8 forceCheckpointSyncByte;
        (forceCheckpointSyncByte,) = P.unpackUint8(ptr);
        payload_.input.forceCheckpointSync = forceCheckpointSyncByte != 0;
    }

    /// @dev Calculate the exact byte size needed for encoding a ProvedEventPayload.
    /// @param _numTransitions Number of transitions in the input.
    /// @return size_ Total byte size needed.
    function _calculateSize(uint256 _numTransitions) private pure returns (uint256 size_) {
        unchecked {
            // ProveInput fixed fields:
            //   firstProposalId: 6 bytes
            //   firstProposalParentBlockHash: 32 bytes
            //   lastProposalHash: 32 bytes
            //   actualProver: 20 bytes
            //   endBlockNumber: 6 bytes
            //   endStateRoot: 32 bytes
            //   transitions array length: 2 bytes
            //   forceCheckpointSync: 1 byte
            // Total ProveInput fixed: 131 bytes
            //
            // Per Transition:
            //   proposer: 20 bytes
            //   designatedProver: 20 bytes
            //   timestamp: 6 bytes
            //   blockHash: 32 bytes
            // Total per transition: 78 bytes
            //
            // Total = 131 + (numTransitions * 78)
            size_ = 131 + (_numTransitions * 78);
        }
    }

    function _encodeTransition(
        uint256 _ptr,
        IInbox.Transition memory _transition
    )
        private
        pure
        returns (uint256 newPtr_)
    {
        newPtr_ = P.packAddress(_ptr, _transition.proposer);
        newPtr_ = P.packAddress(newPtr_, _transition.designatedProver);
        newPtr_ = P.packUint48(newPtr_, _transition.timestamp);
        newPtr_ = P.packBytes32(newPtr_, _transition.blockHash);
    }

    function _decodeTransition(uint256 _ptr)
        private
        pure
        returns (IInbox.Transition memory transition_, uint256 newPtr_)
    {
        (transition_.proposer, newPtr_) = P.unpackAddress(_ptr);
        (transition_.designatedProver, newPtr_) = P.unpackAddress(newPtr_);
        (transition_.timestamp, newPtr_) = P.unpackUint48(newPtr_);
        (transition_.blockHash, newPtr_) = P.unpackBytes32(newPtr_);
    }
}
          

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-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-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;
    }
}
          

contracts/layer1/devnet/DevnetInbox_Layout.sol

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

/// @title DevnetInboxLayout
/// @notice Storage layout documentation for DevnetInbox
/// @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
//   activationTimestamp            | uint48                                             | Slot: 251  | Offset: 0    | Bytes: 6   
//   _coreState                     | struct IInbox.CoreState                            | Slot: 252  | Offset: 0    | Bytes: 64  
//   _proposalHashes                | mapping(uint256 => bytes32)                        | Slot: 254  | Offset: 0    | Bytes: 32  
//   _forcedInclusionStorage        | struct LibForcedInclusion.Storage                  | Slot: 255  | Offset: 0    | Bytes: 64  
//   __gap                          | uint256[44]                                        | Slot: 257  | Offset: 0    | Bytes: 1408
          

contracts/layer1/core/libs/LibHashOptimized.sol

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

import { IInbox } from "../iface/IInbox.sol";
import { EfficientHashLib } from "solady/src/utils/EfficientHashLib.sol";

/// @title LibHashOptimized
/// @notice Optimized hashing functions using Solady's EfficientHashLib
/// @dev This library provides gas-optimized implementations of all hashing functions
///      used in the Inbox contract, replacing standard keccak256(abi.encode(...)) calls
///      with more efficient alternatives from Solady's EfficientHashLib.
/// @custom:security-contact security@taiko.xyz
library LibHashOptimized {
    // ---------------------------------------------------------------
    // Core Structure Hashing Functions
    // ---------------------------------------------------------------

    /// @notice Optimized hashing for Derivation structs
    /// @dev Manually constructs the ABI-encoded layout to avoid nested abi.encode calls
    /// @param _derivation The derivation to hash
    /// @return The hash of the derivation
    function hashDerivation(IInbox.Derivation memory _derivation) internal pure returns (bytes32) {
        unchecked {
            IInbox.DerivationSource[] memory sources = _derivation.sources;
            uint256 sourcesLength = sources.length;

            // Base words:
            // [0] offset to tuple head (0x20)
            // [1] originBlockNumber
            // [2] originBlockHash
            // [3] basefeeSharingPctg
            // [4] offset to sources (0x80)
            // [5] sources length
            uint256 totalWords = 6 + sourcesLength;

            // Each source contributes: element head (2) + blobSlice head (3) + blobHashes
            // length (1) + blobHashes entries
            for (uint256 i; i < sourcesLength; ++i) {
                totalWords += 6 + sources[i].blobSlice.blobHashes.length;
            }

            bytes32[] memory buffer = EfficientHashLib.malloc(totalWords);

            EfficientHashLib.set(buffer, 0, bytes32(uint256(0x20)));
            EfficientHashLib.set(buffer, 1, bytes32(uint256(_derivation.originBlockNumber)));
            EfficientHashLib.set(buffer, 2, _derivation.originBlockHash);
            EfficientHashLib.set(buffer, 3, bytes32(uint256(_derivation.basefeeSharingPctg)));
            EfficientHashLib.set(buffer, 4, bytes32(uint256(0x80)));
            EfficientHashLib.set(buffer, 5, bytes32(sourcesLength));

            uint256 offsetsBase = 6;
            uint256 dataCursor = offsetsBase + sourcesLength;

            for (uint256 i; i < sourcesLength; ++i) {
                IInbox.DerivationSource memory source = sources[i];
                EfficientHashLib.set(
                    buffer, offsetsBase + i, bytes32((dataCursor - offsetsBase) << 5)
                );

                // DerivationSource head
                EfficientHashLib.set(
                    buffer, dataCursor, bytes32(uint256(source.isForcedInclusion ? 1 : 0))
                );
                EfficientHashLib.set(buffer, dataCursor + 1, bytes32(uint256(0x40)));

                // BlobSlice head
                uint256 blobSliceBase = dataCursor + 2;
                EfficientHashLib.set(buffer, blobSliceBase, bytes32(uint256(0x60)));
                EfficientHashLib.set(
                    buffer, blobSliceBase + 1, bytes32(uint256(source.blobSlice.offset))
                );
                EfficientHashLib.set(
                    buffer, blobSliceBase + 2, bytes32(uint256(source.blobSlice.timestamp))
                );

                // Blob hashes array
                bytes32[] memory blobHashes = source.blobSlice.blobHashes;
                uint256 blobHashesLength = blobHashes.length;
                uint256 blobHashesBase = blobSliceBase + 3;
                EfficientHashLib.set(buffer, blobHashesBase, bytes32(blobHashesLength));

                for (uint256 j; j < blobHashesLength; ++j) {
                    EfficientHashLib.set(buffer, blobHashesBase + 1 + j, blobHashes[j]);
                }

                dataCursor = blobHashesBase + 1 + blobHashesLength;
            }

            bytes32 result = EfficientHashLib.hash(buffer);
            EfficientHashLib.free(buffer);
            return result;
        }
    }

    /// @notice Optimized hashing for Proposal structs
    /// @dev Uses efficient multi-field hashing for all proposal fields
    /// @param _proposal The proposal to hash
    /// @return The hash of the proposal
    function hashProposal(IInbox.Proposal memory _proposal) internal pure returns (bytes32) {
        bytes32[] memory buffer = EfficientHashLib.malloc(6);

        EfficientHashLib.set(buffer, 0, bytes32(uint256(_proposal.id)));
        EfficientHashLib.set(buffer, 1, bytes32(uint256(_proposal.timestamp)));
        EfficientHashLib.set(buffer, 2, bytes32(uint256(_proposal.endOfSubmissionWindowTimestamp)));
        EfficientHashLib.set(buffer, 3, bytes32(uint256(uint160(_proposal.proposer))));
        EfficientHashLib.set(buffer, 4, _proposal.parentProposalHash);
        EfficientHashLib.set(buffer, 5, _proposal.derivationHash);

        bytes32 result = EfficientHashLib.hash(buffer);
        EfficientHashLib.free(buffer);
        return result;
    }

    /// @notice Optimized hashing for commitment data.
    /// @param _commitment The commitment data to hash.
    /// @return The hash of the commitment.
    function hashCommitment(IInbox.Commitment memory _commitment) internal pure returns (bytes32) {
        unchecked {
            IInbox.Transition[] memory transitions = _commitment.transitions;
            uint256 transitionsLength = transitions.length;

            // Commitment layout (abi.encode):
            // [0] offset to commitment (0x20)
            //
            // Commitment static section (starts at word 1):
            // [1] firstProposalId
            // [2] firstProposalParentBlockHash
            // [3] lastProposalHash
            // [4] actualProver
            // [5] endBlockNumber
            // [6] endStateRoot
            // [7] offset to transitions (0xe0)
            //
            // Transitions array (starts at word 8):
            // [8] length
            // [9...] transition elements (4 words each)
            uint256 totalWords = 9 + transitionsLength * 4;

            bytes32[] memory buffer = EfficientHashLib.malloc(totalWords);

            // Top-level head
            EfficientHashLib.set(buffer, 0, bytes32(uint256(0x20)));

            // Commitment static fields
            EfficientHashLib.set(buffer, 1, bytes32(uint256(_commitment.firstProposalId)));
            EfficientHashLib.set(buffer, 2, _commitment.firstProposalParentBlockHash);
            EfficientHashLib.set(buffer, 3, _commitment.lastProposalHash);
            EfficientHashLib.set(buffer, 4, bytes32(uint256(uint160(_commitment.actualProver))));
            EfficientHashLib.set(buffer, 5, bytes32(uint256(_commitment.endBlockNumber)));
            EfficientHashLib.set(buffer, 6, _commitment.endStateRoot);
            EfficientHashLib.set(buffer, 7, bytes32(uint256(0xe0)));

            // Transitions array
            EfficientHashLib.set(buffer, 8, bytes32(transitionsLength));

            uint256 base = 9;
            for (uint256 i; i < transitionsLength; ++i) {
                IInbox.Transition memory transition = transitions[i];
                EfficientHashLib.set(buffer, base, bytes32(uint256(uint160(transition.proposer))));
                EfficientHashLib.set(
                    buffer, base + 1, bytes32(uint256(uint160(transition.designatedProver)))
                );
                EfficientHashLib.set(buffer, base + 2, bytes32(uint256(transition.timestamp)));
                EfficientHashLib.set(buffer, base + 3, transition.blockHash);
                base += 4;
            }

            bytes32 result = EfficientHashLib.hash(buffer);
            EfficientHashLib.free(buffer);
            return result;
        }
    }
}
          

contracts/layer1/mainnet/LibFasterReentryLock.sol

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

/// @title LibFasterReentryLock
/// @custom:security-contact security@taiko.xyz
library LibFasterReentryLock {
    /// @dev The slot in transient storage of the reentry lock.
    /// This is the result of keccak256("ownerUUPS.reentry_slot") plus 1. The addition aims to
    /// prevent hash collisions with slots defined in EIP-1967, where slots are derived by
    /// keccak256("something") - 1, and with slots in SignalService, calculated directly with
    /// keccak256("something").
    bytes32 private constant _REENTRY_SLOT =
        0xa5054f728453d3dbe953bdc43e4d0cb97e662ea32d7958190f3dc2da31d9721b;

    function storeReentryLock(uint8 _reentry) internal {
        assembly {
            tstore(_REENTRY_SLOT, _reentry)
        }
    }

    function loadReentryLock() internal view returns (uint8 reentry_) {
        assembly {
            reentry_ := tload(_REENTRY_SLOT)
        }
    }
}
          

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/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);
}
          

contracts/layer1/core/iface/IInbox.sol

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

import { LibBlobs } from "../libs/LibBlobs.sol";
import { LibBonds } from "src/shared/libs/LibBonds.sol";

/// @title IInbox
/// @notice Interface for the Shasta inbox contracts
/// @custom:security-contact security@taiko.xyz
interface IInbox {
    /// @notice Configuration struct for Inbox constructor parameters
    struct Config {
        /// @notice The codec used for encoding and hashing
        address codec;
        /// @notice The proof verifier contract
        address proofVerifier;
        /// @notice The proposer checker contract
        address proposerChecker;
        /// @notice The prover whitelist contract (address(0) means no whitelist)
        address proverWhitelist;
        /// @notice The signal service contract address
        address signalService;
        /// @notice The proving window in seconds
        uint48 provingWindow;
        /// @notice Maximum delay allowed between consecutive proofs to still be on time.
        /// @dev Must be shorter than the expected proposal cadence to prevent backlog growth.
        uint48 maxProofSubmissionDelay;
        /// @notice The ring buffer size for storing proposal hashes
        uint256 ringBufferSize;
        /// @notice The percentage of basefee paid to coinbase
        uint8 basefeeSharingPctg;
        /// @notice The minimum number of forced inclusions that the proposer is forced to process
        /// if they are due
        uint256 minForcedInclusionCount;
        /// @notice The delay for forced inclusions measured in seconds
        uint16 forcedInclusionDelay;
        /// @notice The base fee for forced inclusions in Gwei used in dynamic fee calculation
        uint64 forcedInclusionFeeInGwei;
        /// @notice Queue size at which the fee doubles
        uint64 forcedInclusionFeeDoubleThreshold;
        /// @notice The minimum delay between checkpoints in seconds
        /// @dev Must be less than or equal to finalization grace period
        uint16 minCheckpointDelay;
        /// @notice The multiplier to determine when a forced inclusion is too old so that proposing
        /// becomes permissionless
        uint8 permissionlessInclusionMultiplier;
    }

    /// @notice Represents a source of derivation data within a Derivation
    struct DerivationSource {
        /// @notice Whether this source is from a forced inclusion.
        bool isForcedInclusion;
        /// @notice Blobs that contain the source's manifest data.
        LibBlobs.BlobSlice blobSlice;
    }

    /// @notice Contains derivation data for a proposal that is not needed during proving.
    /// @dev This data is hashed and stored in the Proposal struct to reduce calldata size.
    struct Derivation {
        /// @notice The L1 block number when the proposal was accepted.
        uint48 originBlockNumber;
        /// @notice The hash of the origin block.
        bytes32 originBlockHash;
        /// @notice The percentage of base fee paid to coinbase.
        uint8 basefeeSharingPctg;
        /// @notice Array of derivation sources, where each can be regular or forced inclusion.
        DerivationSource[] sources;
    }

    /// @notice Represents a proposal for L2 blocks.
    struct Proposal {
        /// @notice Unique identifier for the proposal.
        uint48 id;
        /// @notice The L1 block timestamp when the proposal was accepted.
        uint48 timestamp;
        /// @notice The timestamp of the last slot where the current preconfer can propose.
        uint48 endOfSubmissionWindowTimestamp;
        /// @notice Address of the proposer.
        address proposer;
        /// @notice Hash of the parent proposal (zero for genesis).
        bytes32 parentProposalHash;
        /// @notice Hash of the Derivation struct containing additional proposal data.
        bytes32 derivationHash;
    }

    /// @notice Represents the core state of the inbox.
    /// @dev All 5 uint48 fields (30 bytes) pack into a single storage slot.
    struct CoreState {
        /// @notice The next proposal ID to be assigned.
        uint48 nextProposalId;
        /// @notice The last L1 block ID where a proposal was made.
        uint48 lastProposalBlockId;
        /// @notice The ID of the last finalized proposal.
        uint48 lastFinalizedProposalId;
        /// @notice The timestamp when the last proposal was finalized.
        uint48 lastFinalizedTimestamp;
        /// @notice The timestamp when the last checkpoint was saved.
        /// @dev In genesis block, this is set to 0 to allow the first checkpoint to be saved.
        uint48 lastCheckpointTimestamp;
        /// @notice The block hash of the last finalized proposal.
        bytes32 lastFinalizedBlockHash;
    }

    /// @notice Input data for the propose function
    struct ProposeInput {
        /// @notice The deadline timestamp for transaction inclusion (0 = no deadline).
        uint48 deadline;
        /// @notice Blob reference for proposal data.
        LibBlobs.BlobReference blobReference;
        /// @notice The number of forced inclusions that the proposer wants to process.
        /// @dev This can be set to 0 if no forced inclusions are due, and there's none in the queue
        /// that he wants to include.
        uint8 numForcedInclusions;
    }

    /// @notice Transition data for a proposal used in prove
    struct Transition {
        /// @notice Address of the proposer.
        address proposer;
        /// @notice Address of the designated prover.
        address designatedProver;
        /// @notice Timestamp of the proposal.
        uint48 timestamp;
        /// @notice end block hash for the proposal.
        bytes32 blockHash;
    }

    /// @notice Commitment data that the prover commits to when submitting a proof.
    struct Commitment {
        /// @notice The ID of the first proposal being proven.
        uint48 firstProposalId;
        /// @notice The checkpoint hash of the parent of the first proposal, this is used
        /// to verify checkpoint continuity in the proof.
        bytes32 firstProposalParentBlockHash;
        /// @notice The hash of the last proposal being proven.
        bytes32 lastProposalHash;
        /// @notice The actual prover who generated the proof.
        address actualProver;
        /// @notice The block number for the end L2 block in this proposal.
        uint48 endBlockNumber;
        /// @notice The state root for the end L2 block in this proposal.
        bytes32 endStateRoot;
        /// @notice Array of transitions for each proposal in the proof range.
        Transition[] transitions;
    }

    /// @notice Input data for the prove function.
    /// @dev This struct contains two categories of data:
    ///      1. Commitment data - What the prover is actually proving. This must be fully
    ///         determined before proof generation and is the only input to the prover's
    ///         guest program.
    ///      2. Usage options - Parameters that can be decided after proof generation
    ///         (e.g., whether to proactively write a checkpoint). The prover system can
    ///         choose or adjust these options using additional data during or after
    ///         proof generation.
    struct ProveInput {
        /// @notice The commitment data that the proof verifies.
        Commitment commitment;
        /// @notice Whether to force syncing the last checkpoint even if the minimum
        /// delay has not passed.
        /// @dev This allows checkpoint synchronization ahead of schedule.
        bool forceCheckpointSync;
    }

    /// @notice Payload data emitted in the Proposed event
    struct ProposedEventPayload {
        /// @notice The proposal that was created.
        Proposal proposal;
        /// @notice The derivation data for the proposal.
        Derivation derivation;
    }

    /// @notice Payload data emitted in the Proved event
    struct ProvedEventPayload {
        ProveInput input;
    }

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

    /// @notice Emitted when a new proposal is proposed.
    /// @param data The encoded ProposedEventPayload
    event Proposed(bytes data);

    /// @notice Emitted when a proof is submitted
    /// @param data The encoded ProvedEventPayload
    event Proved(bytes data);

    /// @notice Emitted when a bond instruction is signaled to L2
    /// @param proposalId The proposal ID that triggered the bond instruction
    /// @param bondInstruction The encoded bond instruction
    event BondInstructionCreated(
        uint48 indexed proposalId, LibBonds.BondInstruction bondInstruction
    );

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

    /// @notice Proposes new L2 blocks and forced inclusions to the rollup using blobs for DA.
    /// @param _lookahead Encoded data forwarded to the proposer checker (i.e. lookahead payloads).
    /// @param _data The encoded ProposeInput struct.
    function propose(bytes calldata _lookahead, bytes calldata _data) external;

    /// @notice Verifies a batch proof covering multiple consecutive proposals and finalizes them.
    /// @param _data The encoded ProveInput struct.
    /// @param _proof The validity proof for the batch of proposals.
    function prove(bytes calldata _data, bytes calldata _proof) external;

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

    /// @notice Returns the configuration parameters of the Inbox contract
    /// @return config_ The configuration struct containing all immutable parameters
    function getConfig() external view returns (Config memory config_);

    /// @notice Returns the current core state.
    /// @return The core state struct.
    function getCoreState() external view returns (CoreState memory);

    /// @notice Returns the proposal hash for a given proposal ID.
    /// @param _proposalId The proposal ID to look up.
    /// @return proposalHash_ The hash stored at the proposal's ring buffer slot.
    function getProposalHash(uint256 _proposalId) external view returns (bytes32 proposalHash_);
}
          

node_modules/solady/src/utils/EfficientHashLib.sol

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

/// @notice Library for efficiently performing keccak256 hashes.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/EfficientHashLib.sol)
/// @dev To avoid stack-too-deep, you can use:
/// ```
/// bytes32[] memory buffer = EfficientHashLib.malloc(10);
/// EfficientHashLib.set(buffer, 0, value0);
/// ..
/// EfficientHashLib.set(buffer, 9, value9);
/// bytes32 finalHash = EfficientHashLib.hash(buffer);
/// ```
library EfficientHashLib {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*               MALLOC-LESS HASHING OPERATIONS               */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns `keccak256(abi.encode(v0))`.
    function hash(bytes32 v0) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, v0)
            result := keccak256(0x00, 0x20)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0))`.
    function hash(uint256 v0) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, v0)
            result := keccak256(0x00, 0x20)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, v1))`.
    function hash(bytes32 v0, bytes32 v1) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, v0)
            mstore(0x20, v1)
            result := keccak256(0x00, 0x40)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, v1))`.
    function hash(uint256 v0, uint256 v1) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, v0)
            mstore(0x20, v1)
            result := keccak256(0x00, 0x40)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, v1, v2))`.
    function hash(bytes32 v0, bytes32 v1, bytes32 v2) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            result := keccak256(m, 0x60)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, v1, v2))`.
    function hash(uint256 v0, uint256 v1, uint256 v2) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            result := keccak256(m, 0x60)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, v1, v2, v3))`.
    function hash(bytes32 v0, bytes32 v1, bytes32 v2, bytes32 v3)
        internal
        pure
        returns (bytes32 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            result := keccak256(m, 0x80)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, v1, v2, v3))`.
    function hash(uint256 v0, uint256 v1, uint256 v2, uint256 v3)
        internal
        pure
        returns (bytes32 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            result := keccak256(m, 0x80)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v4))`.
    function hash(bytes32 v0, bytes32 v1, bytes32 v2, bytes32 v3, bytes32 v4)
        internal
        pure
        returns (bytes32 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            result := keccak256(m, 0xa0)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v4))`.
    function hash(uint256 v0, uint256 v1, uint256 v2, uint256 v3, uint256 v4)
        internal
        pure
        returns (bytes32 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            result := keccak256(m, 0xa0)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v5))`.
    function hash(bytes32 v0, bytes32 v1, bytes32 v2, bytes32 v3, bytes32 v4, bytes32 v5)
        internal
        pure
        returns (bytes32 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            result := keccak256(m, 0xc0)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v5))`.
    function hash(uint256 v0, uint256 v1, uint256 v2, uint256 v3, uint256 v4, uint256 v5)
        internal
        pure
        returns (bytes32 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            result := keccak256(m, 0xc0)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v6))`.
    function hash(
        bytes32 v0,
        bytes32 v1,
        bytes32 v2,
        bytes32 v3,
        bytes32 v4,
        bytes32 v5,
        bytes32 v6
    ) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            mstore(add(m, 0xc0), v6)
            result := keccak256(m, 0xe0)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v6))`.
    function hash(
        uint256 v0,
        uint256 v1,
        uint256 v2,
        uint256 v3,
        uint256 v4,
        uint256 v5,
        uint256 v6
    ) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            mstore(add(m, 0xc0), v6)
            result := keccak256(m, 0xe0)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v7))`.
    function hash(
        bytes32 v0,
        bytes32 v1,
        bytes32 v2,
        bytes32 v3,
        bytes32 v4,
        bytes32 v5,
        bytes32 v6,
        bytes32 v7
    ) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            mstore(add(m, 0xc0), v6)
            mstore(add(m, 0xe0), v7)
            result := keccak256(m, 0x100)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v7))`.
    function hash(
        uint256 v0,
        uint256 v1,
        uint256 v2,
        uint256 v3,
        uint256 v4,
        uint256 v5,
        uint256 v6,
        uint256 v7
    ) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            mstore(add(m, 0xc0), v6)
            mstore(add(m, 0xe0), v7)
            result := keccak256(m, 0x100)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v8))`.
    function hash(
        bytes32 v0,
        bytes32 v1,
        bytes32 v2,
        bytes32 v3,
        bytes32 v4,
        bytes32 v5,
        bytes32 v6,
        bytes32 v7,
        bytes32 v8
    ) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            mstore(add(m, 0xc0), v6)
            mstore(add(m, 0xe0), v7)
            mstore(add(m, 0x100), v8)
            result := keccak256(m, 0x120)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v8))`.
    function hash(
        uint256 v0,
        uint256 v1,
        uint256 v2,
        uint256 v3,
        uint256 v4,
        uint256 v5,
        uint256 v6,
        uint256 v7,
        uint256 v8
    ) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            mstore(add(m, 0xc0), v6)
            mstore(add(m, 0xe0), v7)
            mstore(add(m, 0x100), v8)
            result := keccak256(m, 0x120)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v9))`.
    function hash(
        bytes32 v0,
        bytes32 v1,
        bytes32 v2,
        bytes32 v3,
        bytes32 v4,
        bytes32 v5,
        bytes32 v6,
        bytes32 v7,
        bytes32 v8,
        bytes32 v9
    ) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            mstore(add(m, 0xc0), v6)
            mstore(add(m, 0xe0), v7)
            mstore(add(m, 0x100), v8)
            mstore(add(m, 0x120), v9)
            result := keccak256(m, 0x140)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v9))`.
    function hash(
        uint256 v0,
        uint256 v1,
        uint256 v2,
        uint256 v3,
        uint256 v4,
        uint256 v5,
        uint256 v6,
        uint256 v7,
        uint256 v8,
        uint256 v9
    ) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            mstore(add(m, 0xc0), v6)
            mstore(add(m, 0xe0), v7)
            mstore(add(m, 0x100), v8)
            mstore(add(m, 0x120), v9)
            result := keccak256(m, 0x140)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v10))`.
    function hash(
        bytes32 v0,
        bytes32 v1,
        bytes32 v2,
        bytes32 v3,
        bytes32 v4,
        bytes32 v5,
        bytes32 v6,
        bytes32 v7,
        bytes32 v8,
        bytes32 v9,
        bytes32 v10
    ) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            mstore(add(m, 0xc0), v6)
            mstore(add(m, 0xe0), v7)
            mstore(add(m, 0x100), v8)
            mstore(add(m, 0x120), v9)
            mstore(add(m, 0x140), v10)
            result := keccak256(m, 0x160)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v10))`.
    function hash(
        uint256 v0,
        uint256 v1,
        uint256 v2,
        uint256 v3,
        uint256 v4,
        uint256 v5,
        uint256 v6,
        uint256 v7,
        uint256 v8,
        uint256 v9,
        uint256 v10
    ) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            mstore(add(m, 0xc0), v6)
            mstore(add(m, 0xe0), v7)
            mstore(add(m, 0x100), v8)
            mstore(add(m, 0x120), v9)
            mstore(add(m, 0x140), v10)
            result := keccak256(m, 0x160)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v11))`.
    function hash(
        bytes32 v0,
        bytes32 v1,
        bytes32 v2,
        bytes32 v3,
        bytes32 v4,
        bytes32 v5,
        bytes32 v6,
        bytes32 v7,
        bytes32 v8,
        bytes32 v9,
        bytes32 v10,
        bytes32 v11
    ) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            mstore(add(m, 0xc0), v6)
            mstore(add(m, 0xe0), v7)
            mstore(add(m, 0x100), v8)
            mstore(add(m, 0x120), v9)
            mstore(add(m, 0x140), v10)
            mstore(add(m, 0x160), v11)
            result := keccak256(m, 0x180)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v11))`.
    function hash(
        uint256 v0,
        uint256 v1,
        uint256 v2,
        uint256 v3,
        uint256 v4,
        uint256 v5,
        uint256 v6,
        uint256 v7,
        uint256 v8,
        uint256 v9,
        uint256 v10,
        uint256 v11
    ) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            mstore(add(m, 0xc0), v6)
            mstore(add(m, 0xe0), v7)
            mstore(add(m, 0x100), v8)
            mstore(add(m, 0x120), v9)
            mstore(add(m, 0x140), v10)
            mstore(add(m, 0x160), v11)
            result := keccak256(m, 0x180)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v12))`.
    function hash(
        bytes32 v0,
        bytes32 v1,
        bytes32 v2,
        bytes32 v3,
        bytes32 v4,
        bytes32 v5,
        bytes32 v6,
        bytes32 v7,
        bytes32 v8,
        bytes32 v9,
        bytes32 v10,
        bytes32 v11,
        bytes32 v12
    ) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            mstore(add(m, 0xc0), v6)
            mstore(add(m, 0xe0), v7)
            mstore(add(m, 0x100), v8)
            mstore(add(m, 0x120), v9)
            mstore(add(m, 0x140), v10)
            mstore(add(m, 0x160), v11)
            mstore(add(m, 0x180), v12)
            result := keccak256(m, 0x1a0)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v12))`.
    function hash(
        uint256 v0,
        uint256 v1,
        uint256 v2,
        uint256 v3,
        uint256 v4,
        uint256 v5,
        uint256 v6,
        uint256 v7,
        uint256 v8,
        uint256 v9,
        uint256 v10,
        uint256 v11,
        uint256 v12
    ) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            mstore(add(m, 0xc0), v6)
            mstore(add(m, 0xe0), v7)
            mstore(add(m, 0x100), v8)
            mstore(add(m, 0x120), v9)
            mstore(add(m, 0x140), v10)
            mstore(add(m, 0x160), v11)
            mstore(add(m, 0x180), v12)
            result := keccak256(m, 0x1a0)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v13))`.
    function hash(
        bytes32 v0,
        bytes32 v1,
        bytes32 v2,
        bytes32 v3,
        bytes32 v4,
        bytes32 v5,
        bytes32 v6,
        bytes32 v7,
        bytes32 v8,
        bytes32 v9,
        bytes32 v10,
        bytes32 v11,
        bytes32 v12,
        bytes32 v13
    ) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            mstore(add(m, 0xc0), v6)
            mstore(add(m, 0xe0), v7)
            mstore(add(m, 0x100), v8)
            mstore(add(m, 0x120), v9)
            mstore(add(m, 0x140), v10)
            mstore(add(m, 0x160), v11)
            mstore(add(m, 0x180), v12)
            mstore(add(m, 0x1a0), v13)
            result := keccak256(m, 0x1c0)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v13))`.
    function hash(
        uint256 v0,
        uint256 v1,
        uint256 v2,
        uint256 v3,
        uint256 v4,
        uint256 v5,
        uint256 v6,
        uint256 v7,
        uint256 v8,
        uint256 v9,
        uint256 v10,
        uint256 v11,
        uint256 v12,
        uint256 v13
    ) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            mstore(add(m, 0xc0), v6)
            mstore(add(m, 0xe0), v7)
            mstore(add(m, 0x100), v8)
            mstore(add(m, 0x120), v9)
            mstore(add(m, 0x140), v10)
            mstore(add(m, 0x160), v11)
            mstore(add(m, 0x180), v12)
            mstore(add(m, 0x1a0), v13)
            result := keccak256(m, 0x1c0)
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*             BYTES32 BUFFER HASHING OPERATIONS              */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns `keccak256(abi.encode(buffer[0], .., buffer[buffer.length - 1]))`.
    function hash(bytes32[] memory buffer) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            result := keccak256(add(buffer, 0x20), shl(5, mload(buffer)))
        }
    }

    /// @dev Sets `buffer[i]` to `value`, without a bounds check.
    /// Returns the `buffer` for function chaining.
    function set(bytes32[] memory buffer, uint256 i, bytes32 value)
        internal
        pure
        returns (bytes32[] memory)
    {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(add(buffer, shl(5, add(1, i))), value)
        }
        return buffer;
    }

    /// @dev Sets `buffer[i]` to `value`, without a bounds check.
    /// Returns the `buffer` for function chaining.
    function set(bytes32[] memory buffer, uint256 i, uint256 value)
        internal
        pure
        returns (bytes32[] memory)
    {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(add(buffer, shl(5, add(1, i))), value)
        }
        return buffer;
    }

    /// @dev Returns `new bytes32[](n)`, without zeroing out the memory.
    function malloc(uint256 n) internal pure returns (bytes32[] memory buffer) {
        /// @solidity memory-safe-assembly
        assembly {
            buffer := mload(0x40)
            mstore(buffer, n)
            mstore(0x40, add(shl(5, add(1, n)), buffer))
        }
    }

    /// @dev Frees memory that has been allocated for `buffer`.
    /// No-op if `buffer.length` is zero, or if new memory has been allocated after `buffer`.
    function free(bytes32[] memory buffer) internal pure {
        /// @solidity memory-safe-assembly
        assembly {
            let n := mload(buffer)
            mstore(shl(6, lt(iszero(n), eq(add(shl(5, add(1, n)), buffer), mload(0x40)))), buffer)
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                      EQUALITY CHECKS                       */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns `a == abi.decode(b, (bytes32))`.
    function eq(bytes32 a, bytes memory b) internal pure returns (bool result) {
        /// @solidity memory-safe-assembly
        assembly {
            result := and(eq(0x20, mload(b)), eq(a, mload(add(b, 0x20))))
        }
    }

    /// @dev Returns `abi.decode(a, (bytes32)) == a`.
    function eq(bytes memory a, bytes32 b) internal pure returns (bool result) {
        /// @solidity memory-safe-assembly
        assembly {
            result := and(eq(0x20, mload(a)), eq(b, mload(add(a, 0x20))))
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*               BYTE SLICE HASHING OPERATIONS                */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns the keccak256 of the slice from `start` to `end` (exclusive).
    /// `start` and `end` are byte offsets.
    function hash(bytes memory b, uint256 start, uint256 end)
        internal
        pure
        returns (bytes32 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let n := mload(b)
            end := xor(end, mul(xor(end, n), lt(n, end)))
            start := xor(start, mul(xor(start, n), lt(n, start)))
            result := keccak256(add(add(b, 0x20), start), mul(gt(end, start), sub(end, start)))
        }
    }

    /// @dev Returns the keccak256 of the slice from `start` to the end of the bytes.
    function hash(bytes memory b, uint256 start) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let n := mload(b)
            start := xor(start, mul(xor(start, n), lt(n, start)))
            result := keccak256(add(add(b, 0x20), start), mul(gt(n, start), sub(n, start)))
        }
    }

    /// @dev Returns the keccak256 of the bytes.
    function hash(bytes memory b) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            result := keccak256(add(b, 0x20), mload(b))
        }
    }

    /// @dev Returns the keccak256 of the slice from `start` to `end` (exclusive).
    /// `start` and `end` are byte offsets.
    function hashCalldata(bytes calldata b, uint256 start, uint256 end)
        internal
        pure
        returns (bytes32 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            end := xor(end, mul(xor(end, b.length), lt(b.length, end)))
            start := xor(start, mul(xor(start, b.length), lt(b.length, start)))
            let n := mul(gt(end, start), sub(end, start))
            calldatacopy(mload(0x40), add(b.offset, start), n)
            result := keccak256(mload(0x40), n)
        }
    }

    /// @dev Returns the keccak256 of the slice from `start` to the end of the bytes.
    function hashCalldata(bytes calldata b, uint256 start) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            start := xor(start, mul(xor(start, b.length), lt(b.length, start)))
            let n := mul(gt(b.length, start), sub(b.length, start))
            calldatacopy(mload(0x40), add(b.offset, start), n)
            result := keccak256(mload(0x40), n)
        }
    }

    /// @dev Returns the keccak256 of the bytes.
    function hashCalldata(bytes calldata b) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            calldatacopy(mload(0x40), b.offset, b.length)
            result := keccak256(mload(0x40), b.length)
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                      SHA2-256 HELPERS                      */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns `sha256(abi.encode(b))`. Yes, it's more efficient.
    function sha2(bytes32 b) internal view returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, b)
            result := mload(staticcall(gas(), 2, 0x00, 0x20, 0x01, 0x20))
            if iszero(returndatasize()) { invalid() }
        }
    }

    /// @dev Returns the sha256 of the slice from `start` to `end` (exclusive).
    /// `start` and `end` are byte offsets.
    function sha2(bytes memory b, uint256 start, uint256 end)
        internal
        view
        returns (bytes32 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let n := mload(b)
            end := xor(end, mul(xor(end, n), lt(n, end)))
            start := xor(start, mul(xor(start, n), lt(n, start)))
            // forgefmt: disable-next-item
            result := mload(staticcall(gas(), 2, add(add(b, 0x20), start),
                mul(gt(end, start), sub(end, start)), 0x01, 0x20))
            if iszero(returndatasize()) { invalid() }
        }
    }

    /// @dev Returns the sha256 of the slice from `start` to the end of the bytes.
    function sha2(bytes memory b, uint256 start) internal view returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let n := mload(b)
            start := xor(start, mul(xor(start, n), lt(n, start)))
            // forgefmt: disable-next-item
            result := mload(staticcall(gas(), 2, add(add(b, 0x20), start),
                mul(gt(n, start), sub(n, start)), 0x01, 0x20))
            if iszero(returndatasize()) { invalid() }
        }
    }

    /// @dev Returns the sha256 of the bytes.
    function sha2(bytes memory b) internal view returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            result := mload(staticcall(gas(), 2, add(b, 0x20), mload(b), 0x01, 0x20))
            if iszero(returndatasize()) { invalid() }
        }
    }

    /// @dev Returns the sha256 of the slice from `start` to `end` (exclusive).
    /// `start` and `end` are byte offsets.
    function sha2Calldata(bytes calldata b, uint256 start, uint256 end)
        internal
        view
        returns (bytes32 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            end := xor(end, mul(xor(end, b.length), lt(b.length, end)))
            start := xor(start, mul(xor(start, b.length), lt(b.length, start)))
            let n := mul(gt(end, start), sub(end, start))
            calldatacopy(mload(0x40), add(b.offset, start), n)
            result := mload(staticcall(gas(), 2, mload(0x40), n, 0x01, 0x20))
            if iszero(returndatasize()) { invalid() }
        }
    }

    /// @dev Returns the sha256 of the slice from `start` to the end of the bytes.
    function sha2Calldata(bytes calldata b, uint256 start) internal view returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            start := xor(start, mul(xor(start, b.length), lt(b.length, start)))
            let n := mul(gt(b.length, start), sub(b.length, start))
            calldatacopy(mload(0x40), add(b.offset, start), n)
            result := mload(staticcall(gas(), 2, mload(0x40), n, 0x01, 0x20))
            if iszero(returndatasize()) { invalid() }
        }
    }

    /// @dev Returns the sha256 of the bytes.
    function sha2Calldata(bytes calldata b) internal view returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            calldatacopy(mload(0x40), b.offset, b.length)
            result := mload(staticcall(gas(), 2, mload(0x40), b.length, 0x01, 0x20))
            if iszero(returndatasize()) { invalid() }
        }
    }
}
          

contracts/layer1/core/impl/Inbox.sol

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

import { IForcedInclusionStore } from "../iface/IForcedInclusionStore.sol";
import { IInbox } from "../iface/IInbox.sol";
import { IProposerChecker } from "../iface/IProposerChecker.sol";
import { IProverWhitelist } from "../iface/IProverWhitelist.sol";
import { LibBlobs } from "../libs/LibBlobs.sol";
import { LibForcedInclusion } from "../libs/LibForcedInclusion.sol";
import { LibHashOptimized } from "../libs/LibHashOptimized.sol";
import { LibInboxSetup } from "../libs/LibInboxSetup.sol";
import { LibProposeInputCodec } from "../libs/LibProposeInputCodec.sol";
import { LibProposedEventCodec } from "../libs/LibProposedEventCodec.sol";
import { LibProveInputCodec } from "../libs/LibProveInputCodec.sol";
import { LibProvedEventCodec } from "../libs/LibProvedEventCodec.sol";
import { IProofVerifier } from "src/layer1/verifiers/IProofVerifier.sol";
import { EssentialContract } from "src/shared/common/EssentialContract.sol";
import { LibAddress } from "src/shared/libs/LibAddress.sol";
import { LibBonds } from "src/shared/libs/LibBonds.sol";
import { LibMath } from "src/shared/libs/LibMath.sol";
import { ICheckpointStore } from "src/shared/signal/ICheckpointStore.sol";
import { ISignalService } from "src/shared/signal/ISignalService.sol";

/// @title Inbox
/// @notice Core contract for managing L2 proposals, proof verification, and forced inclusion in
/// Taiko's based rollup architecture.
/// @dev The Pacaya inbox contract is not being upgraded to the Shasta implementation;
///      instead, Shasta uses a separate inbox address.
/// @dev This contract implements the fundamental inbox logic including:
///      - Proposal submission with forced inclusion support
///      - Sequential proof verification
///      - Ring buffer storage for efficient state management
///      - Bond instruction calculation(but actual funds are managed on L2)
///      - Finalization of proven proposals with checkpoint rate limiting
/// @custom:security-contact security@taiko.xyz
contract Inbox is IInbox, IForcedInclusionStore, EssentialContract {
    using LibAddress for address;
    using LibMath for uint48;
    using LibMath for uint256;

    // ---------------------------------------------------------------
    // Structs
    // ---------------------------------------------------------------

    /// @notice Result from consuming forced inclusions
    struct ConsumptionResult {
        DerivationSource[] sources;
        bool allowsPermissionless;
    }

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

    event InboxActivated(bytes32 lastPacayaBlockHash);

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

    /// @notice The codec used for encoding and hashing.
    address internal immutable _codec;

    /// @notice The proof verifier contract.
    IProofVerifier internal immutable _proofVerifier;

    /// @notice The proposer checker contract.
    IProposerChecker internal immutable _proposerChecker;

    /// @notice The prover whitelist contract (address(0) means no whitelist)
    IProverWhitelist internal immutable _proverWhitelist;

    /// @notice Signal service responsible for checkpoints and bond signals.
    ISignalService internal immutable _signalService;

    /// @notice The proving window in seconds.
    uint48 internal immutable _provingWindow;

    /// @notice Maximum delay allowed between sequential proofs to remain on time.
    uint48 internal immutable _maxProofSubmissionDelay;

    /// @notice The ring buffer size for storing proposal hashes.
    uint256 internal immutable _ringBufferSize;

    /// @notice The percentage of basefee paid to coinbase.
    uint8 internal immutable _basefeeSharingPctg;

    /// @notice The minimum number of forced inclusions that the proposer is forced to process if
    /// they are due.
    uint256 internal immutable _minForcedInclusionCount;

    /// @notice The delay for forced inclusions measured in seconds.
    uint16 internal immutable _forcedInclusionDelay;

    /// @notice The base fee for forced inclusions in Gwei.
    uint64 internal immutable _forcedInclusionFeeInGwei;

    /// @notice Queue size at which the fee doubles. See Config for formula details.
    uint64 internal immutable _forcedInclusionFeeDoubleThreshold;

    /// @notice The minimum delay between checkpoints in seconds.
    uint16 internal immutable _minCheckpointDelay;

    /// @notice The multiplier to determine when a forced inclusion is too old so that proposing
    /// becomes permissionless
    uint8 internal immutable _permissionlessInclusionMultiplier;

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

    /// @notice The timestamp when the first activation occurred.
    uint48 public activationTimestamp;

    /// @notice Persisted core state.
    CoreState internal _coreState;

    /// @dev Ring buffer for storing proposal hashes indexed by buffer slot
    /// - bufferSlot: The ring buffer slot calculated as proposalId % ringBufferSize
    /// - proposalHash: The keccak256 hash of the Proposal struct
    mapping(uint256 bufferSlot => bytes32 proposalHash) internal _proposalHashes;

    /// @dev Storage for forced inclusion requests
    /// @dev 2 slots used
    LibForcedInclusion.Storage private _forcedInclusionStorage;

    uint256[44] private __gap;

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

    /// @notice Initializes the Inbox contract
    /// @param _config Configuration struct containing all constructor parameters
    constructor(Config memory _config) {
        LibInboxSetup.validateConfig(_config);

        _codec = _config.codec;
        _proofVerifier = IProofVerifier(_config.proofVerifier);
        _proposerChecker = IProposerChecker(_config.proposerChecker);
        _proverWhitelist = IProverWhitelist(_config.proverWhitelist);
        _signalService = ISignalService(_config.signalService);
        _provingWindow = _config.provingWindow;
        _maxProofSubmissionDelay = _config.maxProofSubmissionDelay;
        _ringBufferSize = _config.ringBufferSize;
        _basefeeSharingPctg = _config.basefeeSharingPctg;
        _minForcedInclusionCount = _config.minForcedInclusionCount;
        _forcedInclusionDelay = _config.forcedInclusionDelay;
        _forcedInclusionFeeInGwei = _config.forcedInclusionFeeInGwei;
        _forcedInclusionFeeDoubleThreshold = _config.forcedInclusionFeeDoubleThreshold;
        _minCheckpointDelay = _config.minCheckpointDelay;
        _permissionlessInclusionMultiplier = _config.permissionlessInclusionMultiplier;
    }

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

    /// @notice Initializes the owner of the inbox.
    /// @param _owner The owner of this contract
    function init(address _owner) external initializer {
        __Essential_init(_owner);
    }

    /// @notice Activates the inbox so that it can start accepting proposals.
    /// @dev Can be called multiple times within the activation window to handle reorgs.
    /// @param _lastPacayaBlockHash The block hash of the last Pacaya block
    function activate(bytes32 _lastPacayaBlockHash) external onlyOwner {
        (
            uint48 newActivationTimestamp,
            CoreState memory state,
            Derivation memory derivation,
            Proposal memory proposal,
            bytes32 genesisProposalHash
        ) = LibInboxSetup.activate(_lastPacayaBlockHash, activationTimestamp);

        activationTimestamp = newActivationTimestamp;
        _coreState = state;
        _setProposalHash(0, genesisProposalHash);
        _emitProposedEvent(proposal, derivation);
        emit InboxActivated(_lastPacayaBlockHash);
    }

    /// @inheritdoc IInbox
    /// @notice Proposes new L2 blocks and forced inclusions to the rollup using blobs for DA.
    /// @dev Key behaviors:
    ///      1. Validates proposer authorization via `IProposerChecker`
    ///      2. Process `input.numForcedInclusions` forced inclusions. The proposer is forced to
    ///         process at least `config.minForcedInclusionCount` if they are due.
    ///      3. Updates core state and emits `Proposed` event
    /// NOTE: This function can only be called once per block to prevent spams that can fill the
    /// ring buffer.
    function propose(bytes calldata _lookahead, bytes calldata _data) external nonReentrant {
        unchecked {
            ProposeInput memory input = LibProposeInputCodec.decode(_data);
            _validateProposeInput(input);

            uint48 nextProposalId = _coreState.nextProposalId;
            uint48 lastProposalBlockId = _coreState.lastProposalBlockId;
            uint48 lastFinalizedProposalId = _coreState.lastFinalizedProposalId;
            require(nextProposalId > 0, ActivationRequired());

            (Proposal memory proposal, Derivation memory derivation) = _buildProposal(
                input, _lookahead, nextProposalId, lastProposalBlockId, lastFinalizedProposalId
            );

            _coreState.nextProposalId = nextProposalId + 1;
            _coreState.lastProposalBlockId = uint48(block.number);
            _setProposalHash(proposal.id, LibHashOptimized.hashProposal(proposal));

            _emitProposedEvent(proposal, derivation);
        }
    }

    /// @inheritdoc IInbox
    ///
    /// @dev The proof covers a contiguous range of proposals. The input contains an array of
    /// Transition structs, each with the proposal's metadata and checkpoint hash. The proof range
    /// can start at or before the last finalized proposal to handle race conditions where
    /// proposals get finalized between proof generation and submission.
    ///
    /// Example: Proving proposals 3-7 when lastFinalizedProposalId=4
    ///
    ///       lastFinalizedProposalId                nextProposalId
    ///                             ┆                             ┆
    ///                             ▼                             ▼
    ///     0     1     2     3     4     5     6     7     8     9
    ///     ■─────■─────■─────■─────■─────□─────□─────□─────□─────
    ///                       ▲           ▲                 ▲
    ///                       ┆<-offset-> ┆                 ┆
    ///                       ┆                             ┆
    ///                       ┆<-    input.transitions[]   ->┆
    ///         firstProposalId                             lastProposalId
    ///
    /// Key validation rules:
    /// 1. firstProposalId <= lastFinalizedProposalId + 1 (can overlap with finalized range)
    /// 2. lastProposalId < nextProposalId (cannot prove unproposed blocks)
    /// 3. lastProposalId >= lastFinalizedProposalId + 1 (must advance at least one proposal)
    /// 4. The block hash must link to the lastFinalizedBlockHash
    ///
    /// @param _data Encoded ProveInput struct
    /// @param _proof Validity proof for the batch of proposals
    function prove(bytes calldata _data, bytes calldata _proof) external {
        unchecked {

            bool isWhitelistEnabled = _checkProver(msg.sender);
            CoreState memory state = _coreState;
            ProveInput memory input = LibProveInputCodec.decode(_data);

            // -------------------------------------------------------------------------------
            // 1. Validate batch bounds and calculate offset of the first unfinalized proposal
            // -------------------------------------------------------------------------------
            Commitment memory commitment = input.commitment;

            // `offset` is the index of the next-to-finalize proposal in the transitions array.
            (uint256 numProposals, uint256 lastProposalId, uint48 offset) =
                _validateCommitment(state, commitment);

            // ---------------------------------------------------------
            // 2. Verify checkpoint hash continuity and last proposal hash
            // ---------------------------------------------------------
            // The parent block hash must match the stored lastFinalizedBlockHash.
            bytes32 expectedParentHash = offset == 0
                ? commitment.firstProposalParentBlockHash
                : commitment.transitions[offset - 1].blockHash;
            require(state.lastFinalizedBlockHash == expectedParentHash, ParentBlockHashMismatch());

            require(
                commitment.lastProposalHash == getProposalHash(lastProposalId),
                LastProposalHashMismatch()
            );

            // ---------------------------------------------------------
            // 3. Process bond instruction
            // ---------------------------------------------------------
            // Bond transfers only apply when whitelist is not enabled.
            if (!isWhitelistEnabled) {
                _processBondInstruction(commitment, offset);
            }

            // -----------------------------------------------------------------------------
            // 4. Sync checkpoint
            // -----------------------------------------------------------------------------
            if (
                input.forceCheckpointSync
                    || block.timestamp >= state.lastCheckpointTimestamp + _minCheckpointDelay
            ) {
                _signalService.saveCheckpoint(
                    ICheckpointStore.Checkpoint({
                        blockNumber: commitment.endBlockNumber,
                        stateRoot: commitment.endStateRoot,
                        blockHash: commitment.transitions[numProposals - 1].blockHash
                    })
                );
                state.lastCheckpointTimestamp = uint48(block.timestamp);
            }

            // ---------------------------------------------------------
            // 5. Update core state and emit event
            // ---------------------------------------------------------
            state.lastFinalizedProposalId = uint48(lastProposalId);
            state.lastFinalizedTimestamp = uint48(block.timestamp);
            state.lastFinalizedBlockHash = commitment.transitions[numProposals - 1].blockHash;

            _coreState = state;
            emit Proved(LibProvedEventCodec.encode(ProvedEventPayload(input)));

            // ---------------------------------------------------------
            // 6. Verify the proof
            // ---------------------------------------------------------
            // We count the proposalAge as the time since it became available for proving.
            uint256 proposalAge = block.timestamp
                - commitment.transitions[offset].timestamp.max(state.lastFinalizedTimestamp);
            _proofVerifier.verifyProof(
                proposalAge, LibHashOptimized.hashCommitment(commitment), _proof
            );
        }
    }

    /// @inheritdoc IForcedInclusionStore
    /// @dev This function will revert if called before the first non-activation proposal is
    /// submitted to make sure blocks have been produced already and the derivation can use the
    /// parent's block timestamp.
    function saveForcedInclusion(LibBlobs.BlobReference memory _blobReference) external payable {
        bytes32 proposalHash = _proposalHashes[1];
        require(proposalHash != bytes32(0), IncorrectProposalCount());

        uint256 refund = LibForcedInclusion.saveForcedInclusion(
            _forcedInclusionStorage,
            _forcedInclusionFeeInGwei,
            _forcedInclusionFeeDoubleThreshold,
            _blobReference
        );

        // Refund excess payment to the sender
        if (refund > 0) {
            msg.sender.sendEtherAndVerify(refund);
        }
    }

    // ---------------------------------------------------------------
    // External and Public View Functions
    // ---------------------------------------------------------------
    /// @inheritdoc IForcedInclusionStore
    function getCurrentForcedInclusionFee() external view returns (uint64 feeInGwei_) {
        return LibForcedInclusion.getCurrentForcedInclusionFee(
            _forcedInclusionStorage, _forcedInclusionFeeInGwei, _forcedInclusionFeeDoubleThreshold
        );
    }

    /// @inheritdoc IForcedInclusionStore
    function getForcedInclusions(
        uint48 _start,
        uint48 _maxCount
    )
        external
        view
        returns (IForcedInclusionStore.ForcedInclusion[] memory inclusions_)
    {
        return LibForcedInclusion.getForcedInclusions(_forcedInclusionStorage, _start, _maxCount);
    }

    /// @inheritdoc IForcedInclusionStore
    function getForcedInclusionState() external view returns (uint48 head_, uint48 tail_) {
        return LibForcedInclusion.getForcedInclusionState(_forcedInclusionStorage);
    }

    /// @inheritdoc IInbox
    function getConfig() external view returns (Config memory config_) {
        config_ = Config({
            codec: _codec,
            proofVerifier: address(_proofVerifier),
            proposerChecker: address(_proposerChecker),
            proverWhitelist: address(_proverWhitelist),
            signalService: address(_signalService),
            provingWindow: _provingWindow,
            maxProofSubmissionDelay: _maxProofSubmissionDelay,
            ringBufferSize: _ringBufferSize,
            basefeeSharingPctg: _basefeeSharingPctg,
            minForcedInclusionCount: _minForcedInclusionCount,
            forcedInclusionDelay: _forcedInclusionDelay,
            forcedInclusionFeeInGwei: _forcedInclusionFeeInGwei,
            forcedInclusionFeeDoubleThreshold: _forcedInclusionFeeDoubleThreshold,
            minCheckpointDelay: _minCheckpointDelay,
            permissionlessInclusionMultiplier: _permissionlessInclusionMultiplier
        });
    }

    /// @inheritdoc IInbox
    function getCoreState() external view returns (CoreState memory) {
        return _coreState;
    }

    /// @inheritdoc IInbox
    /// @dev Note that due to the ring buffer nature of the `_proposalHashes` mapping proposals
    /// may have been overwritten by a new one. You should verify that the hash matches the
    /// expected proposal.
    function getProposalHash(uint256 _proposalId) public view returns (bytes32) {
        return _proposalHashes[_proposalId % _ringBufferSize];
    }

    // ---------------------------------------------------------------
    // Private State-Changing Functions
    // ---------------------------------------------------------------

    /// @dev Builds proposal and derivation data. It also checks if `msg.sender` can propose.
    /// @param _input The propose input data.
    /// @param _lookahead Encoded data forwarded to the proposer checker (i.e. lookahead payloads).
    /// @param _nextProposalId The proposal ID to assign.
    /// @param _lastProposalBlockId The last block number where a proposal was made.
    /// @param _lastFinalizedProposalId The ID of the last finalized proposal.
    /// @return proposal_ The proposal with final endOfSubmissionWindowTimestamp and derivation
    /// hash set.
    /// @return derivation_ The derivation data for the proposal.
    function _buildProposal(
        ProposeInput memory _input,
        bytes calldata _lookahead,
        uint48 _nextProposalId,
        uint48 _lastProposalBlockId,
        uint48 _lastFinalizedProposalId
    )
        private
        returns (Proposal memory proposal_, Derivation memory derivation_)
    {
        unchecked {
            // Enforce one propose call per Ethereum block to prevent spam attacks that could
            // deplete the ring buffer
            require(block.number > _lastProposalBlockId, CannotProposeInCurrentBlock());
            require(
                _getAvailableCapacity(_nextProposalId, _lastFinalizedProposalId) > 0,
                NotEnoughCapacity()
            );

            ConsumptionResult memory result =
                _consumeForcedInclusions(msg.sender, _input.numForcedInclusions);

            result.sources[result.sources.length - 1] =
                DerivationSource(false, LibBlobs.validateBlobReference(_input.blobReference));

            // If forced inclusion is old enough, allow anyone to propose
            // and set endOfSubmissionWindowTimestamp = 0
            // Otherwise, only the current preconfer can propose
            uint48 endOfSubmissionWindowTimestamp = result.allowsPermissionless
                ? 0
                : _proposerChecker.checkProposer(msg.sender, _lookahead);

            // Use previous block as the origin for the proposal to be able to call `blockhash`
            uint256 parentBlockNumber = block.number - 1;
            derivation_ = Derivation({
                originBlockNumber: uint48(parentBlockNumber),
                originBlockHash: blockhash(parentBlockNumber),
                basefeeSharingPctg: _basefeeSharingPctg,
                sources: result.sources
            });

            proposal_ = Proposal({
                id: _nextProposalId,
                timestamp: uint48(block.timestamp),
                endOfSubmissionWindowTimestamp: endOfSubmissionWindowTimestamp,
                proposer: msg.sender,
                parentProposalHash: getProposalHash(_nextProposalId - 1),
                derivationHash: LibHashOptimized.hashDerivation(derivation_)
            });
        }
    }

    /// @dev Stores a proposal hash in the ring buffer
    /// Overwrites any existing hash at the calculated buffer slot
    function _setProposalHash(uint48 _proposalId, bytes32 _proposalHash) private {
        _proposalHashes[_proposalId % _ringBufferSize] = _proposalHash;
    }

    /// @dev Consumes forced inclusions from the queue and returns result with extra slot for normal
    /// source
    /// @param _feeRecipient Address to receive accumulated fees
    /// @param _numForcedInclusionsRequested Maximum number of forced inclusions to consume
    /// @return result_ ConsumptionResult with sources array (size: processed + 1, last slot empty)
    /// and whether permissionless proposals are allowed
    function _consumeForcedInclusions(
        address _feeRecipient,
        uint256 _numForcedInclusionsRequested
    )
        private
        returns (ConsumptionResult memory result_)
    {
        unchecked {
            LibForcedInclusion.Storage storage $ = _forcedInclusionStorage;

            // Load storage once
            (uint48 head, uint48 tail) = ($.head, $.tail);

            uint256 available = tail - head;
            uint256 toProcess = _numForcedInclusionsRequested > available
                ? available
                : _numForcedInclusionsRequested;

            result_.sources = new DerivationSource[](toProcess + 1);

            uint48 oldestTimestamp;
            (oldestTimestamp, head) = _dequeueAndProcessForcedInclusions(
                $, _feeRecipient, result_.sources, head, toProcess
            );

            // We check the following conditions are met:
            // 1. Proposer is willing to include at least the minimum required
            // (_minForcedInclusionCount) OR
            // 2. Proposer included all available inclusions that are due
            if (_numForcedInclusionsRequested < _minForcedInclusionCount && available > toProcess) {
                bool isOldestInclusionDue = LibForcedInclusion.isOldestForcedInclusionDue(
                    $, head, tail, _forcedInclusionDelay
                );
                require(!isOldestInclusionDue, UnprocessedForcedInclusionIsDue());
            }

            uint256 permissionlessTimestamp = uint256(_forcedInclusionDelay)
                * _permissionlessInclusionMultiplier + oldestTimestamp;
            result_.allowsPermissionless = block.timestamp > permissionlessTimestamp;
        }
    }

    /// @dev Dequeues and processes forced inclusions from the queue without checking if they exist
    /// @param $ Storage reference
    /// @param _feeRecipient Address to receive fees
    /// @param _sources Array to populate with derivation sources
    /// @param _head Current queue head position
    /// @param _toProcess Number of inclusions to process
    /// @return oldestTimestamp_ Oldest timestamp from processed inclusions.
    /// `type(uint48).max` if no inclusions were processed
    /// @return head_ Updated head position
    function _dequeueAndProcessForcedInclusions(
        LibForcedInclusion.Storage storage $,
        address _feeRecipient,
        DerivationSource[] memory _sources,
        uint48 _head,
        uint256 _toProcess
    )
        private
        returns (uint48 oldestTimestamp_, uint48 head_)
    {
        unchecked {
            if (_toProcess == 0) {
                return (type(uint48).max, _head);
            }

            // Process inclusions and accumulate fees
            uint256 totalFees;
            for (uint256 i; i < _toProcess; ++i) {
                IForcedInclusionStore.ForcedInclusion storage inclusion = $.queue[_head + i];
                _sources[i] = IInbox.DerivationSource(true, inclusion.blobSlice);
                totalFees += inclusion.feeInGwei;
            }

            // Transfer accumulated fees
            if (totalFees > 0) {
                _feeRecipient.sendEtherAndVerify(totalFees * 1 gwei);
            }

            // Oldest timestamp is the timestamp of the first inclusion
            oldestTimestamp_ = uint48(_sources[0].blobSlice.timestamp);

            // Update queue position
            head_ = _head + uint48(_toProcess);

            // Write to storage once
            $.head = head_;
        }
    }

    /// @dev Calculates and emits bond instruction if applicable.
    /// @dev Bond instruction rules:
    ///      - On-time (within provingWindow + sequential grace): No bond changes.
    ///      - Late: Liveness bond transfer, even when the designated and actual provers are the
    ///        same address (L2 processing handles slashing/reward splits).
    /// @param _commitment The commitment data.
    /// @param _offset The offset to the first unfinalized proposal.
    function _processBondInstruction(
        Commitment memory _commitment,
        uint48 _offset
    )
        private
    {
        unchecked {
            uint256 livenessWindowDeadline = (_commitment.transitions[_offset].timestamp
                    + _provingWindow)
            .max(_coreState.lastFinalizedTimestamp + _maxProofSubmissionDelay);

            // On-time proof - no bond transfer needed.
            if (block.timestamp <= livenessWindowDeadline) {
                return;
            }

            LibBonds.BondInstruction memory bondInstruction = LibBonds.BondInstruction({
                proposalId: _commitment.firstProposalId + _offset,
                bondType: LibBonds.BondType.LIVENESS,
                payer: _commitment.transitions[_offset].designatedProver,
                payee: _commitment.actualProver
            });

            _signalService.sendSignal(LibBonds.hashBondInstruction(bondInstruction));
            emit BondInstructionCreated(bondInstruction.proposalId, bondInstruction);
        }
    }

    /// @dev Emits the Proposed event
    function _emitProposedEvent(
        Proposal memory _proposal,
        Derivation memory _derivation
    )
        private
    {
        ProposedEventPayload memory payload =
            ProposedEventPayload({ proposal: _proposal, derivation: _derivation });
        emit Proposed(LibProposedEventCodec.encode(payload));
    }

    // ---------------------------------------------------------------
    // Private View/Pure Functions
    // ---------------------------------------------------------------

    /// @dev Calculates remaining capacity for new proposals
    /// Subtracts unfinalized proposals from total capacity
    /// @param _nextProposalId The next proposal ID
    /// @param _lastFinalizedProposalId The ID of the last finalized proposal
    /// @return _ Number of additional proposals that can be submitted
    function _getAvailableCapacity(
        uint48 _nextProposalId,
        uint48 _lastFinalizedProposalId
    )
        private
        view
        returns (uint256)
    {
        unchecked {
            uint256 numUnfinalizedProposals = _nextProposalId - _lastFinalizedProposalId - 1;
            return _ringBufferSize - 1 - numUnfinalizedProposals;
        }
    }

    /// @dev Validates propose function inputs.
    /// @param _input The ProposeInput to validate
    function _validateProposeInput(ProposeInput memory _input) private view {
        require(_input.deadline == 0 || block.timestamp <= _input.deadline, DeadlineExceeded());
    }

    /// @dev Checks if the caller is an authorized prover
    /// @param _addr The address of the caller to check
    /// @return whitelistEnabled_ True if whitelist is enabled (proverCount > 0), false otherwise
    function _checkProver(address _addr) private view returns (bool whitelistEnabled_) {
        if (address(_proverWhitelist) == address(0)) return false;

        (bool isWhitelisted, uint256 proverCount) = _proverWhitelist.isProverWhitelisted(_addr);
        if (proverCount == 0) return false;

        require(isWhitelisted, ProverNotWhitelisted());
        return true;
    }

    /// @dev Validates the batch bounds in the Commitment and calculates the offset
    ///      to the first unfinalized proposal.
    /// @param _state The core state.
    /// @param _commitment The commitment data.
    /// @return numProposals_ The number of proposals in the batch.
    /// @return lastProposalId_ The ID of the last proposal in the batch.
    /// @return offset_ The offset to the first unfinalized proposal.
    function _validateCommitment(
        CoreState memory _state,
        Commitment memory _commitment
    )
        private
        pure
        returns (uint256 numProposals_, uint256 lastProposalId_, uint48 offset_)
    {
        unchecked {
            uint256 firstUnfinalizedId = _state.lastFinalizedProposalId + 1;

            numProposals_ = _commitment.transitions.length;
            require(numProposals_ > 0, EmptyBatch());
            require(_commitment.firstProposalId <= firstUnfinalizedId, FirstProposalIdTooLarge());

            lastProposalId_ = _commitment.firstProposalId + numProposals_ - 1;
            require(lastProposalId_ < _state.nextProposalId, LastProposalIdTooLarge());
            require(lastProposalId_ >= firstUnfinalizedId, LastProposalAlreadyFinalized());

            // Calculate offset to first unfinalized proposal.
            // Some proposals in _commitment.transitions[] may already be finalized.
            // The offset points to the first proposal that will be finalized.
            offset_ = uint48(firstUnfinalizedId - _commitment.firstProposalId);
        }
    }

    // ---------------------------------------------------------------
    // Errors
    // ---------------------------------------------------------------
    error ActivationRequired();
    error CannotProposeInCurrentBlock();
    error CheckpointDelayHasPassed();
    error DeadlineExceeded();
    error EmptyBatch();
    error FirstProposalIdTooLarge();
    error IncorrectProposalCount();
    error LastProposalAlreadyFinalized();
    error LastProposalHashMismatch();
    error LastProposalIdTooLarge();
    error NotEnoughCapacity();
    error ParentBlockHashMismatch();
    error ProverNotWhitelisted();
    error UnprocessedForcedInclusionIsDue();
}
          

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;
}
          

contracts/layer1/core/iface/IProverWhitelist.sol

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

/// @title IProverWhitelist
/// @notice Interface for checking if an address is authorized to prove blocks
/// @custom:security-contact security@taiko.xyz
interface IProverWhitelist {
    /// @notice Checks if an address is a whitelisted prover
    /// @param _prover The address to check
    /// @return isWhitelisted_ True if the address is whitelisted, false otherwise
    /// @return proverCount_ The total number of whitelisted provers
    function isProverWhitelisted(address _prover)
        external
        view
        returns (bool isWhitelisted_, uint256 proverCount_);
}
          

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;
}
          

contracts/layer1/core/libs/LibProposedEventCodec.sol

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

import { IInbox } from "../iface/IInbox.sol";
import { LibPackUnpack as P } from "./LibPackUnpack.sol";

/// @title LibProposedEventCodec
/// @notice Compact encoder/decoder for ProposedEventPayload using LibPackUnpack.
/// @custom:security-contact security@taiko.xyz
library LibProposedEventCodec {
    /// @notice Encodes a ProposedEventPayload into bytes using compact encoding.
    function encode(IInbox.ProposedEventPayload memory _payload)
        internal
        pure
        returns (bytes memory encoded_)
    {
        uint256 bufferSize = calculateProposedEventSize(_payload.derivation.sources);
        encoded_ = new bytes(bufferSize);

        uint256 ptr = P.dataPtr(encoded_);

        ptr = P.packUint48(ptr, _payload.proposal.id);
        ptr = P.packAddress(ptr, _payload.proposal.proposer);
        ptr = P.packUint48(ptr, _payload.proposal.timestamp);
        ptr = P.packUint48(ptr, _payload.proposal.endOfSubmissionWindowTimestamp);
        ptr = P.packBytes32(ptr, _payload.proposal.parentProposalHash);

        ptr = P.packUint48(ptr, _payload.derivation.originBlockNumber);
        ptr = P.packBytes32(ptr, _payload.derivation.originBlockHash);
        ptr = P.packUint8(ptr, _payload.derivation.basefeeSharingPctg);

        uint256 sourcesLength = _payload.derivation.sources.length;
        P.checkArrayLength(sourcesLength);
        ptr = P.packUint16(ptr, uint16(sourcesLength));
        for (uint256 i; i < sourcesLength; ++i) {
            IInbox.DerivationSource memory source = _payload.derivation.sources[i];
            ptr = P.packUint8(ptr, source.isForcedInclusion ? 1 : 0);

            uint256 blobHashesLength = source.blobSlice.blobHashes.length;
            P.checkArrayLength(blobHashesLength);
            ptr = P.packUint16(ptr, uint16(blobHashesLength));
            for (uint256 j; j < blobHashesLength; ++j) {
                ptr = P.packBytes32(ptr, source.blobSlice.blobHashes[j]);
            }

            ptr = P.packUint24(ptr, source.blobSlice.offset);
            ptr = P.packUint48(ptr, source.blobSlice.timestamp);
        }

        ptr = P.packBytes32(ptr, _payload.proposal.derivationHash);
    }

    /// @notice Decodes bytes into a ProposedEventPayload using compact encoding.
    function decode(bytes memory _data)
        internal
        pure
        returns (IInbox.ProposedEventPayload memory payload_)
    {
        uint256 ptr = P.dataPtr(_data);

        (payload_.proposal.id, ptr) = P.unpackUint48(ptr);
        (payload_.proposal.proposer, ptr) = P.unpackAddress(ptr);
        (payload_.proposal.timestamp, ptr) = P.unpackUint48(ptr);
        (payload_.proposal.endOfSubmissionWindowTimestamp, ptr) = P.unpackUint48(ptr);
        (payload_.proposal.parentProposalHash, ptr) = P.unpackBytes32(ptr);

        (payload_.derivation.originBlockNumber, ptr) = P.unpackUint48(ptr);
        (payload_.derivation.originBlockHash, ptr) = P.unpackBytes32(ptr);
        (payload_.derivation.basefeeSharingPctg, ptr) = P.unpackUint8(ptr);

        uint16 sourcesLength;
        (sourcesLength, ptr) = P.unpackUint16(ptr);
        payload_.derivation.sources = new IInbox.DerivationSource[](sourcesLength);
        for (uint256 i; i < sourcesLength; ++i) {
            uint8 isForcedInclusion;
            (isForcedInclusion, ptr) = P.unpackUint8(ptr);
            payload_.derivation.sources[i].isForcedInclusion = isForcedInclusion != 0;

            uint16 blobHashesLength;
            (blobHashesLength, ptr) = P.unpackUint16(ptr);

            payload_.derivation.sources[i].blobSlice.blobHashes = new bytes32[](blobHashesLength);
            for (uint256 j; j < blobHashesLength; ++j) {
                (payload_.derivation.sources[i].blobSlice.blobHashes[j], ptr) = P.unpackBytes32(ptr);
            }

            (payload_.derivation.sources[i].blobSlice.offset, ptr) = P.unpackUint24(ptr);
            (payload_.derivation.sources[i].blobSlice.timestamp, ptr) = P.unpackUint48(ptr);
        }

        (payload_.proposal.derivationHash, ptr) = P.unpackBytes32(ptr);
    }

    /// @notice Calculate the exact byte size needed for encoding a ProposedEventPayload.
    function calculateProposedEventSize(IInbox.DerivationSource[] memory _sources)
        internal
        pure
        returns (uint256 size_)
    {
        unchecked {
            // Fixed size without sources: 143 bytes
            // Proposal: id(6) + proposer(20) + timestamp(6) + endOfSubmissionWindowTimestamp(6) +
            // parentProposalHash(32)
            // Derivation base: originBlockNumber(6) + originBlockHash(32) + basefeeSharingPctg(1)
            // Sources length: 2
            // Proposal hash: derivationHash(32)
            size_ = 143;

            for (uint256 i; i < _sources.length; ++i) {
                size_ += 12 + (_sources[i].blobSlice.blobHashes.length * 32);
            }
        }
    }
}
          

contracts/shared/libs/LibBonds.sol

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

/// @title LibBonds
/// @notice Library for managing bond instructions
/// @custom:security-contact security@taiko.xyz
library LibBonds {
    // ---------------------------------------------------------------
    // Enums
    // ---------------------------------------------------------------

    enum BondType {
        NONE,
        LIVENESS
    }

    // ---------------------------------------------------------------
    // Structs
    // ---------------------------------------------------------------

    struct BondInstruction {
        uint48 proposalId;
        BondType bondType;
        address payer;
        address payee;
    }

    // ---------------------------------------------------------------
    // Functions
    // ---------------------------------------------------------------

    /// @dev Hashing for BondInstruction structs using keccak256 and abi.encode
    /// @dev This function is not optimized using EfficientHashLib for
    ///      gas savings because it's not expected to be called frequently.
    /// @param _bondInstruction The bond instruction to hash
    /// @return The hash of the bond instruction
    function hashBondInstruction(BondInstruction memory _bondInstruction)
        internal
        pure
        returns (bytes32)
    {
        /// forge-lint: disable-next-line(asm-keccak256)
        return keccak256(abi.encode(_bondInstruction));
    }
}
          

node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
          

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 end (last) L2 block in this proposal.
        bytes32 blockHash;
        /// @notice The state root for the end (last) L2 block in this proposal.
        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/layer1/core/libs/LibPackUnpack.sol

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

/// @title LibPackUnpack
/// @notice Library providing low-level packing/unpacking functions for compact binary encoding
/// using inline assembly for maximum gas efficiency.
/// @dev This library implements a trust-the-caller pattern with no bounds checking for optimal
/// performance. Callers are responsible for:
/// - Allocating sufficient memory for pack operations
/// - Ensuring data has sufficient length for unpack operations
/// - Tracking position offsets correctly
///
/// Memory Layout:
/// - Pack functions write directly to memory at absolute positions
/// - Unpack functions read from memory at absolute positions
/// - All multi-byte integers use big-endian encoding
/// - Position tracking is left to the caller
///
/// Safety Notes:
/// - No overflow protection on position increments (caller's responsibility)
/// - No bounds checking on memory access (gas-optimized design)
/// - Suitable for controlled environments where input validation happens upstream
///
/// Usage Example:
/// ```solidity
/// bytes memory buffer = new bytes(100);
/// uint256 pos = LibPackUnpack.dataPtr(buffer);
/// pos = LibPackUnpack.packUint32(pos, 12345);
/// pos = LibPackUnpack.packAddress(pos, msg.sender);
/// ```
/// @custom:security-contact security@taiko.xyz
library LibPackUnpack {
    // ---------------------------------------------------------------
    // Pack Functions (write to buffer with compact encoding)
    // ---------------------------------------------------------------

    /// @notice Pack uint8 (1 byte) at position
    /// @dev Writes a single byte to memory at the specified position.
    /// @param _pos Absolute memory position to write at
    /// @param _value The uint8 value to pack (0-255)
    /// @return newPos_ Updated position after writing (pos + 1)
    function packUint8(uint256 _pos, uint8 _value) internal pure returns (uint256 newPos_) {
        assembly {
            mstore8(_pos, _value)
            newPos_ := add(_pos, 1)
        }
    }

    /// @notice Pack uint16 (2 bytes) at position using big-endian encoding
    /// @dev Optimized to use mstore instead of 2 individual mstore8 operations.
    /// @param _pos Absolute memory position to write at
    /// @param _value The uint16 value to pack (0-65535)
    /// @return newPos_ Updated position after writing (pos + 2)
    function packUint16(uint256 _pos, uint16 _value) internal pure returns (uint256 newPos_) {
        assembly {
            // Shift value left by 30 bytes (240 bits) to align at the start of a 32-byte word
            let shifted := shl(240, _value)

            // Store the shifted value at position
            mstore(_pos, shifted)

            newPos_ := add(_pos, 2)
        }
    }

    /// @notice Pack uint24 (3 bytes) at position using big-endian encoding
    /// @dev Optimized to use mstore instead of 3 individual mstore8 operations.
    /// @param _pos Absolute memory position to write at
    /// @param _value The uint24 value to pack (0-16777215)
    /// @return newPos_ Updated position after writing (pos + 3)
    function packUint24(uint256 _pos, uint24 _value) internal pure returns (uint256 newPos_) {
        assembly {
            // Shift value left by 29 bytes (232 bits) to align at the start of a 32-byte word
            let shifted := shl(232, _value)

            // Store the shifted value at position
            mstore(_pos, shifted)

            newPos_ := add(_pos, 3)
        }
    }

    /// @notice Pack uint32 (4 bytes) at position using big-endian encoding
    /// @dev Optimized to use mstore instead of 4 individual mstore8 operations.
    /// @param _pos Absolute memory position to write at
    /// @param _value The uint32 value to pack (0-4294967295)
    /// @return newPos_ Updated position after writing (pos + 4)
    function packUint32(uint256 _pos, uint32 _value) internal pure returns (uint256 newPos_) {
        assembly {
            // Shift value left by 28 bytes (224 bits) to align at the start of a 32-byte word
            let shifted := shl(224, _value)

            // Store the shifted value at position
            mstore(_pos, shifted)

            newPos_ := add(_pos, 4)
        }
    }

    /// @notice Pack uint48 (6 bytes) at position using big-endian encoding
    /// @dev Optimized to use mstore instead of 6 individual mstore8 operations.
    /// Common use case: block numbers that exceed uint32 range.
    /// @param _pos Absolute memory position to write at
    /// @param _value The uint48 value to pack (0-281474976710655)
    /// @return newPos_ Updated position after writing (pos + 6)
    function packUint48(uint256 _pos, uint48 _value) internal pure returns (uint256 newPos_) {
        assembly {
            // Shift value left by 26 bytes (208 bits) to align at the start of a 32-byte word
            let shifted := shl(208, _value)

            // Store the shifted value at position
            mstore(_pos, shifted)

            newPos_ := add(_pos, 6)
        }
    }

    /// @notice Pack uint256 (32 bytes) at position
    /// @dev Uses single mstore for efficiency, writes full 32-byte word.
    /// @param _pos Absolute memory position to write at (best if 32-byte aligned)
    /// @param _value The uint256 value to pack
    /// @return newPos_ Updated position after writing (pos + 32)
    function packUint256(
        uint256 _pos,
        uint256 _value
    )
        internal
        pure
        returns (uint256 newPos_)
    {
        assembly {
            mstore(_pos, _value)
            newPos_ := add(_pos, 32)
        }
    }

    /// @notice Pack bytes32 at position
    /// @dev Direct 32-byte write, commonly used for hashes and identifiers.
    /// @param _pos Absolute memory position to write at (best if 32-byte aligned)
    /// @param _value The bytes32 value to pack (hash, identifier, etc.)
    /// @return newPos_ Updated position after writing (pos + 32)
    function packBytes32(
        uint256 _pos,
        bytes32 _value
    )
        internal
        pure
        returns (uint256 newPos_)
    {
        assembly {
            mstore(_pos, _value)
            newPos_ := add(_pos, 32)
        }
    }

    /// @notice Pack address (20 bytes) at position
    /// @dev Optimized to use mstore instead of 20 individual mstore8 operations.
    /// Handles alignment by using a single mstore with proper shifting.
    /// @param _pos Absolute memory position to write at
    /// @param _value The address to pack
    /// @return newPos_ Updated position after writing (pos + 20)
    function packAddress(
        uint256 _pos,
        address _value
    )
        internal
        pure
        returns (uint256 newPos_)
    {
        assembly {
            // Shift address left by 12 bytes (96 bits) to align it properly in a 32-byte word
            // This places the 20-byte address at the start of the word with 12 bytes of padding
            let shifted := shl(96, _value)

            // Store the shifted address at position
            // This writes 32 bytes, but we only care about the first 20
            mstore(_pos, shifted)

            newPos_ := add(_pos, 20)
        }
    }

    // ---------------------------------------------------------------
    // Unpack Functions (read from buffer with compact encoding)
    // ---------------------------------------------------------------

    /// @notice Unpack uint8 (1 byte) from position
    /// @dev Optimized to use shift operation instead of byte operation.
    /// @param _pos Absolute memory position to read from
    /// @return value_ The unpacked uint8 value
    /// @return newPos_ Updated position after reading (pos + 1)
    function unpackUint8(uint256 _pos) internal pure returns (uint8 value_, uint256 newPos_) {
        assembly {
            // Load full word and shift right by 248 bits (31 bytes) to get the 1 byte we need
            value_ := shr(248, mload(_pos))
            newPos_ := add(_pos, 1)
        }
    }

    /// @notice Unpack uint16 (2 bytes) from position using big-endian encoding
    /// @dev Optimized to use 1 mload operation instead of 2 byte reads.
    /// @param _pos Absolute memory position to read from
    /// @return value_ The unpacked uint16 value
    /// @return newPos_ Updated position after reading (pos + 2)
    function unpackUint16(uint256 _pos) internal pure returns (uint16 value_, uint256 newPos_) {
        assembly {
            // Load full word and shift right by 240 bits (30 bytes) to get the 2 bytes we need
            value_ := shr(240, mload(_pos))
            newPos_ := add(_pos, 2)
        }
    }

    /// @notice Unpack uint24 (3 bytes) from position using big-endian encoding
    /// @dev Optimized to use 1 mload operation instead of 3 byte reads.
    /// @param _pos Absolute memory position to read from
    /// @return value_ The unpacked uint24 value
    /// @return newPos_ Updated position after reading (pos + 3)
    function unpackUint24(uint256 _pos) internal pure returns (uint24 value_, uint256 newPos_) {
        assembly {
            // Load full word and shift right by 232 bits (29 bytes) to get the 3 bytes we need
            value_ := shr(232, mload(_pos))
            newPos_ := add(_pos, 3)
        }
    }

    /// @notice Unpack uint32 (4 bytes) from position using big-endian encoding
    /// @dev Optimized to use 1 mload operation instead of 4 byte reads.
    /// @param _pos Absolute memory position to read from
    /// @return value_ The unpacked uint32 value
    /// @return newPos_ Updated position after reading (pos + 4)
    function unpackUint32(uint256 _pos) internal pure returns (uint32 value_, uint256 newPos_) {
        assembly {
            // Load full word and shift right by 224 bits (28 bytes) to get the 4 bytes we need
            value_ := shr(224, mload(_pos))
            newPos_ := add(_pos, 4)
        }
    }

    /// @notice Unpack uint48 (6 bytes) from position using big-endian encoding
    /// @dev Optimized to use 1 mload operation instead of 6 byte reads.
    /// @param _pos Absolute memory position to read from
    /// @return value_ The unpacked uint48 value
    /// @return newPos_ Updated position after reading (pos + 6)
    function unpackUint48(uint256 _pos) internal pure returns (uint48 value_, uint256 newPos_) {
        assembly {
            // Load full word and shift right by 208 bits (26 bytes) to get the 6 bytes we need
            value_ := shr(208, mload(_pos))
            newPos_ := add(_pos, 6)
        }
    }

    /// @notice Unpack uint256 (32 bytes) from position
    /// @dev Single mload for efficiency. Reads full 32-byte word.
    /// @param _pos Absolute memory position to read from (best if 32-byte aligned)
    /// @return value_ The unpacked uint256 value
    /// @return newPos_ Updated position after reading (pos + 32)
    function unpackUint256(uint256 _pos) internal pure returns (uint256 value_, uint256 newPos_) {
        assembly {
            value_ := mload(_pos)
            newPos_ := add(_pos, 32)
        }
    }

    /// @notice Unpack bytes32 from position
    /// @dev Direct 32-byte read for hashes and identifiers.
    /// @param _pos Absolute memory position to read from (best if 32-byte aligned)
    /// @return value_ The unpacked bytes32 value
    /// @return newPos_ Updated position after reading (pos + 32)
    function unpackBytes32(uint256 _pos) internal pure returns (bytes32 value_, uint256 newPos_) {
        assembly {
            value_ := mload(_pos)
            newPos_ := add(_pos, 32)
        }
    }

    /// @notice Unpack address (20 bytes) from position
    /// @dev Optimized to use only 1 mload operation instead of 20 individual byte reads.
    /// Reads one full word and shifts to extract the address bytes.
    /// @param _pos Absolute memory position to read from
    /// @return value_ The unpacked address
    /// @return newPos_ Updated position after reading (pos + 20)
    function unpackAddress(uint256 _pos) internal pure returns (address value_, uint256 newPos_) {
        assembly {
            // Load the full 32-byte word starting at _pos
            let word := mload(_pos)
            // Shift right by 96 bits (12 bytes) to align the 20-byte address to the right
            // This removes the 12 trailing bytes and keeps the first 20 bytes
            value_ := shr(96, word)
            newPos_ := add(_pos, 20)
        }
    }

    // ---------------------------------------------------------------
    // Utility Functions
    // ---------------------------------------------------------------

    /// @notice Get the memory pointer to the data section of a bytes array
    /// @dev Skips the 32-byte length prefix to point at actual data.
    /// Essential for converting bytes memory to absolute position for pack/unpack operations.
    /// @param _data The bytes array to get data pointer from
    /// @return ptr_ The absolute memory pointer to the actual data (data location + 0x20)
    function dataPtr(bytes memory _data) internal pure returns (uint256 ptr_) {
        assembly {
            ptr_ := add(_data, 0x20)
        }
    }

    /// @notice Check that an array length fits within uint16 bounds
    /// @dev Reverts if the length exceeds uint16 maximum value (65535).
    /// Useful as a validation guard before packing array lengths.
    /// @param _length The array length to validate
    function checkArrayLength(uint256 _length) internal pure {
        require(_length <= type(uint16).max, LengthExceedsUint16());
    }

    // ---------------------------------------------------------------
    // Errors
    // ---------------------------------------------------------------

    error LengthExceedsUint16();
}
          

contracts/layer1/core/libs/LibProposeInputCodec.sol

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

import { IInbox } from "../iface/IInbox.sol";
import { LibPackUnpack as P } from "./LibPackUnpack.sol";

/// @title LibProposeInputCodec
/// @notice Compact encoder/decoder for propose inputs using LibPackUnpack.
/// @custom:security-contact security@taiko.xyz
library LibProposeInputCodec {
    /// @notice Encodes propose data using compact packing.
    function encode(IInbox.ProposeInput memory _input)
        internal
        pure
        returns (bytes memory encoded_)
    {
        encoded_ = new bytes(14);
        uint256 ptr = P.dataPtr(encoded_);
        ptr = P.packUint48(ptr, _input.deadline);
        ptr = P.packUint16(ptr, _input.blobReference.blobStartIndex);
        ptr = P.packUint16(ptr, _input.blobReference.numBlobs);
        ptr = P.packUint24(ptr, _input.blobReference.offset);
        ptr = P.packUint8(ptr, _input.numForcedInclusions);
    }

    /// @notice Decodes propose data using compact packing.
    function decode(bytes memory _data) internal pure returns (IInbox.ProposeInput memory input_) {
        uint256 ptr = P.dataPtr(_data);
        (input_.deadline, ptr) = P.unpackUint48(ptr);
        (input_.blobReference.blobStartIndex, ptr) = P.unpackUint16(ptr);
        (input_.blobReference.numBlobs, ptr) = P.unpackUint16(ptr);
        (input_.blobReference.offset, ptr) = P.unpackUint24(ptr);
        (input_.numForcedInclusions, ptr) = P.unpackUint8(ptr);
    }
}
          

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/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);
        }
    }
}
          

contracts/shared/libs/LibAddress.sol

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

import "@openzeppelin/contracts/utils/introspection/IERC165.sol";

/// @title LibAddress
/// @dev Provides utilities for address-related operations.
/// @custom:security-contact security@taiko.xyz
library LibAddress {
    error ETH_TRANSFER_FAILED();

    /// @dev Sends Ether to the specified address. This method will not revert even if sending ether
    /// fails.
    /// This function is inspired by
    /// https://github.com/nomad-xyz/ExcessivelySafeCall/blob/main/src/ExcessivelySafeCall.sol
    /// @param _to The recipient address.
    /// @param _amount The amount of Ether to send in wei.
    /// @param _gasLimit The max amount gas to pay for this transaction.
    /// @return success_ true if the call is successful, false otherwise.
    function sendEther(
        address _to,
        uint256 _amount,
        uint256 _gasLimit,
        bytes memory _calldata
    )
        internal
        returns (bool success_)
    {
        // Check for zero-address transactions
        require(_to != address(0), ETH_TRANSFER_FAILED());
        // dispatch message to recipient
        // by assembly calling "handle" function
        // we call via assembly to avoid memcopying a very large returndata
        // returned by a malicious contract
        assembly ("memory-safe") {
            success_ := call(
                _gasLimit, // gas
                _to, // recipient
                _amount, // ether value
                add(_calldata, 0x20), // inloc
                mload(_calldata), // inlen
                0, // outloc
                0 // outlen
            )
        }
    }

    /// @dev Sends Ether to the specified address. This method will revert if sending ether fails.
    /// @param _to The recipient address.
    /// @param _amount The amount of Ether to send in wei.
    /// @param _gasLimit The max amount gas to pay for this transaction.
    function sendEtherAndVerify(address _to, uint256 _amount, uint256 _gasLimit) internal {
        if (_amount == 0) return;
        require(sendEther(_to, _amount, _gasLimit, ""), ETH_TRANSFER_FAILED());
    }

    /// @dev Sends Ether to the specified address. This method will revert if sending ether fails.
    /// @param _to The recipient address.
    /// @param _amount The amount of Ether to send in wei.
    function sendEtherAndVerify(address _to, uint256 _amount) internal {
        sendEtherAndVerify(_to, _amount, gasleft());
    }

    function supportsInterface(
        address _addr,
        bytes4 _interfaceId
    )
        internal
        view
        returns (bool result_)
    {
        (bool success, bytes memory data) =
            _addr.staticcall(abi.encodeCall(IERC165.supportsInterface, (_interfaceId)));
        if (success && data.length == 32) {
            result_ = abi.decode(data, (bool));
        }
    }
}
          

contracts/shared/common/EssentialContract.sol

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

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;

    address internal immutable __resolver;

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

    uint256[50] private __gapFromOldAddressResolver;

    /// @dev Slot 1.
    uint8 internal __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
    function _storeReentryLock(uint8 _reentry) internal virtual {
        __reentry = _reentry;
    }

    // Loads the reentry lock
    function _loadReentryLock() internal view virtual returns (uint8 reentry_) {
        reentry_ = __reentry;
    }

    // ---------------------------------------------------------------
    // 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/libs/LibMath.sol

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

/// @title LibMath
/// @dev This library offers additional math functions for uint256.
/// @custom:security-contact security@taiko.xyz
library LibMath {
    /// @dev Returns the smaller of the two given values.
    /// @param _a The first number to compare.
    /// @param _b The second number to compare.
    /// @return The smaller of the two numbers.
    function min(uint256 _a, uint256 _b) internal pure returns (uint256) {
        return _a > _b ? _b : _a;
    }

    /// @dev Returns the larger of the two given values.
    /// @param _a The first number to compare.
    /// @param _b The second number to compare.
    /// @return The larger of the two numbers.
    function max(uint256 _a, uint256 _b) internal pure returns (uint256) {
        return _a > _b ? _a : _b;
    }

    function capToUint64(uint256 _value) internal pure returns (uint64) {
        return uint64(min(_value, type(uint64).max));
    }
}
          

contracts/layer1/core/libs/LibForcedInclusion.sol

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

import { IForcedInclusionStore } from "../iface/IForcedInclusionStore.sol";
import { LibBlobs } from "../libs/LibBlobs.sol";
import { LibMath } from "src/shared/libs/LibMath.sol";

/// @title LibForcedInclusion
/// @dev Library for storing and managing forced inclusion requests. Forced inclusions
/// allow users to pay a fee to ensure their transactions are included in a block. The library
/// maintains a FIFO queue of inclusion requests.
/// @dev Inclusion delay is measured in seconds, since we don't have an easy way to get batch number
/// in the Shasta design.
/// @dev Forced inclusions are limited to 1 blob only, and one L2 block only(this and other protocol
/// constrains are enforced by the node and verified by the prover)
/// @custom:security-contact security@taiko.xyz
library LibForcedInclusion {
    using LibMath for uint48;
    using LibMath for uint256;

    // ---------------------------------------------------------------
    //  Structs
    // ---------------------------------------------------------------

    /// @dev Storage for the forced inclusion queue. This struct uses 2 slots.
    /// @dev 2 slots used
    struct Storage {
        mapping(uint256 id => IForcedInclusionStore.ForcedInclusion inclusion) queue;
        /// @notice The index of the oldest forced inclusion in the queue. This is where items will
        /// be dequeued.
        uint48 head;
        /// @notice The index of the next free slot in the queue. This is where items will be
        /// enqueued.
        uint48 tail;
    }

    // ---------------------------------------------------------------
    //  Public Functions
    // ---------------------------------------------------------------

    /// @dev See `IForcedInclusionStore.saveForcedInclusion`
    function saveForcedInclusion(
        Storage storage $,
        uint64 _baseFeeInGwei,
        uint64 _feeDoubleThreshold,
        LibBlobs.BlobReference memory _blobReference
    )
        public
        returns (uint256 refund_)
    {
        LibBlobs.BlobSlice memory blobSlice = LibBlobs.validateBlobReference(_blobReference);
        require(blobSlice.blobHashes.length == 1, OnlySingleBlobAllowed());

        uint64 requiredFeeInGwei =
            getCurrentForcedInclusionFee($, _baseFeeInGwei, _feeDoubleThreshold);
        uint256 requiredFee = requiredFeeInGwei * 1 gwei;
        require(msg.value >= requiredFee, InsufficientFee());

        IForcedInclusionStore.ForcedInclusion memory inclusion =
            IForcedInclusionStore.ForcedInclusion({
                feeInGwei: requiredFeeInGwei, blobSlice: blobSlice
            });

        $.queue[$.tail++] = inclusion;

        emit IForcedInclusionStore.ForcedInclusionSaved(inclusion);

        // Calculate and return refund amount
        unchecked {
            refund_ = msg.value - requiredFee;
        }
    }

    /// @dev See `IForcedInclusionStore.getCurrentForcedInclusionFee`
    function getCurrentForcedInclusionFee(
        Storage storage $,
        uint64 _baseFeeInGwei,
        uint64 _feeDoubleThreshold
    )
        public
        view
        returns (uint64 feeInGwei_)
    {
        require(_feeDoubleThreshold > 0, InvalidFeeDoubleThreshold());

        (uint48 head, uint48 tail) = ($.head, $.tail);
        uint256 numPending = uint256(tail - head);

        // Linear scaling formula: fee = baseFee × (threshold + numPending) / threshold
        // This is mathematically equivalent to: fee = baseFee × (1 + numPending / threshold)
        // but avoids floating point arithmetic
        uint256 multipliedFee = _baseFeeInGwei * (_feeDoubleThreshold + numPending);
        feeInGwei_ = uint64((multipliedFee / _feeDoubleThreshold).min(type(uint64).max));
    }

    /// @notice Returns forced inclusions stored starting from a given index.
    /// @dev Returns an empty array if `_start` is outside the valid range [head, tail) or if
    ///      `_maxCount` is zero. Otherwise returns actual stored entries from the queue.
    /// @param _start The queue index to start reading from (must be in range [head, tail)).
    /// @param _maxCount Maximum number of inclusions to return. Passing zero returns an empty
    ///        array.
    /// @return inclusions_ Forced inclusions from the queue starting at `_start`. The actual length
    ///         will be `min(_maxCount, tail - _start)`, or zero if `_start` is out of range.
    function getForcedInclusions(
        Storage storage $,
        uint48 _start,
        uint48 _maxCount
    )
        internal
        view
        returns (IForcedInclusionStore.ForcedInclusion[] memory inclusions_)
    {
        unchecked {
            (uint48 head, uint48 tail) = ($.head, $.tail);

            if (_start < head || _start >= tail || _maxCount == 0) {
                return new IForcedInclusionStore.ForcedInclusion[](0);
            }

            uint256 count = uint256(tail - _start).min(_maxCount);

            inclusions_ = new IForcedInclusionStore.ForcedInclusion[](count);

            for (uint256 i; i < count; ++i) {
                inclusions_[i] = $.queue[i + _start];
            }
        }
    }

    /// @dev Returns the queue pointers for the forced inclusion storage.
    /// @param $ Storage instance tracking the forced inclusion queue.
    /// @return head_ Index of the next forced inclusion to dequeue.
    /// @return tail_ Index where the next forced inclusion will be enqueued.
    function getForcedInclusionState(Storage storage $)
        internal
        view
        returns (uint48 head_, uint48 tail_)
    {
        (head_, tail_) = ($.head, $.tail);
    }

    // ---------------------------------------------------------------
    // Internal functions
    // ---------------------------------------------------------------

    /// @dev Checks if the oldest remaining forced inclusion is due
    /// @param $ Storage reference
    /// @param _head Current queue head position
    /// @param _tail Current queue tail position
    /// @param _forcedInclusionDelay Delay in seconds before inclusion is due
    /// @return True if the oldest remaining inclusion is due for processing
    function isOldestForcedInclusionDue(
        Storage storage $,
        uint48 _head,
        uint48 _tail,
        uint16 _forcedInclusionDelay
    )
        internal
        view
        returns (bool)
    {
        unchecked {
            if (_head == _tail) return false;

            uint256 timestamp = $.queue[_head].blobSlice.timestamp;
            if (timestamp == 0) return false;

            return block.timestamp >= timestamp + _forcedInclusionDelay;
        }
    }

    // ---------------------------------------------------------------
    // Errors
    // ---------------------------------------------------------------

    error InsufficientFee();
    error InvalidFeeDoubleThreshold();
    error OnlySingleBlobAllowed();
}
          

contracts/layer1/core/libs/LibInboxSetup.sol

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

import { IInbox } from "../iface/IInbox.sol";
import { LibHashOptimized } from "./LibHashOptimized.sol";

/// @title LibInboxSetup
/// @notice Library for Inbox setup code (constructor validation, activation).
/// @dev Using public functions in a library forces external linking, reducing deployment size
///      of the main contract at the cost of a small runtime gas overhead for the DELEGATECALL.
/// @custom:security-contact security@taiko.xyz
library LibInboxSetup {
    // ---------------------------------------------------------------
    // Public Functions (externally linked)
    // ---------------------------------------------------------------

    /// @dev The time window during which activate() can be called after the first activation.
    uint256 public constant ACTIVATION_WINDOW = 2 hours;

    /// @dev Validates the Inbox configuration parameters.
    /// @param _config The configuration to validate.
    function validateConfig(IInbox.Config memory _config) public pure {
        // Validate in the order fields are defined in Config struct
        require(_config.codec != address(0), CodecZero());
        require(_config.proofVerifier != address(0), ProofVerifierZero());
        require(_config.proposerChecker != address(0), ProposerCheckerZero());
        require(_config.signalService != address(0), SignalServiceZero());
        require(_config.provingWindow != 0, ProvingWindowZero());
        require(_config.ringBufferSize > 1, RingBufferSizeTooSmall());
        require(_config.basefeeSharingPctg <= 100, BasefeeSharingPctgTooLarge());
        require(_config.minForcedInclusionCount != 0, MinForcedInclusionCountZero());
        require(_config.forcedInclusionFeeInGwei != 0, ForcedInclusionFeeInGweiZero());
        require(
            _config.forcedInclusionFeeDoubleThreshold != 0, ForcedInclusionFeeDoubleThresholdZero()
        );
        require(
            _config.permissionlessInclusionMultiplier > 1,
            PermissionlessInclusionMultiplierTooSmall()
        );
    }

    /// @dev Validates activation and computes the initial state for inbox activation.
    /// @param _lastPacayaBlockHash The block hash of the last Pacaya block.
    /// @param _activationTimestamp The current activation timestamp (0 if not yet activated).
    /// @return activationTimestamp_ The activation timestamp to use.
    /// @return state_ The initial CoreState.
    /// @return derivation_ The genesis derivation.
    /// @return proposal_ The genesis proposal.
    /// @return genesisProposalHash_ The hash of the genesis proposal (id=0).
    function activate(
        bytes32 _lastPacayaBlockHash,
        uint48 _activationTimestamp
    )
        public
        view
        returns (
            uint48 activationTimestamp_,
            IInbox.CoreState memory state_,
            IInbox.Derivation memory derivation_,
            IInbox.Proposal memory proposal_,
            bytes32 genesisProposalHash_
        )
    {
        // Validate activation parameters
        require(_lastPacayaBlockHash != 0, InvalidLastPacayaBlockHash());
        if (_activationTimestamp == 0) {
            activationTimestamp_ = uint48(block.timestamp);
        } else {
            require(
                block.timestamp <= ACTIVATION_WINDOW + _activationTimestamp,
                ActivationPeriodExpired()
            );
            activationTimestamp_ = _activationTimestamp;
        }

        // Set lastProposalBlockId to 1 to ensure the first proposal happens at block 2 or later.
        // This prevents reading blockhash(0) in propose(), which would return 0x0 and create
        // an invalid origin block hash. The EVM hardcodes blockhash(0) to 0x0, so we must
        // ensure proposals never reference the genesis block.
        state_.nextProposalId = 1;
        state_.lastProposalBlockId = 1;
        state_.lastFinalizedTimestamp = uint48(block.timestamp);
        state_.lastFinalizedBlockHash = _lastPacayaBlockHash;

        proposal_.derivationHash = LibHashOptimized.hashDerivation(derivation_);
        genesisProposalHash_ = LibHashOptimized.hashProposal(proposal_);
    }

    // ---------------------------------------------------------------
    // Errors
    // ---------------------------------------------------------------

    error ActivationPeriodExpired();
    error BasefeeSharingPctgTooLarge();
    error CodecZero();
    error ForcedInclusionFeeDoubleThresholdZero();
    error ForcedInclusionFeeInGweiZero();
    error InvalidLastPacayaBlockHash();
    error MinForcedInclusionCountZero();
    error PermissionlessInclusionMultiplierTooSmall();
    error ProofVerifierZero();
    error ProposerCheckerZero();
    error ProvingWindowZero();
    error RingBufferSizeTooSmall();
    error SignalServiceZero();
}
          

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/","@optimism/=node_modules/optimism/","@sp1-contracts/=node_modules/sp1-contracts/contracts/","forge-std/=node_modules/forge-std/","@p256-verifier/contracts/=node_modules/p256-verifier/src/","@eth-fabric/urc/=node_modules/urc/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":"address","name":"_proofVerifier","internalType":"address"},{"type":"address","name":"_proposerChecker","internalType":"address"},{"type":"address","name":"_proverWhitelist","internalType":"address"},{"type":"address","name":"_signalService","internalType":"address"},{"type":"address","name":"_codec","internalType":"address"}]},{"type":"error","name":"ACCESS_DENIED","inputs":[]},{"type":"error","name":"ActivationRequired","inputs":[]},{"type":"error","name":"BlobNotFound","inputs":[]},{"type":"error","name":"CannotProposeInCurrentBlock","inputs":[]},{"type":"error","name":"CheckpointDelayHasPassed","inputs":[]},{"type":"error","name":"DeadlineExceeded","inputs":[]},{"type":"error","name":"ETH_TRANSFER_FAILED","inputs":[]},{"type":"error","name":"EmptyBatch","inputs":[]},{"type":"error","name":"FUNC_NOT_IMPLEMENTED","inputs":[]},{"type":"error","name":"FirstProposalIdTooLarge","inputs":[]},{"type":"error","name":"INVALID_PAUSE_STATUS","inputs":[]},{"type":"error","name":"IncorrectProposalCount","inputs":[]},{"type":"error","name":"LastProposalAlreadyFinalized","inputs":[]},{"type":"error","name":"LastProposalHashMismatch","inputs":[]},{"type":"error","name":"LastProposalIdTooLarge","inputs":[]},{"type":"error","name":"LengthExceedsUint16","inputs":[]},{"type":"error","name":"NoBlobs","inputs":[]},{"type":"error","name":"NotEnoughCapacity","inputs":[]},{"type":"error","name":"ParentBlockHashMismatch","inputs":[]},{"type":"error","name":"ProverNotWhitelisted","inputs":[]},{"type":"error","name":"REENTRANT_CALL","inputs":[]},{"type":"error","name":"UnprocessedForcedInclusionIsDue","inputs":[]},{"type":"error","name":"ZERO_ADDRESS","inputs":[]},{"type":"error","name":"ZERO_VALUE","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":"BeaconUpgraded","inputs":[{"type":"address","name":"beacon","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"BondInstructionCreated","inputs":[{"type":"uint48","name":"proposalId","internalType":"uint48","indexed":true},{"type":"tuple","name":"bondInstruction","internalType":"struct LibBonds.BondInstruction","indexed":false,"components":[{"type":"uint48","name":"proposalId","internalType":"uint48"},{"type":"uint8","name":"bondType","internalType":"enum LibBonds.BondType"},{"type":"address","name":"payer","internalType":"address"},{"type":"address","name":"payee","internalType":"address"}]}],"anonymous":false},{"type":"event","name":"ForcedInclusionSaved","inputs":[{"type":"tuple","name":"forcedInclusion","internalType":"struct IForcedInclusionStore.ForcedInclusion","indexed":false,"components":[{"type":"uint64","name":"feeInGwei","internalType":"uint64"},{"type":"tuple","name":"blobSlice","internalType":"struct LibBlobs.BlobSlice","components":[{"type":"bytes32[]","name":"blobHashes","internalType":"bytes32[]"},{"type":"uint24","name":"offset","internalType":"uint24"},{"type":"uint48","name":"timestamp","internalType":"uint48"}]}]}],"anonymous":false},{"type":"event","name":"InboxActivated","inputs":[{"type":"bytes32","name":"lastPacayaBlockHash","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":"Proposed","inputs":[{"type":"bytes","name":"data","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"event","name":"Proved","inputs":[{"type":"bytes","name":"data","internalType":"bytes","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":"nonpayable","outputs":[],"name":"activate","inputs":[{"type":"bytes32","name":"_lastPacayaBlockHash","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint48","name":"","internalType":"uint48"}],"name":"activationTimestamp","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"config_","internalType":"struct IInbox.Config","components":[{"type":"address","name":"codec","internalType":"address"},{"type":"address","name":"proofVerifier","internalType":"address"},{"type":"address","name":"proposerChecker","internalType":"address"},{"type":"address","name":"proverWhitelist","internalType":"address"},{"type":"address","name":"signalService","internalType":"address"},{"type":"uint48","name":"provingWindow","internalType":"uint48"},{"type":"uint48","name":"maxProofSubmissionDelay","internalType":"uint48"},{"type":"uint256","name":"ringBufferSize","internalType":"uint256"},{"type":"uint8","name":"basefeeSharingPctg","internalType":"uint8"},{"type":"uint256","name":"minForcedInclusionCount","internalType":"uint256"},{"type":"uint16","name":"forcedInclusionDelay","internalType":"uint16"},{"type":"uint64","name":"forcedInclusionFeeInGwei","internalType":"uint64"},{"type":"uint64","name":"forcedInclusionFeeDoubleThreshold","internalType":"uint64"},{"type":"uint16","name":"minCheckpointDelay","internalType":"uint16"},{"type":"uint8","name":"permissionlessInclusionMultiplier","internalType":"uint8"}]}],"name":"getConfig","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct IInbox.CoreState","components":[{"type":"uint48","name":"nextProposalId","internalType":"uint48"},{"type":"uint48","name":"lastProposalBlockId","internalType":"uint48"},{"type":"uint48","name":"lastFinalizedProposalId","internalType":"uint48"},{"type":"uint48","name":"lastFinalizedTimestamp","internalType":"uint48"},{"type":"uint48","name":"lastCheckpointTimestamp","internalType":"uint48"},{"type":"bytes32","name":"lastFinalizedBlockHash","internalType":"bytes32"}]}],"name":"getCoreState","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint64","name":"feeInGwei_","internalType":"uint64"}],"name":"getCurrentForcedInclusionFee","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint48","name":"head_","internalType":"uint48"},{"type":"uint48","name":"tail_","internalType":"uint48"}],"name":"getForcedInclusionState","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple[]","name":"inclusions_","internalType":"struct IForcedInclusionStore.ForcedInclusion[]","components":[{"type":"uint64","name":"feeInGwei","internalType":"uint64"},{"type":"tuple","name":"blobSlice","internalType":"struct LibBlobs.BlobSlice","components":[{"type":"bytes32[]","name":"blobHashes","internalType":"bytes32[]"},{"type":"uint24","name":"offset","internalType":"uint24"},{"type":"uint48","name":"timestamp","internalType":"uint48"}]}]}],"name":"getForcedInclusions","inputs":[{"type":"uint48","name":"_start","internalType":"uint48"},{"type":"uint48","name":"_maxCount","internalType":"uint48"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"getProposalHash","inputs":[{"type":"uint256","name":"_proposalId","internalType":"uint256"}]},{"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":"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":"nonpayable","outputs":[],"name":"propose","inputs":[{"type":"bytes","name":"_lookahead","internalType":"bytes"},{"type":"bytes","name":"_data","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"prove","inputs":[{"type":"bytes","name":"_data","internalType":"bytes"},{"type":"bytes","name":"_proof","internalType":"bytes"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"proxiableUUID","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":"payable","outputs":[],"name":"saveForcedInclusion","inputs":[{"type":"tuple","name":"_blobReference","internalType":"struct LibBlobs.BlobReference","components":[{"type":"uint16","name":"blobStartIndex","internalType":"uint16"},{"type":"uint16","name":"numBlobs","internalType":"uint16"},{"type":"uint24","name":"offset","internalType":"uint24"}]}]},{"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

0x6102a060405230608052348015610014575f5ffd5b506040516149f63803806149f6833981016040819052610033916102d2565b604080516101e0810182526001600160a01b03808416825287811660208301528681169282019290925284821660608201529083166080820152611c2060a082015260b460c0820152606460e0820152604b61010082015260016101208201525f610140820152629896806101608201526032610180808301919091526101a082015260056101c08201526100c66101fb565b6040516348ed17ff60e11b8152739c9d925f3d7d820a994811c17480fe67875a1562906391da2ffe906100fd908490600401610333565b5f6040518083038186803b158015610113575f5ffd5b505af4158015610125573d5f5f3e3d5ffd5b505082516001600160a01b0390811660c09081526020850151821660e09081526040860151831661010090815260608701518416610120908152608088015190941661014090815260a088015165ffffffffffff9081166101609081529489015116610180908152928801516101a09081529188015160ff9081166101c0908152958901516101e0529088015161ffff90811661020052938801516001600160401b0390811661022052928801519092166102405286015190911661026052930151909216610280525061049995505050505050565b5f54610100900460ff16156102665760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b5f5460ff908116146102b5575f805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b80516001600160a01b03811681146102cd575f5ffd5b919050565b5f5f5f5f5f60a086880312156102e6575f5ffd5b6102ef866102b7565b94506102fd602087016102b7565b935061030b604087016102b7565b9250610319606087016102b7565b9150610327608087016102b7565b90509295509295909350565b81516001600160a01b031681526101e08101602083015161035f60208401826001600160a01b03169052565b50604083015161037a60408401826001600160a01b03169052565b50606083015161039560608401826001600160a01b03169052565b5060808301516103b060808401826001600160a01b03169052565b5060a08301516103ca60a084018265ffffffffffff169052565b5060c08301516103e460c084018265ffffffffffff169052565b5060e083015160e083015261010083015161040561010084018260ff169052565b5061012083015161012083015261014083015161042961014084018261ffff169052565b506101608301516104466101608401826001600160401b03169052565b506101808301516104636101808401826001600160401b03169052565b506101a083015161047b6101a084018261ffff169052565b506101c08301516104926101c084018260ff169052565b5092915050565b60805160a05160c05160e05161010051610120516101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516143f96105fd5f395f818161082f0152612e9201525f8181610805015261143601525f81816107d601528181611137015261123f01525f81816107a70152818161110f015261121701525f818161077d01528181612e410152612eb601525f81816107570152612e0701525f818161072e01526120bf01525f81816107080152818161106d01528181611d010152611f5901525f81816106da015261254801525f81816106ac015261258901525f818161067d01528181611472015261266a01525f818161064e01528181612207015261225d01525f818161061f015261201401525f81816105f0015261173301525f6105c101525f6101c701525f8181610a1c01528181610a5c01528181610b5501528181610b950152610c0c01526143f95ff3fe60806040526004361061017b575f3560e01c8063715018a6116100cd578063a834725a11610087578063e305333511610062578063e305333514610879578063e30c3978146108a5578063ea191743146108c2578063f2fde38b146108e1575f5ffd5b8063a834725a1461050d578063c3f909d41461052c578063df596d9e14610866575f5ffd5b8063715018a61461048157806379ba5097146104955780638456cb59146104a95780638abf6077146104bd5780638da5cb5b146104d15780639791e644146104ee575f5ffd5b806340df98661161013857806359db6e851161011357806359db6e85146102f95780635c975abb146103185780635ccc1718146103385780636aa6a01a1461036e575f5ffd5b806340df9866146102985780634f1ef286146102c457806352d1902d146102d7575f5ffd5b80630423c7de1461017f57806304f3bcec146101b957806319ab453c146101ff5780633075db56146102205780633659cfe6146102655780633f4ba83a14610284575b5f5ffd5b34801561018a575f5ffd5b5060fb5461019d9065ffffffffffff1681565b60405165ffffffffffff90911681526020015b60405180910390f35b3480156101c4575f5ffd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040516001600160a01b0390911681526020016101b0565b34801561020a575f5ffd5b5061021e610219366004613796565b610900565b005b34801561022b575f5ffd5b5060027fa5054f728453d3dbe953bdc43e4d0cb97e662ea32d7958190f3dc2da31d9721b5c60ff16145b60405190151581526020016101b0565b348015610270575f5ffd5b5061021e61027f366004613796565b610a12565b34801561028f575f5ffd5b5061021e610ad9565b3480156102a3575f5ffd5b506102b76102b23660046137c4565b610b34565b6040516101b091906137fb565b61021e6102d23660046139ab565b610b4b565b3480156102e2575f5ffd5b506102eb610c00565b6040519081526020016101b0565b348015610304575f5ffd5b5061021e610313366004613a50565b610cb1565b348015610323575f5ffd5b5061025560c954610100900460ff1660021490565b348015610343575f5ffd5b50610100546040805165ffffffffffff8084168252600160301b9093049092166020830152016101b0565b348015610379575f5ffd5b5061040e6040805160c0810182525f80825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c08101825260fc5465ffffffffffff8082168352600160301b820481166020840152600160601b8204811693830193909352600160901b810483166060830152600160c01b9004909116608082015260fd5460a082015290565b6040516101b091905f60c08201905065ffffffffffff835116825265ffffffffffff602084015116602083015265ffffffffffff604084015116604083015265ffffffffffff606084015116606083015265ffffffffffff608084015116608083015260a083015160a083015292915050565b34801561048c575f5ffd5b5061021e610e63565b3480156104a0575f5ffd5b5061021e610e74565b3480156104b4575f5ffd5b5061021e610eeb565b3480156104c8575f5ffd5b506101e7610f40565b3480156104dc575f5ffd5b506033546001600160a01b03166101e7565b3480156104f9575f5ffd5b5061021e610508366004613aab565b610f4e565b348015610518575f5ffd5b506102eb610527366004613a50565b611064565b348015610537575f5ffd5b50610859604080516101e0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c0810191909152604051806101e001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000065ffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000065ffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000081526020017f000000000000000000000000000000000000000000000000000000000000000060ff1681526020017f000000000000000000000000000000000000000000000000000000000000000081526020017f000000000000000000000000000000000000000000000000000000000000000061ffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160401b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160401b031681526020017f000000000000000000000000000000000000000000000000000000000000000061ffff1681526020017f000000000000000000000000000000000000000000000000000000000000000060ff16815250905090565b6040516101b09190613b15565b61021e610874366004613ca1565b6110a7565b348015610884575f5ffd5b5061088d6111f9565b6040516001600160401b0390911681526020016101b0565b3480156108b0575f5ffd5b506065546001600160a01b03166101e7565b3480156108cd575f5ffd5b5061021e6108dc366004613aab565b6112c4565b3480156108ec575f5ffd5b5061021e6108fb366004613796565b6117c6565b5f54610100900460ff161580801561091e57505f54600160ff909116105b806109375750303b15801561093757505f5460ff166001145b61099f5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b5f805460ff1916600117905580156109c0575f805461ff0019166101001790555b6109c982611837565b8015610a0e575f805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610a5a5760405162461bcd60e51b815260040161099690613cf1565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610a8c611895565b6001600160a01b031614610ab25760405162461bcd60e51b815260040161099690613d3d565b610abb816118b0565b604080515f80825260208201909252610ad6918391906118b8565b50565b610ae1611a22565b610af560c9805461ff001916610100179055565b6040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa9060200160405180910390a1610b32335f611a53565b565b6060610b4260ff8484611a5b565b90505b92915050565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610b935760405162461bcd60e51b815260040161099690613cf1565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610bc5611895565b6001600160a01b031614610beb5760405162461bcd60e51b815260040161099690613d3d565b610bf4826118b0565b610a0e828260016118b8565b5f306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610c9f5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610996565b505f51602061437d5f395f51905f5290565b610cb9611c9e565b60fb54604051633dd0723360e21b81526004810183905265ffffffffffff90911660248201525f908190819081908190739c9d925f3d7d820a994811c17480fe67875a15629063f741c8cc906044015f60405180830381865af4158015610d22573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610d499190810190614041565b60fb805465ffffffffffff191665ffffffffffff87811691909117909155845160fc80546020880151604089015160608a015160808b01519587166bffffffffffffffffffffffff1990941693909317600160301b92871692909202919091176bffffffffffffffffffffffff60601b1916600160601b9186169190910265ffffffffffff60901b191617600160901b918516919091021765ffffffffffff60c01b1916600160c01b929093169190910291909117905560a084015160fd55939850919650945092509050610e1e5f82611cf8565b610e288284611d42565b6040518681527fe4356761c97932c05c3ee0859fb1a5e4f91f7a1d7a3752c7d5a72d5cc6ecb2d29060200160405180910390a1505050505050565b610e6b611c9e565b610b325f611d9a565b60655433906001600160a01b03168114610ee25760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b6064820152608401610996565b610ad681611d9a565b610ef3611db3565b60c9805461ff0019166102001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2589060200160405180910390a1610b32336001611a53565b5f610f49611895565b905090565b610f56611de5565b610f606002611e2a565b5f610f9f83838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250611e3392505050565b9050610faa81611e8b565b60fc5465ffffffffffff80821691600160301b8104821691600160601b9091041682610fe95760405163ba74d80f60e01b815260040160405180910390fd5b5f5f610ff9868b8b888888611ec7565b60fc80544365ffffffffffff908116600160301b026bffffffffffffffffffffffff1990921660018b019190911617179055815191935091506110449061103f84612168565b611cf8565b61104e8282611d42565b50505050505061105e6001611e2a565b50505050565b5f60fe816110927f000000000000000000000000000000000000000000000000000000000000000085614132565b81526020019081526020015f20549050919050565b60015f5260fe6020527f457c8a48b4735f56b938837eb0a8a5f9c55f23c1a85767ce3b65c3e59d3d32b754806110f05760405163f37a8b1360e01b815260040160405180910390fd5b604080516312b2aa9160e31b815260ff60048201526001600160401b037f0000000000000000000000000000000000000000000000000000000000000000811660248301527f0000000000000000000000000000000000000000000000000000000000000000166044820152835161ffff908116606483015260208501511660848201529083015162ffffff1660a48201525f90734c0dbff2abf9cbd7641cf38fc5765949a8e5b1bf9063959554889060c401602060405180830381865af41580156111be573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111e29190614151565b905080156111f4576111f433826121f9565b505050565b6040516343c3d71960e01b815260ff60048201526001600160401b037f0000000000000000000000000000000000000000000000000000000000000000811660248301527f00000000000000000000000000000000000000000000000000000000000000001660448201525f90734c0dbff2abf9cbd7641cf38fc5765949a8e5b1bf906343c3d71990606401602060405180830381865af41580156112a0573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f499190614168565b5f6112ce33612204565b6040805160c08101825260fc5465ffffffffffff8082168352600160301b82048116602080850191909152600160601b8304821684860152600160901b830482166060850152600160c01b90920416608083015260fd5460a08301528251601f8901829004820281018201909352878352929350915f916113689189908990819084018382808284375f9201919091525061230192505050565b80519091505f808061137a8685612471565b9250925092505f8165ffffffffffff165f146113c2578460c001516001830365ffffffffffff16815181106113b1576113b161418e565b6020026020010151606001516113c8565b84602001515b9050808760a00151146113ee5760405163198070b360e01b815260040160405180910390fd5b6113f783611064565b85604001511461141a5760405163f904c2fd60e01b815260040160405180910390fd5b87611429576114298583612542565b85602001518061146b57507f000000000000000000000000000000000000000000000000000000000000000061ffff1687608001510165ffffffffffff164210155b1561156a577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c9a0b8c86040518060600160405280886080015165ffffffffffff1681526020018860c0015160018903815181106114d5576114d561418e565b60200260200101516060015181526020018860a001518152506040518263ffffffff1660e01b815260040161152e9190815165ffffffffffff168152602080830151908201526040918201519181019190915260600190565b5f604051808303815f87803b158015611545575f5ffd5b505af1158015611557573d5f5f3e3d5ffd5b50505065ffffffffffff42166080890152505b65ffffffffffff80841660408901524216606088015260c085015180515f19860190811061159a5761159a61418e565b6020026020010151606001518760a00181815250508660fc5f820151815f015f6101000a81548165ffffffffffff021916908365ffffffffffff1602179055506020820151815f0160066101000a81548165ffffffffffff021916908365ffffffffffff1602179055506040820151815f01600c6101000a81548165ffffffffffff021916908365ffffffffffff1602179055506060820151815f0160126101000a81548165ffffffffffff021916908365ffffffffffff1602179055506080820151815f0160186101000a81548165ffffffffffff021916908365ffffffffffff16021790555060a082015181600101559050507fb2d5049ba96efb9e1fee66a51e4e6cbdfa2949627891ee29c6e4281abb8da03c6116c7604051806020016040528089815250612748565b6040516116d491906141d0565b60405180910390a15f61172d886060015165ffffffffffff168760c001518565ffffffffffff168151811061170b5761170b61418e565b60200260200101516040015165ffffffffffff1661287290919063ffffffff16565b420390507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166314bcf3dd8261176a89612887565b8e8e6040518563ffffffff1660e01b815260040161178b949392919061420a565b5f6040518083038186803b1580156117a1575f5ffd5b505afa1580156117b3573d5f5f3e3d5ffd5b5050505050505050505050505050505050565b6117ce611c9e565b606580546001600160a01b0383166001600160a01b031990911681179091556117ff6033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b5f54610100900460ff1661185d5760405162461bcd60e51b815260040161099690614229565b6118656129de565b6118836001600160a01b0382161561187d5781611d9a565b33611d9a565b5060c9805461ff001916610100179055565b5f51602061437d5f395f51905f52546001600160a01b031690565b610ad6611c9e565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156118eb576111f483612a04565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611945575060408051601f3d908101601f1916820190925261194291810190614151565b60015b6119a85760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610996565b5f51602061437d5f395f51905f528114611a165760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610996565b506111f4838383612a9f565b611a3660c954610100900460ff1660021490565b610b325760405163bae6e2a960e01b815260040160405180910390fd5b610a0e611c9e565b600183015460609065ffffffffffff80821691600160301b90048116908516821180611a9757508065ffffffffffff168565ffffffffffff1610155b80611aa8575065ffffffffffff8416155b15611b1157604080515f8082526020820190925290611b07565b611af46040805180820182525f8082528251606080820185528152602081810183905293810191909152909182015290565b815260200190600190039081611ac25790505b5092505050611c97565b5f611b2965ffffffffffff8784038116908716612ac3565b9050806001600160401b03811115611b4357611b436138d9565b604051908082528060200260200182016040528015611ba657816020015b611b936040805180820182525f8082528251606080820185528152602081810183905293810191909152909182015290565b815260200190600190039081611b615790505b5093505f5b81811015611c925765ffffffffffff871681015f90815260208981526040918290208251808401845281546001600160401b0316815283516001830180546080818702840181019097526060830181815293969495870194929391928492918491840182828015611c3957602002820191905f5260205f20905b815481526020019060010190808311611c25575b50505091835250506001919091015462ffffff811660208301526301000000900465ffffffffffff166040909101529052508551869083908110611c7f57611c7f61418e565b6020908102919091010152600101611bab565b505050505b9392505050565b6033546001600160a01b03163314610b325760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610996565b8060fe5f611d2e7f000000000000000000000000000000000000000000000000000000000000000065ffffffffffff8716614132565b815260208101919091526040015f20555050565b60408051808201909152828152602081018290527f10b2060c55406ea48522476f67fd813d4984b12078555d3e2a377e35839d7d01611d8082612ad7565b604051611d8d91906141d0565b60405180910390a1505050565b606580546001600160a01b0319169055610ad681612cb1565b611dc760c954610100900460ff1660021490565b15610b325760405163bae6e2a960e01b815260040160405180910390fd5b60027fa5054f728453d3dbe953bdc43e4d0cb97e662ea32d7958190f3dc2da31d9721b5c60ff1603610b325760405163dfc60d8560e01b815260040160405180910390fd5b610ad681612d02565b611e3b6136ed565b60208281015160d01c82526026830151828201805160f092831c905260288501518151921c9190920152602a830151905160e89190911c604091820152602d9092015160f81c9181019190915290565b805165ffffffffffff161580611eaa5750805165ffffffffffff164211155b610ad65760405163559895a360e01b815260040160405180910390fd5b6040805160c0810182525f80825260208201819052918101829052606081018290526080810182905260a0810191909152604080516080810182525f80825260208201819052918101919091526060808201528365ffffffffffff164311611f42576040516349517a1d60e11b815260040160405180910390fd5b5f611f7d868590035f1990810165ffffffffffff167f0000000000000000000000000000000000000000000000000000000000000000030190565b11611f9b5760405163eaabac9b60e01b815260040160405180910390fd5b5f611fad338a6040015160ff16612d28565b905060405180604001604052805f15158152602001611fcf8b60200151612eee565b9052815180515f198101908110611fe857611fe861418e565b60200260200101819052505f816020015161209257604051635600026d60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063ac0004da9061204d9033908d908d90600401614274565b6020604051808303815f875af1158015612069573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061208d91906142a1565b612094565b5f5b90505f60014303905060405180608001604052808265ffffffffffff168152602001824081526020017f000000000000000000000000000000000000000000000000000000000000000060ff168152602001845f015181525093506040518060c001604052808965ffffffffffff1681526020014265ffffffffffff1681526020018365ffffffffffff168152602001336001600160a01b0316815260200161214760018b0365ffffffffffff16611064565b81526020016121558661302f565b8152509450505050965096945050505050565b604080516006815260e08101909152815165ffffffffffff1660208201525f90602083015165ffffffffffff166040820152604083015165ffffffffffff16606082015260608301516001600160a01b03166080820152608083015160a082015260a083015160c0820152805160051b6020820120611c978280516040516001820160051b83011490151060061b52565b610a0e82825a613234565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661223a57505f919050565b604051633326844b60e11b81526001600160a01b0383811660048301525f9182917f0000000000000000000000000000000000000000000000000000000000000000169063664d0896906024016040805180830381865afa1580156122a1573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122c591906142bc565b91509150805f036122d957505f9392505050565b816122f75760405163c1a58f1960e01b815260040160405180910390fd5b5060019392505050565b612309613724565b602082810151825160d091821c90526026840151835190920191909152604683015182516040015260668301518251606091821c910152607a8301518251911c608091820152820151815160a09081019190915282015160a283019060f01c806001600160401b03811115612380576123806138d9565b6040519080825280602002602001820160405280156123d057816020015b604080516080810182525f8082526020808301829052928201819052606082015282525f1990920191018161239e5790505b50835160c001525f5b8161ffff1681101561245f57604080516080810182525f8082526020820181815292820181815260608084019283528751811c84526014880151901c909352602886015160d01c909252602e850151909152604e8401855160c001518051849081106124475761244761418e565b602090810291909101019190915292506001016123d9565b50505160f81c15156020820152919050565b604082015160c082015151905f90819060010165ffffffffffff16836124aa5760405163c2e5347d60e01b815260040160405180910390fd5b845165ffffffffffff168110156124d4576040516363db3a4160e01b815260040160405180910390fd5b845186515f1965ffffffffffff92831687010194501683106125095760405163677c56f160e01b815260040160405180910390fd5b8083101561252a5760405163181432e760e11b815260040160405180910390fd5b845f015165ffffffffffff1681039150509250925092565b5f6125e97f000000000000000000000000000000000000000000000000000000000000000060fc5f0160129054906101000a900465ffffffffffff160165ffffffffffff167f00000000000000000000000000000000000000000000000000000000000000008560c001518565ffffffffffff16815181106125c6576125c661418e565b6020026020010151604001510165ffffffffffff1661287290919063ffffffff16565b90508042116125f757505050565b60408051608081019091528351830165ffffffffffff1681525f9060208101600181526020018560c001518565ffffffffffff168151811061263b5761263b61418e565b6020026020010151602001516001600160a01b0316815260200185606001516001600160a01b031681525090507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166366ca2bc06126a083613277565b6040518263ffffffff1660e01b81526004016126be91815260200190565b6020604051808303815f875af11580156126da573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126fe9190614151565b50805f015165ffffffffffff167f8796b99bbf275a983988181e85b42502d9347327f4dde674320bec3879bcc5e18260405161273a91906142e6565b60405180910390a250505050565b80515160c08101515160609190604e02608301806001600160401b03811115612773576127736138d9565b6040519080825280601f01601f19166020018201604052801561279d576020820181803683370190505b50825160d090811b602083810191909152840151602683015260408401516046830152606080850151901b606683015260808085015190911b607a83015260a0808501519183019190915260c0840151519194508401906127fd906132a6565b60c08301515160f01b81526002015f5b8360c001515181101561284b57612841828560c0015183815181106128345761283461418e565b60200260200101516132c9565b915060010161280d565b5061286981865f015160200151612862575f6132fe565b60016132fe565b50505050919050565b5f8183116128805781610b42565b5090919050565b60c081015180515f919060096004820201836128b38260408051828152600190920160051b8201905290565b6020808201529050855165ffffffffffff166040820152602086015160608201526040860151608082015260608601516001600160a01b031660a0820152608086015165ffffffffffff1660c082015260a086015160e082015260e0610100820152610120810183905260095f5b848110156129ac575f86828151811061293c5761293c61418e565b602090810291909101015180516001600160a01b03166001850160051b860152905060208101516001600160a01b03166002840160051b850152604081015165ffffffffffff166003840160051b85015260608101516004840160051b8501525060049190910190600101612921565b50815160051b60208301206129d38380516040516001820160051b83011490151060061b52565b979650505050505050565b5f54610100900460ff16610b325760405162461bcd60e51b815260040161099690614229565b6001600160a01b0381163b612a715760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610996565b5f51602061437d5f395f51905f5280546001600160a01b0319166001600160a01b0392909216919091179055565b612aa88361330a565b5f82511180612ab45750805b156111f45761105e8383613349565b5f818311612ad15782610b42565b50919050565b60605f612aeb83602001516060015161336e565b9050806001600160401b03811115612b0557612b056138d9565b6040519080825280601f01601f191660200182016040528015612b2f576020820181803683370190505b5083515160d090811b6020838101919091528551606090810151901b60268401528551810151821b603a8401528551604090810151831b81850152865160800151604685015281870180515190931b6066850152825190910151606c84015290510151909250608c830190612ba59082906132fe565b60208501516060015151909150612bbb816132a6565b612bcb828260f01b815260020190565b91505f5b81811015612ca1575f8660200151606001518281518110612bf257612bf261418e565b60200260200101519050612c0e84825f0151612862575f6132fe565b60208201515151909450612c21816132a6565b612c31858260f01b815260020190565b94505f5b81811015612c7457612c6a8684602001515f01518381518110612c5a57612c5a61418e565b6020026020010151815260200190565b9550600101612c35565b5050602090810180519091015160e81b8452516040015160d01b6003840152600990920191600101612bcf565b5050925160a00151909252919050565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b807fa5054f728453d3dbe953bdc43e4d0cb97e662ea32d7958190f3dc2da31d9721b5d50565b60408051808201909152606081525f60208201526101005460ff9065ffffffffffff80821691600160301b9004811690828203165f818711612d6a5786612d6c565b815b9050806001016001600160401b03811115612d8957612d896138d9565b604051908082528060200260200182016040528015612dec57816020015b612dd96040805180820182525f8082528251606080820185528152602081810183905293810191909152909182015290565b815260200190600190039081612da75790505b508087525f90612e019087908b9088866133b2565b955090507f000000000000000000000000000000000000000000000000000000000000000088108015612e3357508183115b15612e88575f612e658787877f0000000000000000000000000000000000000000000000000000000000000000613536565b90508015612e865760405163014b3fdb60e11b815260040160405180910390fd5b505b65ffffffffffff167f000000000000000000000000000000000000000000000000000000000000000060ff167f000000000000000000000000000000000000000000000000000000000000000061ffff1602014211602087015250939695505050505050565b604080516060808201835281525f6020808301829052928201529082015161ffff16612f2d5760405163fdac229f60e01b815260040160405180910390fd5b5f826020015161ffff166001600160401b03811115612f4e57612f4e6138d9565b604051908082528060200260200182016040528015612f77578160200160208202803683370190505b5090505f5b836020015161ffff16811015612fff578351612f9d90829061ffff16614347565b49828281518110612fb057612fb061418e565b602002602001018181525050818181518110612fce57612fce61418e565b60200260200101515f5f1b03612ff757604051637bb2fa2f60e11b815260040160405180910390fd5b600101612f7c565b50604080516060810182529182529283015162ffffff16602082015265ffffffffffff4216928101929092525090565b606081015180515f919060068101835b8281101561307b578381815181106130595761305961418e565b6020026020010151602001515f0151516006018201915080600101905061303f565b50604080518281526001830160051b8101909152602080820152855165ffffffffffff16604082015260208601516060820152604086015160ff166080820152608060a082015260c0810183905260068381015f5b85811015613201575f8782815181106130eb576130eb61418e565b60200260200101519050613114858386016005878703901b5f1b60019190910160051b82015290565b5061313d8584835f0151613128575f61312b565b60015b60ff1660019190910160051b82015290565b5060406002840160051b86015260606003840160051b86015260028301602080830151015162ffffff166002820160051b87015260208201516040015165ffffffffffff166003820160051b87015260208201515180516004830160051b8801819052600383015f5b828110156131ea576131e18a8284600101018684815181106131ca576131ca61418e565b602002602001015160019190910160051b82015290565b506001016131a6565b5001600190810195509390930192506130d0915050565b50825160051b60208401206132288480516040516001820160051b83011490151060061b52565b98975050505050505050565b815f0361324057505050565b61325a83838360405180602001604052805f81525061359f565b6111f457604051634c67134d60e11b815260040160405180910390fd5b5f8160405160200161328991906142e6565b604051602081830303815290604052805190602001209050919050565b61ffff811115610ad65760405163161e7a6b60e11b815260040160405180910390fd5b8051606090811b83526020820151811b6014840152604082015160d01b6028840152810151602e8301908152604e8301610b42565b5f818353505060010190565b61331381612a04565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a250565b6060610b42838360405180606001604052806027815260200161439d602791396135dc565b608f5f5b8251811015612ad15782818151811061338d5761338d61418e565b6020026020010151602001515f015151602002600c0182019150806001019050613372565b5f5f825f036133cb575065ffffffffffff90508261352c565b5f5f5b848110156134bb5765ffffffffffff861681015f90815260208a81526040918290208251808401845260018082528451908301805460808187028401810190975260608301818152949693958601949293919284929091849184018282801561345457602002820191905f5260205f20905b815481526020019060010190808311613440575b50505091835250506001919091015462ffffff811660208301526301000000900465ffffffffffff16604090910152905288518990849081106134995761349961418e565b6020908102919091010152546001600160401b031691909101906001016133ce565b5080156134db576134db6001600160a01b038816633b9aca0083026121f9565b855f815181106134ed576134ed61418e565b602002602001015160200151604001519250838501915081886001015f6101000a81548165ffffffffffff021916908365ffffffffffff160217905550505b9550959350505050565b5f8265ffffffffffff168465ffffffffffff160361355557505f613597565b65ffffffffffff8085165f90815260208790526040812060020154630100000090049091169081900361358b575f915050613597565b61ffff83160142101590505b949350505050565b5f6001600160a01b0385166135c757604051634c67134d60e11b815260040160405180910390fd5b5f5f835160208501878988f195945050505050565b60605f5f856001600160a01b0316856040516135f89190614366565b5f60405180830381855af49150503d805f8114613630576040519150601f19603f3d011682016040523d82523d5f602084013e613635565b606091505b509150915061364686838387613650565b9695505050505050565b606083156136be5782515f036136b7576001600160a01b0385163b6136b75760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610996565b5081613597565b61359783838151156136d35781518083602001fd5b8060405162461bcd60e51b815260040161099691906141d0565b60408051606080820183525f8083528351918201845280825260208281018290529382015290918201905b81525f60209091015290565b60405180604001604052806137186040518060e001604052805f65ffffffffffff1681526020015f81526020015f81526020015f6001600160a01b031681526020015f65ffffffffffff1681526020015f8152602001606081525090565b6001600160a01b0381168114610ad6575f5ffd5b5f602082840312156137a6575f5ffd5b8135611c9781613782565b65ffffffffffff81168114610ad6575f5ffd5b5f5f604083850312156137d5575f5ffd5b82356137e0816137b1565b915060208301356137f0816137b1565b809150509250929050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b828110156138cd57868503603f19018452815180516001600160401b0316865260209081015160408288018190528151606091890191909152805160a08901819052919201905f9060c08901905b80831015613892578351825260208201915060208401935060018301925061386f565b5060208481015162ffffff1660608b015260409094015165ffffffffffff166080909901989098525050938401939190910190600101613821565b50929695505050505050565b634e487b7160e01b5f52604160045260245ffd5b604051606081016001600160401b038111828210171561390f5761390f6138d9565b60405290565b604051608081016001600160401b038111828210171561390f5761390f6138d9565b604080519081016001600160401b038111828210171561390f5761390f6138d9565b60405160c081016001600160401b038111828210171561390f5761390f6138d9565b604051601f8201601f191681016001600160401b03811182821017156139a3576139a36138d9565b604052919050565b5f5f604083850312156139bc575f5ffd5b82356139c781613782565b915060208301356001600160401b038111156139e1575f5ffd5b8301601f810185136139f1575f5ffd5b80356001600160401b03811115613a0a57613a0a6138d9565b613a1d601f8201601f191660200161397b565b818152866020838501011115613a31575f5ffd5b816020840160208301375f602083830101528093505050509250929050565b5f60208284031215613a60575f5ffd5b5035919050565b5f5f83601f840112613a77575f5ffd5b5081356001600160401b03811115613a8d575f5ffd5b602083019150836020828501011115613aa4575f5ffd5b9250929050565b5f5f5f5f60408587031215613abe575f5ffd5b84356001600160401b03811115613ad3575f5ffd5b613adf87828801613a67565b90955093505060208501356001600160401b03811115613afd575f5ffd5b613b0987828801613a67565b95989497509550505050565b81516001600160a01b031681526101e081016020830151613b4160208401826001600160a01b03169052565b506040830151613b5c60408401826001600160a01b03169052565b506060830151613b7760608401826001600160a01b03169052565b506080830151613b9260808401826001600160a01b03169052565b5060a0830151613bac60a084018265ffffffffffff169052565b5060c0830151613bc660c084018265ffffffffffff169052565b5060e083015160e0830152610100830151613be761010084018260ff169052565b50610120830151610120830152610140830151613c0b61014084018261ffff169052565b50610160830151613c286101608401826001600160401b03169052565b50610180830151613c456101808401826001600160401b03169052565b506101a0830151613c5d6101a084018261ffff169052565b506101c0830151613c746101c084018260ff169052565b5092915050565b803561ffff81168114613c8c575f5ffd5b919050565b62ffffff81168114610ad6575f5ffd5b5f6060828403128015613cb2575f5ffd5b50613cbb6138ed565b613cc483613c7b565b8152613cd260208401613c7b565b60208201526040830135613ce581613c91565b60408201529392505050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b8051613c8c816137b1565b5f6001600160401b03821115613dac57613dac6138d9565b5060051b60200190565b80518015158114613c8c575f5ffd5b8051613c8c81613c91565b5f60808284031215613de0575f5ffd5b613de8613915565b90508151613df5816137b1565b815260208281015190820152604082015160ff81168114613e14575f5ffd5b604082015260608201516001600160401b03811115613e31575f5ffd5b8201601f81018413613e41575f5ffd5b8051613e54613e4f82613d94565b61397b565b8082825260208201915060208360051b850101925086831115613e75575f5ffd5b602084015b83811015613fb55780516001600160401b03811115613e97575f5ffd5b85016040818a03601f19011215613eac575f5ffd5b613eb4613937565b613ec060208301613db6565b815260408201516001600160401b03811115613eda575f5ffd5b6020818401019250506060828b031215613ef2575f5ffd5b613efa6138ed565b82516001600160401b03811115613f0f575f5ffd5b8301601f81018c13613f1f575f5ffd5b8051613f2d613e4f82613d94565b8082825260208201915060208360051b85010192508e831115613f4e575f5ffd5b6020840193505b82841015613f70578351825260209384019390910190613f55565b845250613f8291505060208401613dc5565b6020820152613f9360408401613d89565b6040820152806020830152508085525050602083019250602081019050613e7a565b5060608501525091949350505050565b5f60c08284031215613fd5575f5ffd5b613fdd613959565b90508151613fea816137b1565b81526020820151613ffa816137b1565b6020820152604082015161400d816137b1565b6040820152606082015161402081613782565b60608201526080828101519082015260a09182015191810191909152919050565b5f5f5f5f5f8587036101e0811215614057575f5ffd5b8651614062816137b1565b955060c0601f1982011215614075575f5ffd5b5061407e613959565b602087015161408c816137b1565b8152604087015161409c816137b1565b602082015260608701516140af816137b1565b604082015260808701516140c2816137b1565b606082015260a08701516140d5816137b1565b608082015260c087015160a082015260e08701519094506001600160401b038111156140ff575f5ffd5b61410b88828901613dd0565b93505061411c876101008801613fc5565b6101c09690960151949793965091949392915050565b5f8261414c57634e487b7160e01b5f52601260045260245ffd5b500690565b5f60208284031215614161575f5ffd5b5051919050565b5f60208284031215614178575f5ffd5b81516001600160401b0381168114611c97575f5ffd5b634e487b7160e01b5f52603260045260245ffd5b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f610b4260208301846141a2565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b848152836020820152606060408201525f6136466060830184866141e2565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b6001600160a01b03841681526040602082018190525f9061429890830184866141e2565b95945050505050565b5f602082840312156142b1575f5ffd5b8151611c97816137b1565b5f5f604083850312156142cd575f5ffd5b6142d683613db6565b6020939093015192949293505050565b815165ffffffffffff168152602082015160808201906002811061431857634e487b7160e01b5f52602160045260245ffd5b60208301526040838101516001600160a01b039081169184019190915260609384015116929091019190915290565b80820180821115610b4557634e487b7160e01b5f52601160045260245ffd5b5f82518060208501845e5f92019182525091905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220d4f1ac9fd49ea7eee6187da54098c4e23fef4ba2c14f9cae0b613398b890867d64736f6c634300081e0033000000000000000000000000f4c259d287cc39e197b1148a198227472ca50b65000000000000000000000000638f73a482478130bea16ce151e48aec0ab283e0000000000000000000000000bb128fd4942e8143b8dc10f38ccfeadb3254426400000000000000000000000000acc4d239aa05c797e038b7701be8be6940143900000000000000000000000012100faa7b157e9947340b44409fc7e27ec0abef

Deployed ByteCode

0x60806040526004361061017b575f3560e01c8063715018a6116100cd578063a834725a11610087578063e305333511610062578063e305333514610879578063e30c3978146108a5578063ea191743146108c2578063f2fde38b146108e1575f5ffd5b8063a834725a1461050d578063c3f909d41461052c578063df596d9e14610866575f5ffd5b8063715018a61461048157806379ba5097146104955780638456cb59146104a95780638abf6077146104bd5780638da5cb5b146104d15780639791e644146104ee575f5ffd5b806340df98661161013857806359db6e851161011357806359db6e85146102f95780635c975abb146103185780635ccc1718146103385780636aa6a01a1461036e575f5ffd5b806340df9866146102985780634f1ef286146102c457806352d1902d146102d7575f5ffd5b80630423c7de1461017f57806304f3bcec146101b957806319ab453c146101ff5780633075db56146102205780633659cfe6146102655780633f4ba83a14610284575b5f5ffd5b34801561018a575f5ffd5b5060fb5461019d9065ffffffffffff1681565b60405165ffffffffffff90911681526020015b60405180910390f35b3480156101c4575f5ffd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040516001600160a01b0390911681526020016101b0565b34801561020a575f5ffd5b5061021e610219366004613796565b610900565b005b34801561022b575f5ffd5b5060027fa5054f728453d3dbe953bdc43e4d0cb97e662ea32d7958190f3dc2da31d9721b5c60ff16145b60405190151581526020016101b0565b348015610270575f5ffd5b5061021e61027f366004613796565b610a12565b34801561028f575f5ffd5b5061021e610ad9565b3480156102a3575f5ffd5b506102b76102b23660046137c4565b610b34565b6040516101b091906137fb565b61021e6102d23660046139ab565b610b4b565b3480156102e2575f5ffd5b506102eb610c00565b6040519081526020016101b0565b348015610304575f5ffd5b5061021e610313366004613a50565b610cb1565b348015610323575f5ffd5b5061025560c954610100900460ff1660021490565b348015610343575f5ffd5b50610100546040805165ffffffffffff8084168252600160301b9093049092166020830152016101b0565b348015610379575f5ffd5b5061040e6040805160c0810182525f80825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c08101825260fc5465ffffffffffff8082168352600160301b820481166020840152600160601b8204811693830193909352600160901b810483166060830152600160c01b9004909116608082015260fd5460a082015290565b6040516101b091905f60c08201905065ffffffffffff835116825265ffffffffffff602084015116602083015265ffffffffffff604084015116604083015265ffffffffffff606084015116606083015265ffffffffffff608084015116608083015260a083015160a083015292915050565b34801561048c575f5ffd5b5061021e610e63565b3480156104a0575f5ffd5b5061021e610e74565b3480156104b4575f5ffd5b5061021e610eeb565b3480156104c8575f5ffd5b506101e7610f40565b3480156104dc575f5ffd5b506033546001600160a01b03166101e7565b3480156104f9575f5ffd5b5061021e610508366004613aab565b610f4e565b348015610518575f5ffd5b506102eb610527366004613a50565b611064565b348015610537575f5ffd5b50610859604080516101e0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c0810191909152604051806101e001604052807f00000000000000000000000012100faa7b157e9947340b44409fc7e27ec0abef6001600160a01b031681526020017f000000000000000000000000f4c259d287cc39e197b1148a198227472ca50b656001600160a01b031681526020017f000000000000000000000000638f73a482478130bea16ce151e48aec0ab283e06001600160a01b031681526020017f000000000000000000000000bb128fd4942e8143b8dc10f38ccfeadb325442646001600160a01b031681526020017f00000000000000000000000000acc4d239aa05c797e038b7701be8be694014396001600160a01b031681526020017f0000000000000000000000000000000000000000000000000000000000001c2065ffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000b465ffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000006481526020017f000000000000000000000000000000000000000000000000000000000000004b60ff1681526020017f000000000000000000000000000000000000000000000000000000000000000181526020017f000000000000000000000000000000000000000000000000000000000000000061ffff1681526020017f00000000000000000000000000000000000000000000000000000000009896806001600160401b031681526020017f00000000000000000000000000000000000000000000000000000000000000326001600160401b031681526020017f000000000000000000000000000000000000000000000000000000000000018061ffff1681526020017f000000000000000000000000000000000000000000000000000000000000000560ff16815250905090565b6040516101b09190613b15565b61021e610874366004613ca1565b6110a7565b348015610884575f5ffd5b5061088d6111f9565b6040516001600160401b0390911681526020016101b0565b3480156108b0575f5ffd5b506065546001600160a01b03166101e7565b3480156108cd575f5ffd5b5061021e6108dc366004613aab565b6112c4565b3480156108ec575f5ffd5b5061021e6108fb366004613796565b6117c6565b5f54610100900460ff161580801561091e57505f54600160ff909116105b806109375750303b15801561093757505f5460ff166001145b61099f5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b5f805460ff1916600117905580156109c0575f805461ff0019166101001790555b6109c982611837565b8015610a0e575f805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6001600160a01b037f000000000000000000000000ed704fbe2b64436d6a65a3f7b8c128a647ee97df163003610a5a5760405162461bcd60e51b815260040161099690613cf1565b7f000000000000000000000000ed704fbe2b64436d6a65a3f7b8c128a647ee97df6001600160a01b0316610a8c611895565b6001600160a01b031614610ab25760405162461bcd60e51b815260040161099690613d3d565b610abb816118b0565b604080515f80825260208201909252610ad6918391906118b8565b50565b610ae1611a22565b610af560c9805461ff001916610100179055565b6040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa9060200160405180910390a1610b32335f611a53565b565b6060610b4260ff8484611a5b565b90505b92915050565b6001600160a01b037f000000000000000000000000ed704fbe2b64436d6a65a3f7b8c128a647ee97df163003610b935760405162461bcd60e51b815260040161099690613cf1565b7f000000000000000000000000ed704fbe2b64436d6a65a3f7b8c128a647ee97df6001600160a01b0316610bc5611895565b6001600160a01b031614610beb5760405162461bcd60e51b815260040161099690613d3d565b610bf4826118b0565b610a0e828260016118b8565b5f306001600160a01b037f000000000000000000000000ed704fbe2b64436d6a65a3f7b8c128a647ee97df1614610c9f5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610996565b505f51602061437d5f395f51905f5290565b610cb9611c9e565b60fb54604051633dd0723360e21b81526004810183905265ffffffffffff90911660248201525f908190819081908190739c9d925f3d7d820a994811c17480fe67875a15629063f741c8cc906044015f60405180830381865af4158015610d22573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610d499190810190614041565b60fb805465ffffffffffff191665ffffffffffff87811691909117909155845160fc80546020880151604089015160608a015160808b01519587166bffffffffffffffffffffffff1990941693909317600160301b92871692909202919091176bffffffffffffffffffffffff60601b1916600160601b9186169190910265ffffffffffff60901b191617600160901b918516919091021765ffffffffffff60c01b1916600160c01b929093169190910291909117905560a084015160fd55939850919650945092509050610e1e5f82611cf8565b610e288284611d42565b6040518681527fe4356761c97932c05c3ee0859fb1a5e4f91f7a1d7a3752c7d5a72d5cc6ecb2d29060200160405180910390a1505050505050565b610e6b611c9e565b610b325f611d9a565b60655433906001600160a01b03168114610ee25760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b6064820152608401610996565b610ad681611d9a565b610ef3611db3565b60c9805461ff0019166102001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2589060200160405180910390a1610b32336001611a53565b5f610f49611895565b905090565b610f56611de5565b610f606002611e2a565b5f610f9f83838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250611e3392505050565b9050610faa81611e8b565b60fc5465ffffffffffff80821691600160301b8104821691600160601b9091041682610fe95760405163ba74d80f60e01b815260040160405180910390fd5b5f5f610ff9868b8b888888611ec7565b60fc80544365ffffffffffff908116600160301b026bffffffffffffffffffffffff1990921660018b019190911617179055815191935091506110449061103f84612168565b611cf8565b61104e8282611d42565b50505050505061105e6001611e2a565b50505050565b5f60fe816110927f000000000000000000000000000000000000000000000000000000000000006485614132565b81526020019081526020015f20549050919050565b60015f5260fe6020527f457c8a48b4735f56b938837eb0a8a5f9c55f23c1a85767ce3b65c3e59d3d32b754806110f05760405163f37a8b1360e01b815260040160405180910390fd5b604080516312b2aa9160e31b815260ff60048201526001600160401b037f0000000000000000000000000000000000000000000000000000000000989680811660248301527f0000000000000000000000000000000000000000000000000000000000000032166044820152835161ffff908116606483015260208501511660848201529083015162ffffff1660a48201525f90734c0dbff2abf9cbd7641cf38fc5765949a8e5b1bf9063959554889060c401602060405180830381865af41580156111be573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111e29190614151565b905080156111f4576111f433826121f9565b505050565b6040516343c3d71960e01b815260ff60048201526001600160401b037f0000000000000000000000000000000000000000000000000000000000989680811660248301527f00000000000000000000000000000000000000000000000000000000000000321660448201525f90734c0dbff2abf9cbd7641cf38fc5765949a8e5b1bf906343c3d71990606401602060405180830381865af41580156112a0573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f499190614168565b5f6112ce33612204565b6040805160c08101825260fc5465ffffffffffff8082168352600160301b82048116602080850191909152600160601b8304821684860152600160901b830482166060850152600160c01b90920416608083015260fd5460a08301528251601f8901829004820281018201909352878352929350915f916113689189908990819084018382808284375f9201919091525061230192505050565b80519091505f808061137a8685612471565b9250925092505f8165ffffffffffff165f146113c2578460c001516001830365ffffffffffff16815181106113b1576113b161418e565b6020026020010151606001516113c8565b84602001515b9050808760a00151146113ee5760405163198070b360e01b815260040160405180910390fd5b6113f783611064565b85604001511461141a5760405163f904c2fd60e01b815260040160405180910390fd5b87611429576114298583612542565b85602001518061146b57507f000000000000000000000000000000000000000000000000000000000000018061ffff1687608001510165ffffffffffff164210155b1561156a577f00000000000000000000000000acc4d239aa05c797e038b7701be8be694014396001600160a01b031663c9a0b8c86040518060600160405280886080015165ffffffffffff1681526020018860c0015160018903815181106114d5576114d561418e565b60200260200101516060015181526020018860a001518152506040518263ffffffff1660e01b815260040161152e9190815165ffffffffffff168152602080830151908201526040918201519181019190915260600190565b5f604051808303815f87803b158015611545575f5ffd5b505af1158015611557573d5f5f3e3d5ffd5b50505065ffffffffffff42166080890152505b65ffffffffffff80841660408901524216606088015260c085015180515f19860190811061159a5761159a61418e565b6020026020010151606001518760a00181815250508660fc5f820151815f015f6101000a81548165ffffffffffff021916908365ffffffffffff1602179055506020820151815f0160066101000a81548165ffffffffffff021916908365ffffffffffff1602179055506040820151815f01600c6101000a81548165ffffffffffff021916908365ffffffffffff1602179055506060820151815f0160126101000a81548165ffffffffffff021916908365ffffffffffff1602179055506080820151815f0160186101000a81548165ffffffffffff021916908365ffffffffffff16021790555060a082015181600101559050507fb2d5049ba96efb9e1fee66a51e4e6cbdfa2949627891ee29c6e4281abb8da03c6116c7604051806020016040528089815250612748565b6040516116d491906141d0565b60405180910390a15f61172d886060015165ffffffffffff168760c001518565ffffffffffff168151811061170b5761170b61418e565b60200260200101516040015165ffffffffffff1661287290919063ffffffff16565b420390507f000000000000000000000000f4c259d287cc39e197b1148a198227472ca50b656001600160a01b03166314bcf3dd8261176a89612887565b8e8e6040518563ffffffff1660e01b815260040161178b949392919061420a565b5f6040518083038186803b1580156117a1575f5ffd5b505afa1580156117b3573d5f5f3e3d5ffd5b5050505050505050505050505050505050565b6117ce611c9e565b606580546001600160a01b0383166001600160a01b031990911681179091556117ff6033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b5f54610100900460ff1661185d5760405162461bcd60e51b815260040161099690614229565b6118656129de565b6118836001600160a01b0382161561187d5781611d9a565b33611d9a565b5060c9805461ff001916610100179055565b5f51602061437d5f395f51905f52546001600160a01b031690565b610ad6611c9e565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156118eb576111f483612a04565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611945575060408051601f3d908101601f1916820190925261194291810190614151565b60015b6119a85760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610996565b5f51602061437d5f395f51905f528114611a165760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610996565b506111f4838383612a9f565b611a3660c954610100900460ff1660021490565b610b325760405163bae6e2a960e01b815260040160405180910390fd5b610a0e611c9e565b600183015460609065ffffffffffff80821691600160301b90048116908516821180611a9757508065ffffffffffff168565ffffffffffff1610155b80611aa8575065ffffffffffff8416155b15611b1157604080515f8082526020820190925290611b07565b611af46040805180820182525f8082528251606080820185528152602081810183905293810191909152909182015290565b815260200190600190039081611ac25790505b5092505050611c97565b5f611b2965ffffffffffff8784038116908716612ac3565b9050806001600160401b03811115611b4357611b436138d9565b604051908082528060200260200182016040528015611ba657816020015b611b936040805180820182525f8082528251606080820185528152602081810183905293810191909152909182015290565b815260200190600190039081611b615790505b5093505f5b81811015611c925765ffffffffffff871681015f90815260208981526040918290208251808401845281546001600160401b0316815283516001830180546080818702840181019097526060830181815293969495870194929391928492918491840182828015611c3957602002820191905f5260205f20905b815481526020019060010190808311611c25575b50505091835250506001919091015462ffffff811660208301526301000000900465ffffffffffff166040909101529052508551869083908110611c7f57611c7f61418e565b6020908102919091010152600101611bab565b505050505b9392505050565b6033546001600160a01b03163314610b325760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610996565b8060fe5f611d2e7f000000000000000000000000000000000000000000000000000000000000006465ffffffffffff8716614132565b815260208101919091526040015f20555050565b60408051808201909152828152602081018290527f10b2060c55406ea48522476f67fd813d4984b12078555d3e2a377e35839d7d01611d8082612ad7565b604051611d8d91906141d0565b60405180910390a1505050565b606580546001600160a01b0319169055610ad681612cb1565b611dc760c954610100900460ff1660021490565b15610b325760405163bae6e2a960e01b815260040160405180910390fd5b60027fa5054f728453d3dbe953bdc43e4d0cb97e662ea32d7958190f3dc2da31d9721b5c60ff1603610b325760405163dfc60d8560e01b815260040160405180910390fd5b610ad681612d02565b611e3b6136ed565b60208281015160d01c82526026830151828201805160f092831c905260288501518151921c9190920152602a830151905160e89190911c604091820152602d9092015160f81c9181019190915290565b805165ffffffffffff161580611eaa5750805165ffffffffffff164211155b610ad65760405163559895a360e01b815260040160405180910390fd5b6040805160c0810182525f80825260208201819052918101829052606081018290526080810182905260a0810191909152604080516080810182525f80825260208201819052918101919091526060808201528365ffffffffffff164311611f42576040516349517a1d60e11b815260040160405180910390fd5b5f611f7d868590035f1990810165ffffffffffff167f0000000000000000000000000000000000000000000000000000000000000064030190565b11611f9b5760405163eaabac9b60e01b815260040160405180910390fd5b5f611fad338a6040015160ff16612d28565b905060405180604001604052805f15158152602001611fcf8b60200151612eee565b9052815180515f198101908110611fe857611fe861418e565b60200260200101819052505f816020015161209257604051635600026d60e11b81526001600160a01b037f000000000000000000000000638f73a482478130bea16ce151e48aec0ab283e0169063ac0004da9061204d9033908d908d90600401614274565b6020604051808303815f875af1158015612069573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061208d91906142a1565b612094565b5f5b90505f60014303905060405180608001604052808265ffffffffffff168152602001824081526020017f000000000000000000000000000000000000000000000000000000000000004b60ff168152602001845f015181525093506040518060c001604052808965ffffffffffff1681526020014265ffffffffffff1681526020018365ffffffffffff168152602001336001600160a01b0316815260200161214760018b0365ffffffffffff16611064565b81526020016121558661302f565b8152509450505050965096945050505050565b604080516006815260e08101909152815165ffffffffffff1660208201525f90602083015165ffffffffffff166040820152604083015165ffffffffffff16606082015260608301516001600160a01b03166080820152608083015160a082015260a083015160c0820152805160051b6020820120611c978280516040516001820160051b83011490151060061b52565b610a0e82825a613234565b5f7f000000000000000000000000bb128fd4942e8143b8dc10f38ccfeadb325442646001600160a01b031661223a57505f919050565b604051633326844b60e11b81526001600160a01b0383811660048301525f9182917f000000000000000000000000bb128fd4942e8143b8dc10f38ccfeadb32544264169063664d0896906024016040805180830381865afa1580156122a1573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122c591906142bc565b91509150805f036122d957505f9392505050565b816122f75760405163c1a58f1960e01b815260040160405180910390fd5b5060019392505050565b612309613724565b602082810151825160d091821c90526026840151835190920191909152604683015182516040015260668301518251606091821c910152607a8301518251911c608091820152820151815160a09081019190915282015160a283019060f01c806001600160401b03811115612380576123806138d9565b6040519080825280602002602001820160405280156123d057816020015b604080516080810182525f8082526020808301829052928201819052606082015282525f1990920191018161239e5790505b50835160c001525f5b8161ffff1681101561245f57604080516080810182525f8082526020820181815292820181815260608084019283528751811c84526014880151901c909352602886015160d01c909252602e850151909152604e8401855160c001518051849081106124475761244761418e565b602090810291909101019190915292506001016123d9565b50505160f81c15156020820152919050565b604082015160c082015151905f90819060010165ffffffffffff16836124aa5760405163c2e5347d60e01b815260040160405180910390fd5b845165ffffffffffff168110156124d4576040516363db3a4160e01b815260040160405180910390fd5b845186515f1965ffffffffffff92831687010194501683106125095760405163677c56f160e01b815260040160405180910390fd5b8083101561252a5760405163181432e760e11b815260040160405180910390fd5b845f015165ffffffffffff1681039150509250925092565b5f6125e97f00000000000000000000000000000000000000000000000000000000000000b460fc5f0160129054906101000a900465ffffffffffff160165ffffffffffff167f0000000000000000000000000000000000000000000000000000000000001c208560c001518565ffffffffffff16815181106125c6576125c661418e565b6020026020010151604001510165ffffffffffff1661287290919063ffffffff16565b90508042116125f757505050565b60408051608081019091528351830165ffffffffffff1681525f9060208101600181526020018560c001518565ffffffffffff168151811061263b5761263b61418e565b6020026020010151602001516001600160a01b0316815260200185606001516001600160a01b031681525090507f00000000000000000000000000acc4d239aa05c797e038b7701be8be694014396001600160a01b03166366ca2bc06126a083613277565b6040518263ffffffff1660e01b81526004016126be91815260200190565b6020604051808303815f875af11580156126da573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126fe9190614151565b50805f015165ffffffffffff167f8796b99bbf275a983988181e85b42502d9347327f4dde674320bec3879bcc5e18260405161273a91906142e6565b60405180910390a250505050565b80515160c08101515160609190604e02608301806001600160401b03811115612773576127736138d9565b6040519080825280601f01601f19166020018201604052801561279d576020820181803683370190505b50825160d090811b602083810191909152840151602683015260408401516046830152606080850151901b606683015260808085015190911b607a83015260a0808501519183019190915260c0840151519194508401906127fd906132a6565b60c08301515160f01b81526002015f5b8360c001515181101561284b57612841828560c0015183815181106128345761283461418e565b60200260200101516132c9565b915060010161280d565b5061286981865f015160200151612862575f6132fe565b60016132fe565b50505050919050565b5f8183116128805781610b42565b5090919050565b60c081015180515f919060096004820201836128b38260408051828152600190920160051b8201905290565b6020808201529050855165ffffffffffff166040820152602086015160608201526040860151608082015260608601516001600160a01b031660a0820152608086015165ffffffffffff1660c082015260a086015160e082015260e0610100820152610120810183905260095f5b848110156129ac575f86828151811061293c5761293c61418e565b602090810291909101015180516001600160a01b03166001850160051b860152905060208101516001600160a01b03166002840160051b850152604081015165ffffffffffff166003840160051b85015260608101516004840160051b8501525060049190910190600101612921565b50815160051b60208301206129d38380516040516001820160051b83011490151060061b52565b979650505050505050565b5f54610100900460ff16610b325760405162461bcd60e51b815260040161099690614229565b6001600160a01b0381163b612a715760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610996565b5f51602061437d5f395f51905f5280546001600160a01b0319166001600160a01b0392909216919091179055565b612aa88361330a565b5f82511180612ab45750805b156111f45761105e8383613349565b5f818311612ad15782610b42565b50919050565b60605f612aeb83602001516060015161336e565b9050806001600160401b03811115612b0557612b056138d9565b6040519080825280601f01601f191660200182016040528015612b2f576020820181803683370190505b5083515160d090811b6020838101919091528551606090810151901b60268401528551810151821b603a8401528551604090810151831b81850152865160800151604685015281870180515190931b6066850152825190910151606c84015290510151909250608c830190612ba59082906132fe565b60208501516060015151909150612bbb816132a6565b612bcb828260f01b815260020190565b91505f5b81811015612ca1575f8660200151606001518281518110612bf257612bf261418e565b60200260200101519050612c0e84825f0151612862575f6132fe565b60208201515151909450612c21816132a6565b612c31858260f01b815260020190565b94505f5b81811015612c7457612c6a8684602001515f01518381518110612c5a57612c5a61418e565b6020026020010151815260200190565b9550600101612c35565b5050602090810180519091015160e81b8452516040015160d01b6003840152600990920191600101612bcf565b5050925160a00151909252919050565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b807fa5054f728453d3dbe953bdc43e4d0cb97e662ea32d7958190f3dc2da31d9721b5d50565b60408051808201909152606081525f60208201526101005460ff9065ffffffffffff80821691600160301b9004811690828203165f818711612d6a5786612d6c565b815b9050806001016001600160401b03811115612d8957612d896138d9565b604051908082528060200260200182016040528015612dec57816020015b612dd96040805180820182525f8082528251606080820185528152602081810183905293810191909152909182015290565b815260200190600190039081612da75790505b508087525f90612e019087908b9088866133b2565b955090507f000000000000000000000000000000000000000000000000000000000000000188108015612e3357508183115b15612e88575f612e658787877f0000000000000000000000000000000000000000000000000000000000000000613536565b90508015612e865760405163014b3fdb60e11b815260040160405180910390fd5b505b65ffffffffffff167f000000000000000000000000000000000000000000000000000000000000000560ff167f000000000000000000000000000000000000000000000000000000000000000061ffff1602014211602087015250939695505050505050565b604080516060808201835281525f6020808301829052928201529082015161ffff16612f2d5760405163fdac229f60e01b815260040160405180910390fd5b5f826020015161ffff166001600160401b03811115612f4e57612f4e6138d9565b604051908082528060200260200182016040528015612f77578160200160208202803683370190505b5090505f5b836020015161ffff16811015612fff578351612f9d90829061ffff16614347565b49828281518110612fb057612fb061418e565b602002602001018181525050818181518110612fce57612fce61418e565b60200260200101515f5f1b03612ff757604051637bb2fa2f60e11b815260040160405180910390fd5b600101612f7c565b50604080516060810182529182529283015162ffffff16602082015265ffffffffffff4216928101929092525090565b606081015180515f919060068101835b8281101561307b578381815181106130595761305961418e565b6020026020010151602001515f0151516006018201915080600101905061303f565b50604080518281526001830160051b8101909152602080820152855165ffffffffffff16604082015260208601516060820152604086015160ff166080820152608060a082015260c0810183905260068381015f5b85811015613201575f8782815181106130eb576130eb61418e565b60200260200101519050613114858386016005878703901b5f1b60019190910160051b82015290565b5061313d8584835f0151613128575f61312b565b60015b60ff1660019190910160051b82015290565b5060406002840160051b86015260606003840160051b86015260028301602080830151015162ffffff166002820160051b87015260208201516040015165ffffffffffff166003820160051b87015260208201515180516004830160051b8801819052600383015f5b828110156131ea576131e18a8284600101018684815181106131ca576131ca61418e565b602002602001015160019190910160051b82015290565b506001016131a6565b5001600190810195509390930192506130d0915050565b50825160051b60208401206132288480516040516001820160051b83011490151060061b52565b98975050505050505050565b815f0361324057505050565b61325a83838360405180602001604052805f81525061359f565b6111f457604051634c67134d60e11b815260040160405180910390fd5b5f8160405160200161328991906142e6565b604051602081830303815290604052805190602001209050919050565b61ffff811115610ad65760405163161e7a6b60e11b815260040160405180910390fd5b8051606090811b83526020820151811b6014840152604082015160d01b6028840152810151602e8301908152604e8301610b42565b5f818353505060010190565b61331381612a04565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a250565b6060610b42838360405180606001604052806027815260200161439d602791396135dc565b608f5f5b8251811015612ad15782818151811061338d5761338d61418e565b6020026020010151602001515f015151602002600c0182019150806001019050613372565b5f5f825f036133cb575065ffffffffffff90508261352c565b5f5f5b848110156134bb5765ffffffffffff861681015f90815260208a81526040918290208251808401845260018082528451908301805460808187028401810190975260608301818152949693958601949293919284929091849184018282801561345457602002820191905f5260205f20905b815481526020019060010190808311613440575b50505091835250506001919091015462ffffff811660208301526301000000900465ffffffffffff16604090910152905288518990849081106134995761349961418e565b6020908102919091010152546001600160401b031691909101906001016133ce565b5080156134db576134db6001600160a01b038816633b9aca0083026121f9565b855f815181106134ed576134ed61418e565b602002602001015160200151604001519250838501915081886001015f6101000a81548165ffffffffffff021916908365ffffffffffff160217905550505b9550959350505050565b5f8265ffffffffffff168465ffffffffffff160361355557505f613597565b65ffffffffffff8085165f90815260208790526040812060020154630100000090049091169081900361358b575f915050613597565b61ffff83160142101590505b949350505050565b5f6001600160a01b0385166135c757604051634c67134d60e11b815260040160405180910390fd5b5f5f835160208501878988f195945050505050565b60605f5f856001600160a01b0316856040516135f89190614366565b5f60405180830381855af49150503d805f8114613630576040519150601f19603f3d011682016040523d82523d5f602084013e613635565b606091505b509150915061364686838387613650565b9695505050505050565b606083156136be5782515f036136b7576001600160a01b0385163b6136b75760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610996565b5081613597565b61359783838151156136d35781518083602001fd5b8060405162461bcd60e51b815260040161099691906141d0565b60408051606080820183525f8083528351918201845280825260208281018290529382015290918201905b81525f60209091015290565b60405180604001604052806137186040518060e001604052805f65ffffffffffff1681526020015f81526020015f81526020015f6001600160a01b031681526020015f65ffffffffffff1681526020015f8152602001606081525090565b6001600160a01b0381168114610ad6575f5ffd5b5f602082840312156137a6575f5ffd5b8135611c9781613782565b65ffffffffffff81168114610ad6575f5ffd5b5f5f604083850312156137d5575f5ffd5b82356137e0816137b1565b915060208301356137f0816137b1565b809150509250929050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b828110156138cd57868503603f19018452815180516001600160401b0316865260209081015160408288018190528151606091890191909152805160a08901819052919201905f9060c08901905b80831015613892578351825260208201915060208401935060018301925061386f565b5060208481015162ffffff1660608b015260409094015165ffffffffffff166080909901989098525050938401939190910190600101613821565b50929695505050505050565b634e487b7160e01b5f52604160045260245ffd5b604051606081016001600160401b038111828210171561390f5761390f6138d9565b60405290565b604051608081016001600160401b038111828210171561390f5761390f6138d9565b604080519081016001600160401b038111828210171561390f5761390f6138d9565b60405160c081016001600160401b038111828210171561390f5761390f6138d9565b604051601f8201601f191681016001600160401b03811182821017156139a3576139a36138d9565b604052919050565b5f5f604083850312156139bc575f5ffd5b82356139c781613782565b915060208301356001600160401b038111156139e1575f5ffd5b8301601f810185136139f1575f5ffd5b80356001600160401b03811115613a0a57613a0a6138d9565b613a1d601f8201601f191660200161397b565b818152866020838501011115613a31575f5ffd5b816020840160208301375f602083830101528093505050509250929050565b5f60208284031215613a60575f5ffd5b5035919050565b5f5f83601f840112613a77575f5ffd5b5081356001600160401b03811115613a8d575f5ffd5b602083019150836020828501011115613aa4575f5ffd5b9250929050565b5f5f5f5f60408587031215613abe575f5ffd5b84356001600160401b03811115613ad3575f5ffd5b613adf87828801613a67565b90955093505060208501356001600160401b03811115613afd575f5ffd5b613b0987828801613a67565b95989497509550505050565b81516001600160a01b031681526101e081016020830151613b4160208401826001600160a01b03169052565b506040830151613b5c60408401826001600160a01b03169052565b506060830151613b7760608401826001600160a01b03169052565b506080830151613b9260808401826001600160a01b03169052565b5060a0830151613bac60a084018265ffffffffffff169052565b5060c0830151613bc660c084018265ffffffffffff169052565b5060e083015160e0830152610100830151613be761010084018260ff169052565b50610120830151610120830152610140830151613c0b61014084018261ffff169052565b50610160830151613c286101608401826001600160401b03169052565b50610180830151613c456101808401826001600160401b03169052565b506101a0830151613c5d6101a084018261ffff169052565b506101c0830151613c746101c084018260ff169052565b5092915050565b803561ffff81168114613c8c575f5ffd5b919050565b62ffffff81168114610ad6575f5ffd5b5f6060828403128015613cb2575f5ffd5b50613cbb6138ed565b613cc483613c7b565b8152613cd260208401613c7b565b60208201526040830135613ce581613c91565b60408201529392505050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b8051613c8c816137b1565b5f6001600160401b03821115613dac57613dac6138d9565b5060051b60200190565b80518015158114613c8c575f5ffd5b8051613c8c81613c91565b5f60808284031215613de0575f5ffd5b613de8613915565b90508151613df5816137b1565b815260208281015190820152604082015160ff81168114613e14575f5ffd5b604082015260608201516001600160401b03811115613e31575f5ffd5b8201601f81018413613e41575f5ffd5b8051613e54613e4f82613d94565b61397b565b8082825260208201915060208360051b850101925086831115613e75575f5ffd5b602084015b83811015613fb55780516001600160401b03811115613e97575f5ffd5b85016040818a03601f19011215613eac575f5ffd5b613eb4613937565b613ec060208301613db6565b815260408201516001600160401b03811115613eda575f5ffd5b6020818401019250506060828b031215613ef2575f5ffd5b613efa6138ed565b82516001600160401b03811115613f0f575f5ffd5b8301601f81018c13613f1f575f5ffd5b8051613f2d613e4f82613d94565b8082825260208201915060208360051b85010192508e831115613f4e575f5ffd5b6020840193505b82841015613f70578351825260209384019390910190613f55565b845250613f8291505060208401613dc5565b6020820152613f9360408401613d89565b6040820152806020830152508085525050602083019250602081019050613e7a565b5060608501525091949350505050565b5f60c08284031215613fd5575f5ffd5b613fdd613959565b90508151613fea816137b1565b81526020820151613ffa816137b1565b6020820152604082015161400d816137b1565b6040820152606082015161402081613782565b60608201526080828101519082015260a09182015191810191909152919050565b5f5f5f5f5f8587036101e0811215614057575f5ffd5b8651614062816137b1565b955060c0601f1982011215614075575f5ffd5b5061407e613959565b602087015161408c816137b1565b8152604087015161409c816137b1565b602082015260608701516140af816137b1565b604082015260808701516140c2816137b1565b606082015260a08701516140d5816137b1565b608082015260c087015160a082015260e08701519094506001600160401b038111156140ff575f5ffd5b61410b88828901613dd0565b93505061411c876101008801613fc5565b6101c09690960151949793965091949392915050565b5f8261414c57634e487b7160e01b5f52601260045260245ffd5b500690565b5f60208284031215614161575f5ffd5b5051919050565b5f60208284031215614178575f5ffd5b81516001600160401b0381168114611c97575f5ffd5b634e487b7160e01b5f52603260045260245ffd5b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f610b4260208301846141a2565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b848152836020820152606060408201525f6136466060830184866141e2565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b6001600160a01b03841681526040602082018190525f9061429890830184866141e2565b95945050505050565b5f602082840312156142b1575f5ffd5b8151611c97816137b1565b5f5f604083850312156142cd575f5ffd5b6142d683613db6565b6020939093015192949293505050565b815165ffffffffffff168152602082015160808201906002811061431857634e487b7160e01b5f52602160045260245ffd5b60208301526040838101516001600160a01b039081169184019190915260609384015116929091019190915290565b80820180821115610b4557634e487b7160e01b5f52601160045260245ffd5b5f82518060208501845e5f92019182525091905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220d4f1ac9fd49ea7eee6187da54098c4e23fef4ba2c14f9cae0b613398b890867d64736f6c634300081e0033