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

Contract Address Details

0xcB84cF9bfAe383b73Dc23C5EFF792929D714029A

Contract Name
DevnetInbox
Creator
0x4779d1–4df7b8 at 0x37156b–f28bf8
Balance
0 ETH
Tokens
Fetching tokens...
Transactions
Fetching transactions...
Transfers
Fetching transfers...
Gas Used
Fetching gas used...
Last Balance Update
21208
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
2026-01-09T13:04:29.831894Z

Constructor Arguments

0x000000000000000000000000461461e95de3cc306d5424f554463c162433384e000000000000000000000000cfb57e95cbab87bfd167b3eddd5c11e2d1613b2200000000000000000000000053789e39e3310737e8c8ced483032aac25b39ded000000000000000000000000cbf1639b8809adff74bd59ec292e436107852cc9000000000000000000000000a20182131658295f37c1a1efdbdc89eff97d9c58000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Arg [0] (address) : 0x461461e95de3cc306d5424f554463c162433384e
Arg [1] (address) : 0xcfb57e95cbab87bfd167b3eddd5c11e2d1613b22
Arg [2] (address) : 0x53789e39e3310737e8c8ced483032aac25b39ded
Arg [3] (address) : 0xcbf1639b8809adff74bd59ec292e436107852cc9
Arg [4] (address) : 0xa20182131658295f37c1a1efdbdc89eff97d9c58
Arg [5] (uint64) : 0
Arg [6] (uint64) : 0
Arg [7] (uint48) : 0

              

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 _bondToken,
        uint64 _minBond,
        uint64 _livenessBond,
        uint48 _withdrawalDelay
    )
        Inbox(Config({
                proofVerifier: _proofVerifier,
                proposerChecker: _proposerChecker,
                proverWhitelist: _proverWhitelist,
                signalService: _signalService,
                bondToken: _bondToken,
                minBond: _minBond,
                livenessBond: _livenessBond,
                withdrawalDelay: _withdrawalDelay,
                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();
    }
}
        

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/layer1/verifiers/IProofVerifier.sol

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

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

contracts/shared/common/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_);
}
          

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

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

/// @title LibBlobs
/// @notice Library for handling blobs.
/// @custom:security-contact security@taiko.xyz
library LibBlobs {
    /// @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);
}
          

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

node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 amount) external returns (bool);
}
          

node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/IERC20Permit.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 *
 * ==== Security Considerations
 *
 * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
 * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
 * considered as an intention to spend the allowance in any specific way. The second is that because permits have
 * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
 * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
 * generally recommended is:
 *
 * ```solidity
 * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
 *     try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
 *     doThing(..., value);
 * }
 *
 * function doThing(..., uint256 value) public {
 *     token.safeTransferFrom(msg.sender, address(this), value);
 *     ...
 * }
 * ```
 *
 * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
 * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
 * {SafeERC20-safeTransferFrom}).
 *
 * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
 * contracts should have entry points that don't rely on permit.
 */
interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     *
     * CAUTION: See Security Considerations above.
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}
          

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.26;

/// @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  
//   _bondStorage                   | struct LibBonds.Storage                            | Slot: 257  | Offset: 0    | Bytes: 32  
//   __gap                          | uint256[43]                                        | Slot: 258  | Offset: 0    | Bytes: 1376
          

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

contracts/layer1/core/iface/IBondManager.sol

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

/// @title IBondManager
/// @notice Interface for managing bonds on L1 in the Taiko protocol.
/// @custom:security-contact security@taiko.xyz
interface IBondManager {
    // ---------------------------------------------------------------
    // Structs
    // ---------------------------------------------------------------

    /// @notice Represents a bond for a given address.
    struct Bond {
        /// @notice The bond balance in gwei.
        uint64 balance;
        /// @notice The timestamp when the withdrawal was requested.
        /// @dev 0 = active, >0 = withdrawal requested timestamp
        uint48 withdrawalRequestedAt;
    }

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

    /// @notice Emitted when a bond is deposited.
    /// @param depositor The account that made the deposit.
    /// @param recipient The account that received the bond credit.
    /// @param amount The amount deposited in gwei.
    event BondDeposited(address indexed depositor, address indexed recipient, uint64 amount);

    /// @notice Emitted when a bond is withdrawn.
    /// @param account The account that withdrew the bond.
    /// @param amount The amount withdrawn in gwei.
    event BondWithdrawn(address indexed account, uint64 amount);

    /// @notice Emitted when a withdrawal is requested.
    /// @param account The account requesting withdrawal.
    /// @param withdrawableAt The timestamp when withdrawal becomes unrestricted.
    event WithdrawalRequested(address indexed account, uint48 withdrawableAt);

    /// @notice Emitted when a withdrawal request is cancelled.
    /// @param account The account cancelling the withdrawal request.
    event WithdrawalCancelled(address indexed account);

    /// @notice Emitted when a liveness bond is settled.
    /// @param payer The account that paid the liveness bond.
    /// @param payee The account that received the liveness bond.
    /// @param livenessBond The value of the liveness bond in gwei.
    /// @param credited The amount of the liveness bond that was credited to the payee in gwei.
    /// @param slashed The amount of the liveness bond that was slashed in gwei.
    event LivenessBondSettled(
        address indexed payer,
        address indexed payee,
        uint64 livenessBond,
        uint64 credited,
        uint64 slashed
    );

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

    /// @notice Deposits bond tokens for the caller.
    /// @dev Clears the caller's pending withdrawal request, if any.
    /// @param _amount The amount to deposit in gwei.
    function deposit(uint64 _amount) external;

    /// @notice Deposits bond tokens for a recipient.
    /// @dev Recipient must be non-zero. Does not cancel the recipient's pending withdrawal,
    /// even if the recipient is the caller.
    /// @param _recipient The address to credit the bond to.
    /// @param _amount The amount to deposit in gwei.
    function depositTo(address _recipient, uint64 _amount) external;

    /// @notice Withdraws bond to a recipient.
    /// @dev Withdrawals are subject to a delay so bond operations can be resolved properly.
    /// The user can always withdraw any excess amount without delays.
    /// If this withdrawal debits the entire bond balance, any pending withdrawal request is
    /// cleared.
    /// @param _to The recipient of withdrawn funds.
    /// @param _amount The amount to withdraw in gwei.
    function withdraw(address _to, uint64 _amount) external;

    /// @notice Requests to start the withdrawal process.
    /// @dev Account cannot perform bond-restricted actions after requesting withdrawal.
    function requestWithdrawal() external;

    /// @notice Cancels withdrawal request to reactivate the account.
    /// @dev Can be called during or after the withdrawal delay period.
    function cancelWithdrawal() external;

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

    /// @notice Gets the bond state of an address.
    /// @param _address The address to get the bond state for.
    /// @return bond_ The bond struct for the address.
    function getBond(address _address) external view returns (Bond memory bond_);
}
          

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(when more efficient than keccak256)
/// @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(when more efficient than keccak256).
/// @custom:security-contact security@taiko.xyz
library LibHashOptimized {
    // ---------------------------------------------------------------
    // Core Structure Hashing Functions
    // ---------------------------------------------------------------

    /// @notice Hashing for proposal data.
    /// @dev Uses keccak256(abi.encode(...)) to hash the proposal. Contrarty to the intuition,
    /// this is as efficient if not more than using `EfficientHashLib` in this case because
    /// the structure of the data(nested dynamic arryas).
    /// @param _proposal The proposal to hash
    /// @return The hash of the proposal
    function hashProposal(IInbox.Proposal memory _proposal) internal pure returns (bytes32) {
        /// forge-lint: disable-start(asm-keccak256)
        return keccak256(abi.encode(_proposal));
    }

    /// @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 (3 words each)
            uint256 totalWords = 9 + transitionsLength * 3;

            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(transition.timestamp)));
                EfficientHashLib.set(buffer, base + 2, transition.blockHash);
                base += 3;
            }

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

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

import { IBondManager } from "../iface/IBondManager.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

/// @title LibBonds
/// @notice Library for bond ledger operations and settlement.
/// @custom:security-contact security@taiko.xyz
library LibBonds {
    using SafeERC20 for IERC20;

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

    uint256 internal constant GWEI_UNIT = 1 gwei;

    // ---------------------------------------------------------------
    // Storage
    // ---------------------------------------------------------------

    /// @dev Storage layout for bond balances. Each bond packs into one slot.
    struct Storage {
        mapping(address account => IBondManager.Bond bond) bonds;
    }

    // ---------------------------------------------------------------
    // Internal Functions meant to be called by contracts that use this library
    // ---------------------------------------------------------------

    /// @dev Deposits bond tokens in gwei units and credits the recipient.
    /// If `_cancelWithdrawal` is true, the pending withdrawal request is cleared.
    function deposit(
        Storage storage $,
        IERC20 _bondToken,
        address _depositor,
        address _recipient,
        uint64 _amount,
        bool _cancelWithdrawal
    )
        internal
    {
        if (_recipient == address(0)) revert InvalidAddress();

        _creditBond($, _recipient, _amount);
        if (_cancelWithdrawal && $.bonds[_recipient].withdrawalRequestedAt != 0) {
            $.bonds[_recipient].withdrawalRequestedAt = 0;
        }
        _bondToken.safeTransferFrom(_depositor, address(this), _toTokenAmount(_amount));

        emit IBondManager.BondDeposited(_depositor, _recipient, _amount);
    }

    /// @dev Withdraws bond tokens in gwei units to a recipient.
    /// If the full balance is withdrawn, the pending withdrawal request is cleared.
    function withdraw(
        Storage storage $,
        IERC20 _bondToken,
        address _from,
        address _to,
        uint64 _amount,
        uint64 _minBond,
        uint48 _withdrawalDelay
    )
        internal
        returns (uint64 debited_)
    {
        if (_to == address(0)) revert InvalidAddress();

        IBondManager.Bond storage bond_ = $.bonds[_from];
        uint64 balance = bond_.balance;
        uint64 amount = _amount > balance ? balance : _amount;

        if (
            bond_.withdrawalRequestedAt == 0
                || block.timestamp < bond_.withdrawalRequestedAt + _withdrawalDelay
        ) {
            require(balance - amount >= _minBond, MustMaintainMinBond());
        }

        debited_ = _debitBond($, _from, amount);
        if (debited_ == balance && bond_.withdrawalRequestedAt != 0) {
            bond_.withdrawalRequestedAt = 0;
        }
        _bondToken.safeTransfer(_to, _toTokenAmount(debited_));
        emit IBondManager.BondWithdrawn(_from, debited_);
    }

    /// @dev Requests a withdrawal. Withdrawals are unrestricted after the delay.
    function requestWithdrawal(
        Storage storage $,
        address _account,
        uint48 _withdrawalDelay
    )
        internal
    {
        IBondManager.Bond memory bond_ = $.bonds[_account];
        if (bond_.balance == 0) revert NoBondToWithdraw();
        if (bond_.withdrawalRequestedAt != 0) revert WithdrawalAlreadyRequested();

        bond_.withdrawalRequestedAt = uint48(block.timestamp);
        $.bonds[_account] = bond_;
        emit IBondManager.WithdrawalRequested(_account, uint48(block.timestamp + _withdrawalDelay));
    }

    /// @dev Cancels a pending withdrawal request.
    function cancelWithdrawal(Storage storage $, address _account) internal {
        IBondManager.Bond storage bond_ = $.bonds[_account];
        if (bond_.withdrawalRequestedAt == 0) revert NoWithdrawalRequested();

        bond_.withdrawalRequestedAt = 0;
        emit IBondManager.WithdrawalCancelled(_account);
    }

    /// @dev Returns the bond state for an account.
    function getBond(
        Storage storage $,
        address _account
    )
        internal
        view
        returns (IBondManager.Bond memory)
    {
        return $.bonds[_account];
    }

    /// @dev Checks if an account has sufficient bond and is active.
    function hasSufficientBond(
        Storage storage $,
        address _account,
        uint64 _minBond
    )
        internal
        view
        returns (bool)
    {
        IBondManager.Bond storage bond_ = $.bonds[_account];
        return bond_.balance >= _minBond && bond_.withdrawalRequestedAt == 0;
    }

    /// @dev Applies a liveness bond slash with a 50/50 split (payee/burn).
    /// @param $ Storage reference.
    /// @param _payer Account whose bond is debited.
    /// @param _payee Account credited with half of the debited bond.
    /// @param _livenessBond Liveness bond amount in gwei.
    function settleLivenessBond(
        Storage storage $,
        address _payer,
        address _payee,
        uint64 _livenessBond
    )
        internal
    {
        // We try to debit the full liveness bond, but since it is best effort
        // the amount may be lower.
        uint64 debited = _debitBond($, _payer, _livenessBond);
        if (debited == 0) return;

        uint64 payeeAmount = debited / 2;
        uint64 slashedAmount = debited - payeeAmount;
        if (payeeAmount > 0) {
            _creditBond($, _payee, payeeAmount);
        }

        emit IBondManager.LivenessBondSettled(
            _payer, _payee, _livenessBond, payeeAmount, slashedAmount
        );
    }

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

    /// @dev Debits a bond with best effort.
    function _debitBond(
        Storage storage $,
        address _account,
        uint64 _amount
    )
        private
        returns (uint64 debited_)
    {
        IBondManager.Bond storage bond_ = $.bonds[_account];

        if (bond_.balance <= _amount) {
            debited_ = bond_.balance;
            bond_.balance = 0;
        } else {
            debited_ = _amount;
            bond_.balance = bond_.balance - _amount;
        }
    }

    /// @dev Credits a bond balance.
    function _creditBond(Storage storage $, address _account, uint64 _amount) private {
        IBondManager.Bond storage bond_ = $.bonds[_account];
        bond_.balance = bond_.balance + _amount;
    }

    /// @dev Converts bond amounts in gwei to token units (18 decimals).
    function _toTokenAmount(uint64 _amount) private pure returns (uint256) {
        return uint256(_amount) * GWEI_UNIT;
    }

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

    error InvalidAddress();
    error MustMaintainMinBond();
    error NoBondToWithdraw();
    error NoWithdrawalRequested();
    error WithdrawalAlreadyRequested();
}
          

contracts/layer1/core/libs/LibTransitionCodec.sol

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

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

/// @title LibTransitionCodec
/// @notice Shared transition encode/decode helpers to avoid duplication across codecs.
/// @custom:security-contact security@taiko.xyz
library LibTransitionCodec {
    uint256 internal constant TRANSITION_SIZE = 58;

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

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

contracts/layer1/core/iface/IInbox.sol

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

import { LibBlobs } from "../libs/LibBlobs.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 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 ERC20 bond token address
        address bondToken;
        /// @notice The minimum bond a proposer is required to have in gwei
        uint64 minBond;
        /// @notice The liveness bond amount in gwei
        uint64 livenessBond;
        /// @notice The withdrawal delay in seconds
        uint48 withdrawalDelay;
        /// @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 Proposal
    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 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 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 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 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 Proved event
    struct ProvedEventPayload {
        /// @notice The ID of the first proposal being proven.
        uint48 firstProposalId;
        /// @notice The ID of the first proposal that had not been proven before.
        uint48 firstNewProposalId;
        /// @notice The ID of the last proposal being proven.
        uint48 lastProposalId;
        /// @notice The actual prover who generated the proof.
        address actualProver;
        /// @notice Whether the checkpoint was synced.
        bool checkpointSynced;
    }

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

    /// @notice Emitted when a new proposal is proposed.
    /// @param id Unique identifier for the proposal.
    /// @param proposer Address of the proposer.
    /// @param parentProposalHash The hash of the parent proposal (zero for genesis).
    /// @param endOfSubmissionWindowTimestamp Last slot timestamp where the preconfer can propose.
    /// @param basefeeSharingPctg The percentage of base fee paid to coinbase.
    /// @param sources Array of derivation sources for this proposal.
    event Proposed(
        uint48 indexed id,
        address indexed proposer,
        bytes32 parentProposalHash,
        uint48 endOfSubmissionWindowTimestamp,
        uint8 basefeeSharingPctg,
        DerivationSource[] sources
    );

    /// @notice Emitted when a proof is submitted
    /// @param firstProposalId The first proposal ID covered by the proof (may include finalized ids)
    /// @param firstNewProposalId The first proposal ID that was newly proven by this proof
    /// @param lastProposalId The last proposal ID covered by the proof
    /// @param actualProver The prover that submitted the proof
    /// @param checkpointSynced Whether a checkpoint was synced as part of this proof
    event Proved(
        uint48 firstProposalId,
        uint48 firstNewProposalId,
        uint48 lastProposalId,
        address indexed actualProver,
        bool checkpointSynced
    );

    event DebugHash(uint8 index, bytes32 hash);
    event DebugNumber(uint8 index, uint48 number);
    event DebugAddress(uint8 index, address addr);

    // ---------------------------------------------------------------
    // 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.26;

import { IBondManager } from "../iface/IBondManager.sol";
import { ICodec } from "../iface/ICodec.sol";
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 { LibBonds } from "../libs/LibBonds.sol";
import { LibCodec } from "../libs/LibCodec.sol";
import { LibForcedInclusion } from "../libs/LibForcedInclusion.sol";
import { LibHashOptimized } from "../libs/LibHashOptimized.sol";
import { LibInboxSetup } from "../libs/LibInboxSetup.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.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 { 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 accounting and liveness bond processing
///      - Finalization of proven proposals with checkpoint rate limiting
/// @custom:security-contact security@taiko.xyz
contract Inbox is IInbox, ICodec, IForcedInclusionStore, IBondManager, EssentialContract {
    using LibAddress for address;
    using LibBonds for LibBonds.Storage;
    using LibForcedInclusion for LibForcedInclusion.Storage;
    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 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.
    ISignalService internal immutable _signalService;

    /// @notice ERC20 token used as bond.
    IERC20 internal immutable _bondToken;

    /// @notice Minimum bond the proposer is required to have in gwei.
    uint64 internal immutable _minBond;

    /// @notice Liveness bond amount in gwei.
    uint64 internal immutable _livenessBond;

    /// @notice Time delay required before withdrawal after request.
    uint48 internal immutable _withdrawalDelay;

    /// @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;

    /// @dev Storage for bond balances.
    LibBonds.Storage private _bondStorage;

    uint256[43] private __gap;

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

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

        _proofVerifier = IProofVerifier(_config.proofVerifier);
        _proposerChecker = IProposerChecker(_config.proposerChecker);
        _proverWhitelist = IProverWhitelist(_config.proverWhitelist);
        _signalService = ISignalService(_config.signalService);
        _bondToken = IERC20(_config.bondToken);
        _minBond = _config.minBond;
        _livenessBond = _config.livenessBond;
        _withdrawalDelay = _config.withdrawalDelay;
        _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,
            Proposal memory proposal,
            bytes32 genesisProposalHash
        ) = LibInboxSetup.activate(_lastPacayaBlockHash, activationTimestamp);

        activationTimestamp = newActivationTimestamp;
        _coreState = state;
        _setProposalHash(0, genesisProposalHash);
        _emitProposedEvent(proposal);
        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 = LibCodec.decodeProposeInput(_data);
            _validateProposeInput(input);

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

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

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

            _emitProposedEvent(proposal);
        }
    }

    /// @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 = LibCodec.decodeProveInput(_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) {
                _processLivenessBond(commitment, offset);
            }

            // -----------------------------------------------------------------------------
            // 4. Sync checkpoint
            // -----------------------------------------------------------------------------
            bool checkpointSynced = input.forceCheckpointSync
                || block.timestamp >= state.lastCheckpointTimestamp + _minCheckpointDelay;

            if (checkpointSynced) {
                _signalService.saveCheckpoint(
                    ICheckpointStore.Checkpoint({
                        blockNumber: commitment.endBlockNumber,
                        stateRoot: commitment.endStateRoot,
                        blockHash: commitment.transitions[numProposals - 1].blockHash
                    })
                );
                state.lastCheckpointTimestamp = uint48(block.timestamp);
            }

            // ---------------------------------------------------------
            // 5. Compute proposalAge (for single-proposal proofs only)
            // ---------------------------------------------------------
            uint256 proposalAge;
            if (numProposals == 1) {
                // We count proposalAge as the time since it became available for proving.
                proposalAge = block.timestamp
                    - commitment.transitions[offset].timestamp.max(state.lastFinalizedTimestamp);
            }

            // ---------------------------------------------------------
            // 6. 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(
                commitment.firstProposalId,
                commitment.firstProposalId + offset,
                uint48(lastProposalId),
                commitment.actualProver,
                checkpointSynced
            );

            // ---------------------------------------------------------
            // 7. Verify the proof
            // ---------------------------------------------------------
            bytes32 commitmentHash = LibHashOptimized.hashCommitment(commitment);
            emit DebugHash(1, commitmentHash);
            emit DebugNumber(2, commitment.firstProposalId);
            emit DebugHash(3, commitment.firstProposalParentBlockHash);
            emit DebugHash(4, commitment.lastProposalHash);
            emit DebugAddress(5, commitment.actualProver);
            emit DebugNumber(6, commitment.endBlockNumber);
            emit DebugHash(7, commitment.endStateRoot);
            emit DebugHash(8, commitment.transitions[0].blockHash);
            emit DebugAddress(9, commitment.transitions[0].proposer);
            emit DebugNumber(11, commitment.transitions[0].timestamp);
            _proofVerifier.verifyProof(
                proposalAge, commitmentHash, _proof
            );
        }
    }

    /// @inheritdoc IBondManager
    function deposit(uint64 _amount) external nonReentrant {
        _bondStorage.deposit(_bondToken, msg.sender, msg.sender, _amount, true);
    }

    /// @inheritdoc IBondManager
    function depositTo(address _recipient, uint64 _amount) external nonReentrant {
        _bondStorage.deposit(_bondToken, msg.sender, _recipient, _amount, false);
    }

    /// @inheritdoc IBondManager
    function withdraw(address _to, uint64 _amount) external nonReentrant {
        _bondStorage.withdraw(_bondToken, msg.sender, _to, _amount, _minBond, _withdrawalDelay);
    }

    /// @inheritdoc IBondManager
    function requestWithdrawal() external nonReentrant {
        _bondStorage.requestWithdrawal(msg.sender, _withdrawalDelay);
    }

    /// @inheritdoc IBondManager
    function cancelWithdrawal() external nonReentrant {
        _bondStorage.cancelWithdrawal(msg.sender);
    }

    /// @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 = _forcedInclusionStorage.saveForcedInclusion(
            _forcedInclusionFeeInGwei, _forcedInclusionFeeDoubleThreshold, _blobReference
        );

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

    /// @inheritdoc ICodec
    function encodeProposeInput(IInbox.ProposeInput calldata _input)
        external
        pure
        returns (bytes memory encoded_)
    {
        return LibCodec.encodeProposeInput(_input);
    }

    /// @inheritdoc ICodec
    function decodeProposeInput(bytes calldata _data)
        external
        pure
        returns (IInbox.ProposeInput memory input_)
    {
        return LibCodec.decodeProposeInput(_data);
    }

    /// @inheritdoc ICodec
    function encodeProveInput(IInbox.ProveInput calldata _input)
        external
        pure
        returns (bytes memory encoded_)
    {
        return LibCodec.encodeProveInput(_input);
    }

    /// @inheritdoc ICodec
    function decodeProveInput(bytes calldata _data)
        external
        pure
        returns (IInbox.ProveInput memory input_)
    {
        return LibCodec.decodeProveInput(_data);
    }

    /// @inheritdoc ICodec
    function hashProposal(IInbox.Proposal calldata _proposal) external pure returns (bytes32) {
        return LibHashOptimized.hashProposal(_proposal);
    }

    /// @inheritdoc ICodec
    function hashCommitment(IInbox.Commitment calldata _commitment)
        external
        pure
        returns (bytes32)
    {
        return LibHashOptimized.hashCommitment(_commitment);
    }

    // ---------------------------------------------------------------
    // External and Public View Functions
    // ---------------------------------------------------------------
    /// @inheritdoc IBondManager
    function getBond(address _address) external view returns (Bond memory bond_) {
        return _bondStorage.getBond(_address);
    }

    /// @inheritdoc IForcedInclusionStore
    function getCurrentForcedInclusionFee() external view returns (uint64 feeInGwei_) {
        return _forcedInclusionStorage.getCurrentForcedInclusionFee(
            _forcedInclusionFeeInGwei, _forcedInclusionFeeDoubleThreshold
        );
    }

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

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

    /// @inheritdoc IInbox
    function getConfig() external view returns (Config memory config_) {
        config_ = Config({
            proofVerifier: address(_proofVerifier),
            proposerChecker: address(_proposerChecker),
            proverWhitelist: address(_proverWhitelist),
            signalService: address(_signalService),
            bondToken: address(_bondToken),
            minBond: _minBond,
            livenessBond: _livenessBond,
            withdrawalDelay: _withdrawalDelay,
            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.
    /// This function also checks:
    /// - If `msg.sender` can propose.
    /// - If `msg.sender` has sufficient bond.
    /// @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 set.
    function _buildProposal(
        ProposeInput memory _input,
        bytes calldata _lookahead,
        uint48 _nextProposalId,
        uint48 _lastProposalBlockId,
        uint48 _lastFinalizedProposalId
    )
        private
        returns (Proposal memory proposal_)
    {
        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
            // set endOfSubmissionWindowTimestamp = 0, and do not require a bond
            // Otherwise, only the current preconfer can propose
            uint48 endOfSubmissionWindowTimestamp;
            if (!result.allowsPermissionless) {
                endOfSubmissionWindowTimestamp =
                    _proposerChecker.checkProposer(msg.sender, _lookahead);
                require(_bondStorage.hasSufficientBond(msg.sender, _minBond), InsufficientBond());
            }

            // Use previous block as the origin for the proposal to be able to call `blockhash`
            uint256 parentBlockNumber = block.number - 1;
            proposal_ = Proposal({
                id: _nextProposalId,
                timestamp: uint48(block.timestamp),
                endOfSubmissionWindowTimestamp: endOfSubmissionWindowTimestamp,
                proposer: msg.sender,
                parentProposalHash: getProposalHash(_nextProposalId - 1),
                originBlockNumber: uint48(parentBlockNumber),
                originBlockHash: blockhash(parentBlockNumber),
                basefeeSharingPctg: _basefeeSharingPctg,
                sources: result.sources
            });
        }
    }

    /// @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 =
                    $.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
            _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 processes liveness bond settlement if applicable.
    /// @dev Settlement rules:
    ///      - On-time (within provingWindow + sequential grace): No bond changes.
    ///      - Late: Liveness bond slash with 50% credited to the actual prover and 50% burned.
    /// @param _commitment The commitment data.
    /// @param _offset The offset to the first unfinalized proposal.
    function _processLivenessBond(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;
            }

            _bondStorage.settleLivenessBond(
                _commitment.transitions[_offset].proposer, _commitment.actualProver, _livenessBond
            );
        }
    }

    /// @dev Emits the Proposed event
    function _emitProposedEvent(Proposal memory _proposal) private {
        emit Proposed(
            _proposal.id,
            _proposal.proposer,
            _proposal.parentProposalHash,
            _proposal.endOfSubmissionWindowTimestamp,
            _proposal.basefeeSharingPctg,
            _proposal.sources
        );
    }

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

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/LibCodec.sol

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

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

/// @title LibCodec
/// @notice Compact encoder/decoder for Inbox inputs using LibPackUnpack.
/// @custom:security-contact security@taiko.xyz
library LibCodec {
    // ---------------------------------------------------------------
    // ProposeInputCodec Functions
    // ---------------------------------------------------------------

    /// @dev Encodes propose input data using compact packing.
    function encodeProposeInput(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);
    }

    /// @dev Decodes propose input data using compact packing.
    function decodeProposeInput(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,) = P.unpackUint8(ptr);
    }

    // ---------------------------------------------------------------
    // ProveInputCodec Functions
    // ---------------------------------------------------------------

    /// @dev Encodes prove input data using compact packing.
    function encodeProveInput(IInbox.ProveInput memory _input)
        internal
        pure
        returns (bytes memory encoded_)
    {
        IInbox.Commitment memory c = _input.commitment;
        uint256 bufferSize = _calculateProveInputSize(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) {
            ptr = LibTransitionCodec.encodeTransition(ptr, c.transitions[i]);
        }

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

    /// @dev Decodes prove input data using compact packing.
    function decodeProveInput(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) = LibTransitionCodec.decodeTransition(ptr);
        }

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

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

    /// @dev Calculates the size needed for ProveInput encoding.
    /// @param _numTransitions Number of transitions in the array.
    /// @return size_ Total byte size needed.
    function _calculateProveInputSize(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
            size_ = 131 + (_numTransitions * LibTransitionCodec.TRANSITION_SIZE);
        }
    }
}
          

contracts/layer1/core/iface/ICodec.sol

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

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

/// @title ICodec
/// @notice Interface for Inbox encoder/decoder and hashing functions
/// @dev Input validation assumptions:
/// - All decode functions may revert on malformed input data
/// - Array inputs should be bounded to prevent excessive gas usage
/// - Struct fields are not validated for business logic constraints
/// - Hash functions assume well-formed input structures
/// @dev Compatibility warning:
/// - Different codec implementations produce INCOMPATIBLE encoded outputs and hashes for the same
/// inputs
/// - Codec implementations cannot be used interchangeably
/// - System upgrades between codec types require careful migration planning
/// @custom:security-contact security@taiko.xyz
interface ICodec {
    // ---------------------------------------------------------------
    // ProposeInputCodec Functions
    // ---------------------------------------------------------------

    /// @notice Encodes propose input data
    /// @param _input The ProposeInput to encode
    /// @return encoded_ The encoded data
    function encodeProposeInput(IInbox.ProposeInput calldata _input)
        external
        pure
        returns (bytes memory encoded_);

    /// @notice Decodes propose data
    /// @param _data The encoded data
    /// @return input_ The decoded ProposeInput
    /// @dev Reverts on malformed or truncated input data
    function decodeProposeInput(bytes calldata _data)
        external
        pure
        returns (IInbox.ProposeInput memory input_);

    // ---------------------------------------------------------------
    // ProveInputCodec Functions
    // ---------------------------------------------------------------

    /// @notice Encodes prove input data
    /// @param _input The ProveInput to encode
    /// @return encoded_ The encoded data
    function encodeProveInput(IInbox.ProveInput calldata _input)
        external
        pure
        returns (bytes memory encoded_);

    /// @notice Decodes prove input data
    /// @param _data The encoded data
    /// @return input_ The decoded ProveInput
    /// @dev Reverts on malformed or truncated input data
    function decodeProveInput(bytes calldata _data)
        external
        pure
        returns (IInbox.ProveInput memory input_);

    // ---------------------------------------------------------------
    // Hashing Functions
    // ---------------------------------------------------------------

    /// @notice Hashing for Proposal structs
    /// @param _proposal The proposal to hash
    /// @return The hash of the proposal
    function hashProposal(IInbox.Proposal calldata _proposal) external pure returns (bytes32);

    /// @notice Hashing for commitment data
    /// @param _commitment The commitment data to hash
    /// @return The hash of the commitment
    function hashCommitment(IInbox.Commitment calldata _commitment) external pure returns (bytes32);
}
          

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

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

node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";
import "../extensions/IERC20Permit.sol";
import "../../../utils/Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

    /**
     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    /**
     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
     */
    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(IERC20 token, address spender, uint256 value) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    /**
     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 oldAllowance = token.allowance(address(this), spender);
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
    }

    /**
     * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
        }
    }

    /**
     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
     * to be set to zero before setting it to a non-zero value, such as USDT.
     */
    function forceApprove(IERC20 token, address spender, uint256 value) internal {
        bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);

        if (!_callOptionalReturnBool(token, approvalCall)) {
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
            _callOptionalReturn(token, approvalCall);
        }
    }

    /**
     * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.
     * Revert on invalid signature.
     */
    function safePermit(
        IERC20Permit token,
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal {
        uint256 nonceBefore = token.nonces(owner);
        token.permit(owner, spender, value, deadline, v, r, s);
        uint256 nonceAfter = token.nonces(owner);
        require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     *
     * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
     */
    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
        // and not revert is the subcall reverts.

        (bool success, bytes memory returndata) = address(token).call(data);
        return
            success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
    }
}
          

contracts/layer1/core/libs/LibPackUnpack.sol

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

/// @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/shared/libs/LibAddress.sol

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

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.26;

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

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

    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.26;

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.26;

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 Minimum ring buffer size to keep one slot reserved in capacity calculations.
    uint256 public constant MIN_RING_BUFFER_SIZE = 2;

    /// @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.proofVerifier != address(0), ProofVerifierZero());
        require(_config.proposerChecker != address(0), ProposerCheckerZero());
        require(_config.signalService != address(0), SignalServiceZero());
        require(_config.bondToken != address(0), BondTokenZero());
        require(_config.provingWindow != 0, ProvingWindowZero());
        require(_config.ringBufferSize >= MIN_RING_BUFFER_SIZE, 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 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.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;

        genesisProposalHash_ = LibHashOptimized.hashProposal(proposal_);
    }

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

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

Compiler Settings

{"viaIR":true,"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":{"contracts/layer1/core/libs/LibInboxSetup.sol":{"LibInboxSetup":"0xb2c8E57eb1eb0b686B63f58E53f859bEA615677B"},"contracts/layer1/core/libs/LibForcedInclusion.sol":{"LibForcedInclusion":"0x8bBdF7B3D44c1CF6aA64Db449E93aD5C0d10E63c"}},"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":"_bondToken","internalType":"address"},{"type":"uint64","name":"_minBond","internalType":"uint64"},{"type":"uint64","name":"_livenessBond","internalType":"uint64"},{"type":"uint48","name":"_withdrawalDelay","internalType":"uint48"}]},{"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":"InsufficientBond","inputs":[]},{"type":"error","name":"InvalidAddress","inputs":[]},{"type":"error","name":"LastProposalAlreadyFinalized","inputs":[]},{"type":"error","name":"LastProposalHashMismatch","inputs":[]},{"type":"error","name":"LastProposalIdTooLarge","inputs":[]},{"type":"error","name":"LengthExceedsUint16","inputs":[]},{"type":"error","name":"MustMaintainMinBond","inputs":[]},{"type":"error","name":"NoBlobs","inputs":[]},{"type":"error","name":"NoBondToWithdraw","inputs":[]},{"type":"error","name":"NoWithdrawalRequested","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":"WithdrawalAlreadyRequested","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":"BondDeposited","inputs":[{"type":"address","name":"depositor","internalType":"address","indexed":true},{"type":"address","name":"recipient","internalType":"address","indexed":true},{"type":"uint64","name":"amount","internalType":"uint64","indexed":false}],"anonymous":false},{"type":"event","name":"BondWithdrawn","inputs":[{"type":"address","name":"account","internalType":"address","indexed":true},{"type":"uint64","name":"amount","internalType":"uint64","indexed":false}],"anonymous":false},{"type":"event","name":"DebugAddress","inputs":[{"type":"uint8","name":"index","internalType":"uint8","indexed":false},{"type":"address","name":"addr","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"DebugHash","inputs":[{"type":"uint8","name":"index","internalType":"uint8","indexed":false},{"type":"bytes32","name":"hash","internalType":"bytes32","indexed":false}],"anonymous":false},{"type":"event","name":"DebugNumber","inputs":[{"type":"uint8","name":"index","internalType":"uint8","indexed":false},{"type":"uint48","name":"number","internalType":"uint48","indexed":false}],"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":"LivenessBondSettled","inputs":[{"type":"address","name":"payer","internalType":"address","indexed":true},{"type":"address","name":"payee","internalType":"address","indexed":true},{"type":"uint64","name":"livenessBond","internalType":"uint64","indexed":false},{"type":"uint64","name":"credited","internalType":"uint64","indexed":false},{"type":"uint64","name":"slashed","internalType":"uint64","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":"uint48","name":"id","internalType":"uint48","indexed":true},{"type":"address","name":"proposer","internalType":"address","indexed":true},{"type":"bytes32","name":"parentProposalHash","internalType":"bytes32","indexed":false},{"type":"uint48","name":"endOfSubmissionWindowTimestamp","internalType":"uint48","indexed":false},{"type":"uint8","name":"basefeeSharingPctg","internalType":"uint8","indexed":false},{"type":"tuple[]","name":"sources","internalType":"struct IInbox.DerivationSource[]","indexed":false,"components":[{"type":"bool","name":"isForcedInclusion","internalType":"bool"},{"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":"Proved","inputs":[{"type":"uint48","name":"firstProposalId","internalType":"uint48","indexed":false},{"type":"uint48","name":"firstNewProposalId","internalType":"uint48","indexed":false},{"type":"uint48","name":"lastProposalId","internalType":"uint48","indexed":false},{"type":"address","name":"actualProver","internalType":"address","indexed":true},{"type":"bool","name":"checkpointSynced","internalType":"bool","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":"event","name":"WithdrawalCancelled","inputs":[{"type":"address","name":"account","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"WithdrawalRequested","inputs":[{"type":"address","name":"account","internalType":"address","indexed":true},{"type":"uint48","name":"withdrawableAt","internalType":"uint48","indexed":false}],"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":"nonpayable","outputs":[],"name":"cancelWithdrawal","inputs":[]},{"type":"function","stateMutability":"pure","outputs":[{"type":"tuple","name":"input_","internalType":"struct IInbox.ProposeInput","components":[{"type":"uint48","name":"deadline","internalType":"uint48"},{"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":"uint8","name":"numForcedInclusions","internalType":"uint8"}]}],"name":"decodeProposeInput","inputs":[{"type":"bytes","name":"_data","internalType":"bytes"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"tuple","name":"input_","internalType":"struct IInbox.ProveInput","components":[{"type":"tuple","name":"commitment","internalType":"struct IInbox.Commitment","components":[{"type":"uint48","name":"firstProposalId","internalType":"uint48"},{"type":"bytes32","name":"firstProposalParentBlockHash","internalType":"bytes32"},{"type":"bytes32","name":"lastProposalHash","internalType":"bytes32"},{"type":"address","name":"actualProver","internalType":"address"},{"type":"uint48","name":"endBlockNumber","internalType":"uint48"},{"type":"bytes32","name":"endStateRoot","internalType":"bytes32"},{"type":"tuple[]","name":"transitions","internalType":"struct IInbox.Transition[]","components":[{"type":"address","name":"proposer","internalType":"address"},{"type":"uint48","name":"timestamp","internalType":"uint48"},{"type":"bytes32","name":"blockHash","internalType":"bytes32"}]}]},{"type":"bool","name":"forceCheckpointSync","internalType":"bool"}]}],"name":"decodeProveInput","inputs":[{"type":"bytes","name":"_data","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"deposit","inputs":[{"type":"uint64","name":"_amount","internalType":"uint64"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"depositTo","inputs":[{"type":"address","name":"_recipient","internalType":"address"},{"type":"uint64","name":"_amount","internalType":"uint64"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bytes","name":"encoded_","internalType":"bytes"}],"name":"encodeProposeInput","inputs":[{"type":"tuple","name":"_input","internalType":"struct IInbox.ProposeInput","components":[{"type":"uint48","name":"deadline","internalType":"uint48"},{"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":"uint8","name":"numForcedInclusions","internalType":"uint8"}]}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bytes","name":"encoded_","internalType":"bytes"}],"name":"encodeProveInput","inputs":[{"type":"tuple","name":"_input","internalType":"struct IInbox.ProveInput","components":[{"type":"tuple","name":"commitment","internalType":"struct IInbox.Commitment","components":[{"type":"uint48","name":"firstProposalId","internalType":"uint48"},{"type":"bytes32","name":"firstProposalParentBlockHash","internalType":"bytes32"},{"type":"bytes32","name":"lastProposalHash","internalType":"bytes32"},{"type":"address","name":"actualProver","internalType":"address"},{"type":"uint48","name":"endBlockNumber","internalType":"uint48"},{"type":"bytes32","name":"endStateRoot","internalType":"bytes32"},{"type":"tuple[]","name":"transitions","internalType":"struct IInbox.Transition[]","components":[{"type":"address","name":"proposer","internalType":"address"},{"type":"uint48","name":"timestamp","internalType":"uint48"},{"type":"bytes32","name":"blockHash","internalType":"bytes32"}]}]},{"type":"bool","name":"forceCheckpointSync","internalType":"bool"}]}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"bond_","internalType":"struct IBondManager.Bond","components":[{"type":"uint64","name":"balance","internalType":"uint64"},{"type":"uint48","name":"withdrawalRequestedAt","internalType":"uint48"}]}],"name":"getBond","inputs":[{"type":"address","name":"_address","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"config_","internalType":"struct IInbox.Config","components":[{"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":"bondToken","internalType":"address"},{"type":"uint64","name":"minBond","internalType":"uint64"},{"type":"uint64","name":"livenessBond","internalType":"uint64"},{"type":"uint48","name":"withdrawalDelay","internalType":"uint48"},{"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":"pure","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"hashCommitment","inputs":[{"type":"tuple","name":"_commitment","internalType":"struct IInbox.Commitment","components":[{"type":"uint48","name":"firstProposalId","internalType":"uint48"},{"type":"bytes32","name":"firstProposalParentBlockHash","internalType":"bytes32"},{"type":"bytes32","name":"lastProposalHash","internalType":"bytes32"},{"type":"address","name":"actualProver","internalType":"address"},{"type":"uint48","name":"endBlockNumber","internalType":"uint48"},{"type":"bytes32","name":"endStateRoot","internalType":"bytes32"},{"type":"tuple[]","name":"transitions","internalType":"struct IInbox.Transition[]","components":[{"type":"address","name":"proposer","internalType":"address"},{"type":"uint48","name":"timestamp","internalType":"uint48"},{"type":"bytes32","name":"blockHash","internalType":"bytes32"}]}]}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"hashProposal","inputs":[{"type":"tuple","name":"_proposal","internalType":"struct IInbox.Proposal","components":[{"type":"uint48","name":"id","internalType":"uint48"},{"type":"uint48","name":"timestamp","internalType":"uint48"},{"type":"uint48","name":"endOfSubmissionWindowTimestamp","internalType":"uint48"},{"type":"address","name":"proposer","internalType":"address"},{"type":"bytes32","name":"parentProposalHash","internalType":"bytes32"},{"type":"uint48","name":"originBlockNumber","internalType":"uint48"},{"type":"bytes32","name":"originBlockHash","internalType":"bytes32"},{"type":"uint8","name":"basefeeSharingPctg","internalType":"uint8"},{"type":"tuple[]","name":"sources","internalType":"struct IInbox.DerivationSource[]","components":[{"type":"bool","name":"isForcedInclusion","internalType":"bool"},{"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"}]}]}]}]},{"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":"nonpayable","outputs":[],"name":"requestWithdrawal","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"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdraw","inputs":[{"type":"address","name":"_to","internalType":"address"},{"type":"uint64","name":"_amount","internalType":"uint64"}]}]
              

Contract Creation Code

Verify & Publish
0x610300806040523461057657610100816157978038038091610021828561061d565b8339810103126105765761003481610640565b9061004160208201610640565b9061004e60408201610640565b61005a60608301610640565b61006660808401610640565b9061007360a08501610654565b9260e061008260c08701610654565b9501519565ffffffffffff8716809703610576576040519761024089016001600160401b0381118a8210176106095760409081526001600160a01b039182168a5291811660208a0152918216908801529081166060870152166080808601919091526001600160401b0391821660a0860152911660c084015260e0830191909152611c2061010083015260b46101208301526064610140830152604b6101608301526001610180808401919091525f6101a08401819052629896806101c085015260326101e085015261020084019190915260056102208401523090915254600881901c60ff166105b45760ff8082160361057a575b5073b2c8e57eb1eb0b686b63f58e53f859bea615677b3b1561057657604080516348ed17ff60e11b815282516001600160a01b03908116600483015260208401518116602483015291830151821660448201526060830151821660648201526080830151909116608482015260a08201516001600160401b0390811660a483015260c0830151811660c483015260e083015165ffffffffffff90811660e484015261010084015181166101048401526101208401511661012483015261014083015161014483015261016083015160ff9081166101648401526101808401516101848401526101a084015161ffff9081166101a48501526101c085015183166101c48501526101e08501519092166101e484015261020084015190911661020483015261022083015116610224820152905f826102448173b2c8e57eb1eb0b686b63f58e53f859bea615677b5af490811561056b5760ff926102209261055b575b5080516001600160a01b0390811660c09081526020830151821660e0908152604080850151841661010090815260608601518516610120908152608087015190951661014090815260a08701516001600160401b039081166101609081529588015181166101809081529488015165ffffffffffff9081166101a09081529389015181166101c090815297890151166101e090815291880151610200908152958801518a16895293870151610240529086015161ffff90811661026052948601518316610280528501519091166102a052908301519091166102c0529101519091166102e0525161512e908161066982396080518181816107ce01528181610b6a0152610bbd015260a051816102c1015260c0518181816116de0152612445015260e05181818161170a0152613e66015261010051818181611739015261407d015261012051818181611768015261251801526101405181818161042a015281816117970152611b0f0152610160518181816117ce01528181611bcb0152613ea80152610180518181816117fd015261444d01526101a05181818161182b01528181611c060152611d3a01526101c05181818161185901526143eb01526101e05181818161188801526143c70152610200518181816118b001528181612ff3015281816139c601528181613a180152613cf80152610220518181816118d90152613e0e015261024051818181611901015261491a01526102605181818161192b0152818161497401526149ac01526102805181818161195b01528181611ef20152611fb001526102a05181818161198b01528181611ed10152611fd801526102c0518181816119b6015261262001526102e0518181816119e0015261494f0152f35b5f6105659161061d565b5f6102d9565b6040513d5f823e3d90fd5b5f80fd5b60ff90811916175f557f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498602060405160ff8152a15f610178565b60405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b6064820152608490fd5b634e487b7160e01b5f52604160045260245ffd5b601f909101601f19168101906001600160401b0382119082101761060957604052565b51906001600160a01b038216820361057657565b51906001600160401b03821682036105765756fe60806040526004361015610011575f80fd5b5f3560e01c80630423c7de1461027457806304f3bcec1461026f5780630d8912f31461026a578063137658381461026557806319ab453c14610260578063226112801461025b5780632f1969b0146102565780633075db56146102515780633659cfe61461024c5780633f4ba83a1461024757806340df9866146102425780634f1ef2861461023d57806352d1902d1461023857806359db6e85146102335780635c975abb1461022e5780635ccc1718146102295780636aa6a01a14610224578063715018a61461021f57806379ba50971461021a5780638301d56d146102155780638456cb59146102105780638abf60771461020b5780638da5cb5b146102065780639791e64414610201578063a834725a146101fc578063afb63ad4146101f7578063b28e824e146101f2578063c3f909d4146101ed578063d6dad060146101e8578063dbaf2145146101e3578063df596d9e146101de578063e3053335146101d9578063e30c3978146101d4578063ea191743146101cf578063edbacd44146101ca578063efba83c9146101c5578063f2fde38b146101c05763f954ab92146101bb575f80fd5b612896565b612826565b612789565b6126e1565b61209d565b612075565b611f82565b611e6f565b611c44565b611a37565b6116b8565b611482565b61140c565b6113bc565b61127e565b6111d9565b6111a5565b611139565b610f78565b610ef4565b610e8f565b610de6565b610db6565b610d88565b610c6e565b610bab565b610b18565b610942565b61085c565b6107ac565b61077d565b6106a0565b6105c7565b6104cf565b6103b0565b61030e565b6102ac565b610287565b5f91031261028357565b5f80fd5b34610283575f36600319011261028357602065ffffffffffff60fb5416604051908152f35b34610283575f366003190112610283576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b6001600160a01b0381160361028357565b359061030c826102f0565b565b3461028357602036600319011261028357604061035c600435610330816102f0565b6103386128de565b506103416128de565b506001600160a01b03165f9081526101016020526040902090565b65ffffffffffff82519161036f83610a08565b546001600160401b0381168352816020840191851c1681526001600160401b038451935116835251166020820152f35b6001600160401b0381160361028357565b34610283576020366003190112610283576004356103cd8161039f565b6103d5613408565b60025f5160206150b95f395f51905f525d33156104c0576103f98133610101614634565b335f9081526101016020526040902065ffffffffffff905460401c1661049c575b61044e61042682614688565b30337f00000000000000000000000000000000000000000000000000000000000000006146ad565b6040516001600160401b03919091168152339081907fe5e95641fa87bdfef3ce0d39f0c9a37c200f3bf59f53623b3de21e03ed33e3d290602090a360015f5160206150b95f395f51905f525d005b335f90815261010160205260409020805465ffffffffffff60401b1916905561041a565b63e6c4247b60e01b5f5260045ffd5b34610283576020366003190112610283576004356104ec816102f0565b61053a5f549161052061050a6105068560ff9060081c1690565b1590565b809481956105b9575b8115610599575b506128f6565b82610531600160ff195f5416175f55565b61058257613492565b61054057005b61054e5f5461ff0019165f55565b604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989080602081015b0390a1005b6105946101005f5461ff001916175f55565b613492565b303b159150816105ab575b505f61051a565b60ff1660011490505f6105a4565b600160ff8216109150610513565b34610283575f366003190112610283576105df613408565b60025f5160206150b95f395f51905f525d335f9081526101016020526040902065ffffffffffff815460401c161561065957805465ffffffffffff60401b19169055337fc51fdb96728de385ec7859819e3997bc618362ef0dbca0ad051d856866cda3db5f80a260015f5160206150b95f395f51905f525d005b6387bdc6a960e01b5f5260045ffd5b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b90602061069d928181520190610668565b90565b346102835760a0366003190112610283576107796040516106c081610a23565b6004356106cc816108c7565b815261076c6106da36611dd3565b6020830190815261076661075e61074f6040608435946106f986612959565b818801958652610707612a31565b9765ffffffffffff60d01b905160d01b16602089015261ffff60f01b81515160f01b16602689015261ffff60f01b60208251015160f01b16602889015251015162ffffff1690565b60e81b602a860152602d850190565b915160ff1690565b906146f6565b506040519182918261068c565b0390f35b34610283575f366003190112610283576020600260ff5f5160206150b95f395f51905f525c1614604051908152f35b34610283576020366003190112610283576004356107c9816102f0565b6108207f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166108023082141561296f565b5f5160206150d95f395f51905f52546001600160a01b0316146129d0565b61082861396c565b6040516108559161083a602083610a59565b5f8252601f196108495f610ac7565b0136602084013761358a565b005b6109f4565b34610283575f36600319011261028357610886610881600260ff60c95460081c161490565b613712565b61010060c95461ff0019161760c9557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a161085561396c565b65ffffffffffff81160361028357565b359061030c826108c7565b9060608101918051926060835283518091526020608084019401905f5b81811061092c5750505065ffffffffffff60408262ffffff60208395015116602086015201511691015290565b82518652602095860195909201916001016108ff565b3461028357604036600319011261028357610974600435610962816108c7565b6024359061096f826108c7565b6138a2565b6040518091602082016020835281518091526040830190602060408260051b8601019301915f905b8282106109ab57505050500390f35b919360019193955060206109e48192603f198a82030186526040838a516001600160401b038151168452015191818582015201906108e2565b960192019201859493919261099c565b634e487b7160e01b5f52604160045260245ffd5b604081019081106001600160401b0382111761085757604052565b606081019081106001600160401b0382111761085757604052565b60c081019081106001600160401b0382111761085757604052565b90601f801991011681019081106001600160401b0382111761085757604052565b6040519061030c61012083610a59565b6040519061030c61024083610a59565b6040519061030c606083610a59565b6040519061030c60e083610a59565b6040519061030c604083610a59565b6001600160401b03811161085757601f01601f191660200190565b929192610aee82610ac7565b91610afc6040519384610a59565b829481845281830111610283578281602093845f960137010152565b604036600319011261028357600435610b30816102f0565b602435906001600160401b038211610283573660238301121561028357610b64610855923690602481600401359101610ae2565b90610b9e7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166108023082141561296f565b610ba661396c565b613652565b34610283575f366003190112610283577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163003610c03576040515f5160206150d95f395f51905f528152602090f35b60405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608490fd5b3461028357602036600319011261028357600435610c8a61396c565b65ffffffffffff60fb541660405190633dd0723360e21b825282600483015260248201525f8160448173b2c8e57eb1eb0b686b63f58e53f859bea615677b5af4918215610d8357610d3d61057d927fe4356761c97932c05c3ee0859fb1a5e4f91f7a1d7a3752c7d5a72d5cc6ecb2d2945f905f5f925f92610d4d575b610d3893945090610d2e610d339265ffffffffffff1665ffffffffffff1960fb54161760fb55565b612db0565b6139c4565b613ac0565b6040519081529081906020820190565b50505050610d38610d2e610d75610d33933d805f833e610d6d8183610a59565b810190612ce6565b909550859450925090610d06565b612da5565b34610283575f366003190112610283576020610dac600260ff60c95460081c161490565b6040519015158152f35b34610283575f3660031901126102835760406101005465ffffffffffff825191818116835260301c166020820152f35b34610283575f366003190112610283575f60a0604051610e0581610a3e565b828152826020820152826040820152826060820152826080820152015260c0610e2c612e43565b60a06040519165ffffffffffff815116835265ffffffffffff602082015116602084015265ffffffffffff604082015116604084015265ffffffffffff606082015116606084015265ffffffffffff6080820151166080840152015160a0820152f35b34610283575f36600319011261028357610ea761396c565b606580546001600160a01b03199081169091556033805491821690555f906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b34610283575f36600319011261028357606554336001600160a01b0390911603610f215761085533613b46565b60405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b6064820152608490fd5b34610283576020366003190112610283576004356001600160401b03811161028357604060031982360301126102835760405190610fb582610a08565b80600401356001600160401b038111610283576024610fdc60209260043691860101612f42565b92838552013592610fec84612abd565b0191825260c08101906110af61109261101261100d855151603a0260830190565b612a53565b9260a061108761107561105c61104f61104360208a01611038885165ffffffffffff1690565b60d01b815260060190565b60208781015182520190565b6040860151815260200190565b60608501516001600160a01b031660601b815260140190565b608084015165ffffffffffff16611038565b910151815260200190565b61109d845151614865565b83515161ffff1660f01b815260020190565b905f915b83518051841015611113576001916110ce8561110b93613303565b51805160601b6bffffffffffffffffffffffff19168252602081015160d01b6001600160d01b031916601483015260400151601a820152603a0190565b9201916110b3565b6107798361076c846111258a51151590565b15611132576001906146f6565b5f906146f6565b34610283575f3660031901126102835761116461115e600260ff60c95460081c161490565b15613712565b61020060c95461ff0019161760c9557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586020604051338152a161085561396c565b34610283575f366003190112610283575f5160206150d95f395f51905f52546040516001600160a01b039091168152602090f35b34610283575f366003190112610283576033546040516001600160a01b039091168152602090f35b9181601f84011215610283578235916001600160401b038311610283576020838186019501011161028357565b6040600319820112610283576004356001600160401b038111610283578161125891600401611201565b92909291602435906001600160401b0382116102835761127a91600401611201565b9091565b34610283576112bd6112b86112923661122e565b6112a0959395949294613408565b60025f5160206150b95f395f51905f525d3691610ae2565b613b99565b65ffffffffffff81511680159081156113b1575b50156113a25765ffffffffffff60016113336113509361139a9660fc54906112fe8265ffffffffffff1690565b978891611320603085901c65ffffffffffff169460601c65ffffffffffff1690565b9461132e8985161515612fc7565b613cbd565b93011665ffffffffffff1665ffffffffffff1960fc54161760fc55565b60fc80546bffffffffffff00000000000019164360301b6bffffffffffff00000000000016179055610d3861138b825165ffffffffffff1690565b61139483613f08565b90613a16565b610855614621565b63559895a360e01b5f5260045ffd5b90504211155f6112d1565b346102835760203660031901126102835760206113da600435612ff1565b604051908152f35b602060031982011261028357600435906001600160401b0382116102835761127a91600401611201565b346102835760a06114326112b8611422366113e2565b61142a61304c565b503691610ae2565b60ff604080519265ffffffffffff81511684526114786020820151602086019062ffffff6040809261ffff815116855261ffff6020820151166020860152015116910152565b0151166080820152f35b34610283576020366003190112610283576004356001600160401b038111610283576101206003198236030112610283576114bb610a7a565b906114c8816004016108d7565b82526114d6602482016108d7565b60208301526114e7604482016108d7565b60408301526114f860648201610301565b60608301526084810135608083015261151360a482016108d7565b60a083015260c481013560c083015261152e60e48201612964565b60e0830152610104810135916001600160401b0383116102835761155e610d3d9260046107799536920101613071565b610100820152613f08565b81516001600160a01b031681526102408101929161030c91906102209081906020818101516001600160a01b0316908501526040818101516001600160a01b0316908501526060818101516001600160a01b0316908501526080818101516001600160a01b03169085015260a0818101516001600160401b03169085015260c0818101516001600160401b03169085015260e08181015165ffffffffffff16908501526101008181015165ffffffffffff16908501526101208181015165ffffffffffff169085015261014081015161014085015261165461016082015161016086019060ff169052565b6101808101516101808501526116776101a08201516101a086019061ffff169052565b6101c0818101516001600160401b0316908501526101e0818101516001600160401b0316908501526102008181015161ffff1690850152015160ff16910152565b34610283575f366003190112610283576116d06131d4565b506107796116dc610a8a565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031660208201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031660408201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031660608201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031660808201526001600160401b037f00000000000000000000000000000000000000000000000000000000000000001660a08201526001600160401b037f00000000000000000000000000000000000000000000000000000000000000001660c082015265ffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660e082015265ffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001661010082015265ffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166101208201527f000000000000000000000000000000000000000000000000000000000000000061014082015260ff7f0000000000000000000000000000000000000000000000000000000000000000166101608201527f000000000000000000000000000000000000000000000000000000000000000061018082015261ffff7f0000000000000000000000000000000000000000000000000000000000000000166101a08201526001600160401b037f0000000000000000000000000000000000000000000000000000000000000000166101c08201526001600160401b037f0000000000000000000000000000000000000000000000000000000000000000166101e082015261ffff7f00000000000000000000000000000000000000000000000000000000000000001661020082015260ff7f00000000000000000000000000000000000000000000000000000000000000001661022082015260405191829182611569565b604090600319011261028357600435611a2a816102f0565b9060243561069d8161039f565b3461028357611a4536611a12565b90611a4e613408565b60025f5160206150b95f395f51905f525d6001600160a01b038116156104c057335f90815261010160205260409020611b339190611aeb611acb8254611a9a816001600160401b031690565b6001600160401b03811697886001600160401b038216115f14611c3357508092839265ffffffffffff9060401c1690565b65ffffffffffff811615908115611bfb575b50611bb3575b505033614b73565b936001600160401b0385161480611b8e575b611b78575b50611b0c83614688565b907f0000000000000000000000000000000000000000000000000000000000000000614be9565b6040516001600160401b03909116815233907f3362c96009316515fccd3dd29c7036c305ad9e892d83dd5681845ac9edb0c9a89080602081015b0390a2610855614621565b805465ffffffffffff60401b191690555f611b02565b508054611bac9060401c65ffffffffffff165b65ffffffffffff1690565b1515611afd565b611bf491611bc091613ffe565b6001600160401b03807f0000000000000000000000000000000000000000000000000000000000000000169116101561401e565b805f611ae3565b611c2b9150611ba1907f000000000000000000000000000000000000000000000000000000000000000090613fdb565b42105f611add565b92839260401c65ffffffffffff1690565b34610283575f36600319011261028357611c5c613408565b60025f5160206150b95f395f51905f525d335f90815261010160205260409020611c85906133db565b6001600160401b03611c9e82516001600160401b031690565b1615611dac57602081019065ffffffffffff611cc0835165ffffffffffff1690565b16611d9d574265ffffffffffff16909152611d2b90335f90815261010160205260409020815181546020909301516dffffffffffff000000000000000060409190911b166dffffffffffffffffffffffffffff199093166001600160401b0390911617919091179055565b611d60611ba165ffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001642614034565b60405165ffffffffffff909116815233907f3bbe41cfdd142e0f9b2224dac18c6efd2a6966e35a9ec23ab57ce63a60b33604908060208101611b6d565b63fb52063b60e01b5f5260045ffd5b634555262b60e01b5f5260045ffd5b62ffffff81160361028357565b359061030c82611dbb565b60609060231901126102835760405190611dec82610a23565b8160243561ffff8116810361028357815260443561ffff81168103610283576020820152604060643591611e1f83611dbb565b0152565b60609060031901126102835760405190611e3c82610a23565b8160043561ffff8116810361028357815260243561ffff81168103610283576020820152604060443591611e1f83611dbb565b606036600319011261028357611f1a6020611e8936611e23565b60015f5260fe602052611ebe7f457c8a48b4735f56b938837eb0a8a5f9c55f23c1a85767ce3b65c3e59d3d32b7541515613252565b604051809381926312b2aa9160e31b83527f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060048501613277565b0381738bbdf7b3d44c1cf6aa64db449e93ad5c0d10e63c5af4908115610d83575f91611f53575b5080611f4957005b6108559033614041565b611f75915060203d602011611f7b575b611f6d8183610a59565b810190613268565b5f611f41565b503d611f63565b34610283575f366003190112610283576040516343c3d71960e01b815260ff60048201526001600160401b037f0000000000000000000000000000000000000000000000000000000000000000811660248301527f0000000000000000000000000000000000000000000000000000000000000000166044820152602081606481738bbdf7b3d44c1cf6aa64db449e93ad5c0d10e63c5af48015610d8357610779915f91612046575b506040516001600160401b0390911681529081906020820190565b612068915060203d60201161206e575b6120608183610a59565b8101906132c8565b5f61202b565b503d612056565b34610283575f366003190112610283576065546040516001600160a01b039091168152602090f35b34610283576120ab3661122e565b926120d16120cc6120bb3361407b565b926120c4612e43565b953691610ae2565b614183565b80516120dd81866142d9565b919365ffffffffffff83169788155f1461265a57612132602080870151935b61210c60a0850195865114613317565b60408801996121258b5161211f89612ff1565b1461332d565b1561264b575b0151151590565b9283156125ff575b83612511575b5f99600188146124bb575b5065ffffffffffff16604082018190529165ffffffffffff4216606083015260c08601968751905f190161217e91613303565b5160400151905261218e90612db0565b8351606080860180516040805165ffffffffffff9586168082529890980185166020890152949093169386019390935292151592840192909252916001600160a01b03909116907f7ca0f1e30099488c4ee24e86a6b2c6802e9add6d530919af7aa17db3bcc1cff190608090a261220482614489565b936040518061221f8782919060206040840193600181520152565b035f5160206150995f395f51905f5291a18251604080516002815265ffffffffffff90921660208301527f6f0efde8b0c0045e52dacc742e064d057851db770103fca4eca3691f06b1477491a1602083015160405161228b819282919060206040840193600381520152565b035f5160206150995f395f51905f5291a1516040516122b7819282919060206040840193600481520152565b035f5160206150995f395f51905f5291a15160408051600581526001600160a01b0390921660208301527f960d4d998d188d9c36e4f362ffd9f6ab7c6eb8e6fb06fed6ecc702f2821168ba91a16080810151604080516006815265ffffffffffff90921660208301527f6f0efde8b0c0045e52dacc742e064d057851db770103fca4eca3691f06b1477491a160a00151604051612361819282919060206040840193600781520152565b035f5160206150995f395f51905f5291a1805161237d906132f1565b516040015160405161239c819282919060206040840193600881520152565b035f5160206150995f395f51905f5291a180516123b8906132f1565b515160408051600981526001600160a01b0390921660208301527f960d4d998d188d9c36e4f362ffd9f6ab7c6eb8e6fb06fed6ecc702f2821168ba91a1516123ff906132f1565b5160209081015160408051600b815265ffffffffffff909216928201929092527f6f0efde8b0c0045e52dacc742e064d057851db770103fca4eca3691f06b147749190a17f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690813b15610283575f93612497604051968795869485946314bcf3dd60e01b865260048601613363565b03915afa8015610d83576124a757005b806124b55f61085593610a59565b80610279565b65ffffffffffff919a506124ec611ba160206124de6125089460c08c0151613303565b51015165ffffffffffff1690565b612502611ba1606086015165ffffffffffff1690565b90614477565b4203999061214b565b60808601517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169065ffffffffffff169060a0880151604061256360c08b01515f198d0190613303565b51015161257f612571610a9a565b65ffffffffffff9095168552565b60208401526040830152803b156102835760408051631934171960e31b8152835165ffffffffffff1660048201526020840151602482015292015160448301525f908290606490829084905af18015610d83576125eb575b504265ffffffffffff166080830152612140565b806124b55f6125f993610a59565b5f6125d7565b925065ffffffffffff61261b608083015165ffffffffffff1690565b61ffff7f00000000000000000000000000000000000000000000000000000000000000001601164210159261213a565b6126558789614391565b61212b565b6121326020604061267b60c089015165ffffffffffff5f198a011690613303565b510151936120fc565b90602080835192838152019201905f5b8181106126a15750505090565b825180516001600160a01b0316855260208181015165ffffffffffff16818701526040918201519186019190915260609094019390920191600101612694565b34610283576126fd6120cc6126f5366113e2565b61142a61337f565b604051809160208252610779602061277d60c0845160408488015265ffffffffffff8151166060880152838101516080880152604081015160a088015260018060a01b036060820151168288015265ffffffffffff60808201511660e088015260a0810151610100880152015160e0610120870152610140860190612684565b92015115156040840152565b346102835761279736611a12565b61279f613408565b60025f5160206150b95f395f51905f525d6001600160a01b0382169182156104c057816127ce91610101614634565b6127da61042682614688565b6040516001600160401b0391909116815233907fe5e95641fa87bdfef3ce0d39f0c9a37c200f3bf59f53623b3de21e03ed33e3d290602090a360015f5160206150b95f395f51905f525d005b3461028357602036600319011261028357600435612843816102f0565b61284b61396c565b606580546001600160a01b0319166001600160a01b039283169081179091556033549091167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227005f80a3005b34610283576020366003190112610283576004356001600160401b0381116102835760e06003198236030112610283576113da6128d96020923690600401612f42565b614489565b604051906128eb82610a08565b5f6020838281520152565b156128fd57565b60405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608490fd5b60ff81160361028357565b359061030c82612959565b1561297657565b60405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b19195b1959d85d1958d85b1b60a21b6064820152608490fd5b156129d757565b60405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b6163746976652070726f787960a01b6064820152608490fd5b60408051909190612a428382610a59565b600e815291601f1901366020840137565b90612a5d82610ac7565b612a6a6040519182610a59565b8281528092612a7b601f1991610ac7565b0190602036910137565b519061030c826108c7565b519061030c826102f0565b519061030c82612959565b6001600160401b0381116108575760051b60200190565b8015150361028357565b519061030c82611dbb565b9080601f83011215610283578151612ae981612aa6565b92612af76040519485610a59565b81845260208085019260051b820101908382116102835760208101925b828410612b2357505050505090565b83516001600160401b0381116102835782016040818703601f1901126102835760405190612b5082610a08565b6020810151612b5e81612abd565b825260408101516001600160401b0381116102835760209101016060818803126102835760405190612b8f82610a23565b80516001600160401b03811161028357810188601f8201121561028357805190612bb882612aa6565b91612bc66040519384610a59565b80835260208084019160051b830101918b831161028357602001905b828210612c255750505091612c11604060209694938796948452612c07878201612ac7565b8785015201612a85565b604082015283820152815201930192612b14565b8151815260209182019101612be2565b9190916101208184031261028357612c4b610a7a565b92612c5582612a85565b8452612c6360208301612a85565b6020850152612c7460408301612a85565b6040850152612c8560608301612a90565b606085015260808201516080850152612ca060a08301612a85565b60a085015260c082015160c0850152612cbb60e08301612a9b565b60e08501526101008201516001600160401b03811161028357612cde9201612ad2565b610100830152565b8082039261012084126102835760c08251612d00816108c7565b94601f19011261028357604051612d1681610a3e565b6020830151612d24816108c7565b81526040830151612d34816108c7565b60208201526060830151612d47816108c7565b60408201526080830151612d5a816108c7565b606082015260a0830151612d6d816108c7565b608082015260c083015160a08201529260e08301516001600160401b0381116102835761010091612d9f918501612c35565b92015190565b6040513d5f823e3d90fd5b805160fc805460208401516040850151606080870151608088015165ffffffffffff60c01b60c09190911b166001600160f01b031990951665ffffffffffff909716969096176bffffffffffff00000000000060309490941b9390931692909217911b65ffffffffffff60601b161760909390931b65ffffffffffff60901b169290921791909117905560a0015160fd55565b60405190612e5082610a3e565b81612e9b65ffffffffffff60fc548181168452818160301c166020850152818160601c16604085015281808260901c1616606085015260c01c16608083019065ffffffffffff169052565b60a060fd54910152565b81601f8201121561028357803590612ebc82612aa6565b92612eca6040519485610a59565b8284526020606081860194028301019181831161028357602001925b828410612ef4575050505090565b606084830312610283576020606091604051612f0f81610a23565b8635612f1a816102f0565b815282870135612f29816108c7565b8382015260408701356040820152815201930192612ee6565b91909160e08184031261028357612f57610aa9565b92612f61826108d7565b84526020820135602085015260408201356040850152612f8360608301610301565b6060850152612f94608083016108d7565b608085015260a082013560a085015260c08201356001600160401b03811161028357612fc09201612ea5565b60c0830152565b15612fce57565b63ba74d80f60e01b5f5260045ffd5b634e487b7160e01b5f52601260045260245ffd5b7f000000000000000000000000000000000000000000000000000000000000000090811561302957065f5260fe60205260405f205490565b612fdd565b6040519061303b82610a23565b5f6040838281528260208201520152565b6040519061305982610a23565b5f60408382815261306861302e565b60208201520152565b9080601f8301121561028357813561308881612aa6565b926130966040519485610a59565b81845260208085019260051b820101908382116102835760208101925b8284106130c257505050505090565b83356001600160401b0381116102835782016040818703601f19011261028357604051906130ef82610a08565b60208101356130fd81612abd565b825260408101356001600160401b038111610283576020910101606081880312610283576040519061312e82610a23565b80356001600160401b03811161028357810188601f820112156102835780359061315782612aa6565b916131656040519384610a59565b80835260208084019160051b830101918b831161028357602001905b8282106131c457505050916131b06040602096949387969484526131a6878201611dc8565b87850152016108d7565b6040820152838201528152019301926130b3565b8135815260209182019101613181565b6131dc610a8a565b905f82525f60208301525f60408301525f60608301525f60808301525f60a08301525f60c08301525f60e08301525f6101008301525f6101208301525f6101408301525f6101608301525f6101808301525f6101a08301525f6101c08301525f6101e08301525f6102008301525f610220830152565b1561325957565b63f37a8b1360e01b5f5260045ffd5b90816020910312610283575190565b6060906001600160401b0361030c94969593968160c084019860ff8552166020840152166040820152019062ffffff6040809261ffff815116855261ffff6020820151166020860152015116910152565b90816020910312610283575161069d8161039f565b634e487b7160e01b5f52603260045260245ffd5b8051156132fe5760200190565b6132dd565b80518210156132fe5760209160051b010190565b1561331e57565b63198070b360e01b5f5260045ffd5b1561333457565b63f904c2fd60e01b5f5260045ffd5b908060209392818452848401375f828201840152601f01601f1916010190565b61069d9492606092825260208201528160408201520191613343565b6040519061338c82610a08565b60405160e08101836001600160401b03821183831017610857575f9260209260405283815283838201528360408201528360608201528360808201528360a0820152606060c082015281520152565b906040516133e881610a08565b91546001600160401b038116835260401c65ffffffffffff166020830152565b600260ff5f5160206150b95f395f51905f525c161461342357565b63dfc60d8560e01b5f5260045ffd5b1561343957565b60405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608490fd5b6134ab60ff5f5460081c166134a681613432565b613432565b6001600160a01b0381166134d457506134c333613b46565b61010060c95461ff0019161760c955565b6134c390613b46565b156134e457565b60405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608490fd5b60809060208152602e60208201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960408201526d6f6e206973206e6f74205555505360901b60608201520190565b906135b67f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1690565b156135c5575061030c906147bd565b6040516352d1902d60e01b8152906020826004816001600160a01b0387165afa5f9281613631575b5061360f5760405162461bcd60e51b81528061360b6004820161353b565b0390fd5b61030c9261362c5f5160206150d95f395f51905f525f94146134dd565b6146ff565b61364b91935060203d602011611f7b57611f6d8183610a59565b915f6135ed565b9061367e7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1690565b1561368d575061030c906147bd565b6040516352d1902d60e01b8152906020826004816001600160a01b0387165afa5f92816136f1575b506136d35760405162461bcd60e51b81528061360b6004820161353b565b61030c9261362c5f5160206150d95f395f51905f52600194146134dd565b61370b91935060203d602011611f7b57611f6d8183610a59565b915f6136b5565b1561371957565b63bae6e2a960e01b5f5260045ffd5b6040519061373582610a23565b5f604083606081528260208201520152565b6040519061375482610a08565b815f81526020613762613728565b910152565b60405190613776602083610a59565b5f80835282815b82811061378957505050565b602090613794613747565b8282850101520161377d565b906137aa82612aa6565b6137b76040519182610a59565b82815280926137c8601f1991612aa6565b01905f5b8281106137d857505050565b6020906137e3613747565b828285010152016137cc565b906040516137fc81610a23565b80926040518060208354918281520190835f5260205f20905f5b81811061386357505050600161030c949383613839604095613856950382610a59565b8552015462ffffff8116602085015260181c65ffffffffffff1690565b65ffffffffffff16910152565b8254845260209093019260019283019201613816565b9060405161388681610a08565b6020613762600183956001600160401b038154168552016137ef565b6101005465ffffffffffff8281169493603083901c821693929091168510801561395a575b801561394a575b61393d576138e9929165ffffffffffff809216920316614859565b6138f2816137a0565b925f5b82811061390157505050565b8061392161391c846001940160ff905f5260205260405f2090565b613879565b61392b8288613303565b526139368187613303565b50016138f5565b505050905061069d613767565b5065ffffffffffff8116156138ce565b5065ffffffffffff83168510156138c7565b6033546001600160a01b0316330361398057565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b7f000000000000000000000000000000000000000000000000000000000000000015613029575f805260fe6020527f32796e36004994222362c2f9423d5e208bb848170964890784a8d59ed40f50af55565b7f00000000000000000000000000000000000000000000000000000000000000009081156130295765ffffffffffff16065f5260fe60205260405f2055565b9080602083519182815201916020808360051b8301019401925f915b838310613a8057505050505090565b9091929394602080613ab1600193601f198682030187526040838b51805115158452015191818582015201906108e2565b97019301930191939290613a71565b65ffffffffffff8151167f7c4c4523e17533e451df15762a093e0693a2cd8b279fe54c6cd3777ed577121360018060a01b03606084015116926080810151613b4165ffffffffffff6040840151169261010060ff60e08301511691015190604051948594855260208501526040840152608060608401526080830190613a55565b0390a3565b606580546001600160a01b0319908116909155603380549182166001600160a01b0393841690811790915591167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3565b9060ff602d613ba661304c565b93602081015160d01c8552602681015160f01c6020860190815152602882015160f01c6020825101526040602a83015160e81c91510152016001815160f81c915050166040830152565b6040519061012082018281106001600160401b03821117610857576040526060610100835f81525f60208201525f60408201525f838201525f60808201525f60a08201525f60c08201525f60e08201520152565b15613c4b57565b6349517a1d60e11b5f5260045ffd5b15613c6157565b63eaabac9b60e01b5f5260045ffd5b90816020910312610283575161069d816108c7565b6001600160a01b03909116815260406020820181905261069d93910191613343565b15613cae57565b63e92c469f60e01b5f5260045ffd5b9294613d1c90613ce365ffffffffffff613d239497613cda613bf0565b50164311613c44565b5f1965ffffffffffff918803821681019091167f0000000000000000000000000000000000000000000000000000000000000000030190565b1515613c5a565b613d7c613d536020613d4b613d45613d3f604088015160ff1690565b60ff1690565b336148ad565b940151614a44565b613d5b610ab8565b905f8252602082015283515f1981510191613d768383613303565b52613303565b505f92613d8f6105066020850151151590565b613e3c575b50505f19430190613deb613db265ffffffffffff5f19870116612ff1565b915193613dce613dc0610a7a565b65ffffffffffff9097168752565b4265ffffffffffff16602087015265ffffffffffff166040860152565b336060850152608084015265ffffffffffff811660a08401524060c083015260ff7f00000000000000000000000000000000000000000000000000000000000000001660e083015261010082015290565b604051635600026d60e11b815292935060209183918291613e61913360048501613c85565b03815f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af1908115610d83575f91613ed9575b5090613ed2613ecd7f000000000000000000000000000000000000000000000000000000000000000033614b2d565b613ca7565b5f80613d94565b613efb915060203d602011613f01575b613ef38183610a59565b810190613c70565b5f613e9e565b503d613ee9565b604051613fc181613fb3610100602083019560208752613f3360408501825165ffffffffffff169052565b602081015165ffffffffffff166060850152604081015165ffffffffffff16608085015260608101516001600160a01b031660a0850152608081015160c085015260a081015165ffffffffffff1660e085015260c08101518483015260e081015160ff166101208501520151610120610140840152610160830190613a55565b03601f198101835282610a59565b51902090565b634e487b7160e01b5f52601160045260245ffd5b9065ffffffffffff8091169116019065ffffffffffff8211613ff957565b613fc7565b906001600160401b03809116911603906001600160401b038211613ff957565b1561402557565b6321f68cc160e21b5f5260045ffd5b91908201809211613ff957565b61030c915a91614c3a565b91908260409103126102835760208251612d9f81612abd565b1561406c57565b63c1a58f1960e01b5f5260045ffd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690811561412e5760408051633326844b60e11b81526001600160a01b0390921660048301529091829060249082905afa8015610d83575f915f916140fd575b50156140f8576140f390614065565b600190565b505f90565b9050614121915060403d604011614127575b6141198183610a59565b81019061404c565b5f6140e4565b503d61410f565b50505f90565b9061413e82612aa6565b61414b6040519182610a59565b828152809261415c601f1991612aa6565b01905f5b82811061416c57505050565b60209061417761302e565b82828501015201614160565b9061ffff6142476142336141cf61421f6142126141fe6141ea6141d96141cf6141be60206141af61337f565b9d01906006825160d01c920190565b91908d519065ffffffffffff169052565b9060208251920190565b9060208c5101529060208251920190565b9060408b510152906014825160601c920190565b919060608a51019060018060a01b03169052565b906006825160d01c920190565b919060808851019065ffffffffffff169052565b9060a086510152906002825160f01c920190565b911661425281614134565b60c0855101525f905b8082106142715750505160f81c15156020830152565b909161427e600191614c7d565b939061428f8260c089510151613303565b52019061425b565b1561429e57565b6363db3a4160e01b5f5260045ffd5b156142b457565b63677c56f160e01b5f5260045ffd5b156142ca57565b63181432e760e11b5f5260045ffd5b909165ffffffffffff60018160408501511601169260c08101515193841561438257614375611ba1836143288465ffffffffffff61432061069d985165ffffffffffff1690565b161115614297565b61435d614356611ba15f198b614347611ba1875165ffffffffffff1690565b0101995165ffffffffffff1690565b88106142ad565b614369848810156142c3565b5165ffffffffffff1690565b900365ffffffffffff1690565b63c2e5347d60e01b5f5260045ffd5b60c081019161441165ffffffffffff60206143b182875195168095613303565b5101511665ffffffffffff808060fc5460901c167f00000000000000000000000000000000000000000000000000000000000000000116917f00000000000000000000000000000000000000000000000000000000000000000116614477565b42111561447257606061443c61442e61444b9361030c9651613303565b51516001600160a01b031690565b9201516001600160a01b031690565b7f000000000000000000000000000000000000000000000000000000000000000091614cab565b505050565b9080821115614484575090565b905090565b60c081015180519061455160a06144b56003850260090190604051828193825260010160051b01604052565b602080820152946144db6144d2611ba1835165ffffffffffff1690565b60408801528690565b5060208101516060870152604081015160808701526060810151614522906145199061450d906001600160a01b031681565b6001600160a01b031690565b60a08801528690565b5061454561453c611ba1608084015165ffffffffffff1690565b60c08801528690565b50015160e08501528390565b5060e061010084015261012083018290525f9060095b83831061459f575050505061069d614586826020815160051b91012090565b918051604051828260010160051b011490151060061b52565b600360019161461760406145b38787613303565b5180516145dc906145ce9061450d906001600160a01b031681565b6001860160051b8c01528a90565b506146066145f6611ba1602084015165ffffffffffff1690565b60018689010160051b8c01528a90565b5001516003830160051b8901528790565b5001920191614567565b60015f5160206150b95f395f51905f525d565b6001600160a01b039091165f90815260209190915260409020906001600160401b03808354169116016001600160401b038111613ff957815467ffffffffffffffff19166001600160401b03909116179055565b6001600160401b0316633b9aca00810290808204633b9aca001490151715613ff95790565b6040516323b872dd60e01b60208201526001600160a01b03928316602482015292909116604483015260648083019390935291815261030c916146f1608483610a59565b614da9565b60019181530190565b91614709836147bd565b6001600160a01b0383167fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b5f80a2815115908115916147b5575b5061474c575050565b6147b2915f8060405193614761606086610a59565b602785527f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c6020860152660819985a5b195960ca1b6040860152602081519101845af46147ac614fd0565b91614fff565b50565b90505f614743565b803b156147fe5760018060a01b03166bffffffffffffffffffffffff60a01b5f5160206150d95f395f51905f525416175f5160206150d95f395f51905f5255565b60405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608490fd5b81811115614484575090565b61ffff1061486f57565b63161e7a6b60e11b5f5260045ffd5b6040519061488b82610a08565b5f602083606081520152565b1561489e57565b63014b3fdb60e11b5f5260045ffd5b919065ffffffffffff61030c916148c261487e565b94610100546148e86148d98265ffffffffffff1690565b9160301c65ffffffffffff1690565b916149158583850316918286115f146149e757829384915b61490c600184016137a0565b90818d52614e95565b9290947f00000000000000000000000000000000000000000000000000000000000000001191826149dd575b505061499f575b50501660ff7f00000000000000000000000000000000000000000000000000000000000000001661ffff7f000000000000000000000000000000000000000000000000000000000000000016020142116020840152565b6105066149d1916149d6937f000000000000000000000000000000000000000000000000000000000000000091614f92565b614897565b5f80614948565b1190505f80614941565b85938491614900565b156149f757565b63fdac229f60e01b5f5260045ffd5b90614a1082612aa6565b614a1d6040519182610a59565b8281528092612a7b601f1991612aa6565b15614a3557565b637bb2fa2f60e11b5f5260045ffd5b90614a4d613728565b506020820191614a6d61ffff614a65855161ffff1690565b1615156149f0565b614a8b614a86614a7f855161ffff1690565b61ffff1690565b614a06565b915f5b614a9d614a7f865161ffff1690565b811015614aef57614a7f600182614ac5614a9d94614ac0614a7f895161ffff1690565b614034565b49614ad08289613303565b52614ae6614ade8289613303565b511515614a2e565b01915050614a8e565b509250614b056040614b1c92015162ffffff1690565b614b0d610a9a565b92835262ffffff166020830152565b4265ffffffffffff16604082015290565b60018060a01b03165f526101016020526001600160401b0360405f205491166001600160401b03821610159081614b62575090565b65ffffffffffff915060401c161590565b6001600160a01b03165f9081526101016020526040902080549092916001600160401b039182169181168211614bc15750506001600160401b03825416916001600160401b03198154169055565b92614bcf8461030c93613ffe565b6001600160401b03166001600160401b0319825416179055565b60405163a9059cbb60e01b60208201526001600160a01b03909216602483015260448083019390935291815261030c916146f1606483610a59565b15614c2b57565b634c67134d60e11b5f5260045ffd5b919080156144725761030c925f92839260405192614c59602085610a59565b848452614c706001600160a01b0382161515614c24565b60208451940192f1614c24565b614c8561302e565b91815160601c8352601482015160d01c6020840152603a601a8301519201916040840152565b6001600160a01b0381165f908152610101602052604090209092919080546001600160401b039081169084168111614d945750805467ffffffffffffffff1981169091556001600160401b03165b6001600160401b03811615614d8e577faa22f5157944b5fa6846460e159d57ea9c3878e71fda274af372fa2ccf285aa0916001600160401b0382614d4d677fffffffffffffff60609560011c168092613ffe565b9080614d7c575b60408051978416885260208801919091529116908501526001600160a01b03908116941692a3565b614d898185610101614634565b614d54565b50505050565b90614da490614bcf858094613ffe565b614cf9565b90614e039160018060a01b03165f8060405193614dc7604086610a59565b602085527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564602086015260208151910182855af16147ac614fd0565b8051908115918215614e71575b505015614e1957565b60405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608490fd5b9091506020908201829003126102835760200151614e8e81612abd565b5f80614e10565b939190938315614f84575f5f5b858110614f0a575060406020614ed565ffffffffffff969798614ed08896633b9aca00614ee5970290614041565b6132f1565b510151015165ffffffffffff1690565b941601169061030c826101009065ffffffffffff1665ffffffffffff19825416179055565b90600190614f7c614f70614f318565ffffffffffff89160160ff905f5260205260405f2090565b614f39610ab8565b60018152614f488683016137ef565b6020820152614f57878d613303565b52614f62868c613303565b50546001600160401b031690565b6001600160401b031690565b019101614ea2565b5065ffffffffffff93509150565b65ffffffffffff8091169116811461412e575f5260ff60205265ffffffffffff600260405f20015460181c1690811561412e5761ffff160142101590565b3d15614ffa573d90614fe182610ac7565b91614fef6040519384610a59565b82523d5f602084013e565b606090565b919290156150615750815115615013575090565b3b1561501c5790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b8251909150156150745750805190602001fd5b60405162461bcd60e51b81526020600482015290819061360b90602483019061066856fe712de588b76f7fdb47439ab8677a0c8233392168ef0308d402c7b8d72138a080a5054f728453d3dbe953bdc43e4d0cb97e662ea32d7958190f3dc2da31d9721b360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca2646970667358221220f86c43e17817ce316cd3d772eaca06b07592db2cfd160e26ed1e615a9f74846a64736f6c634300081e0033000000000000000000000000461461e95de3cc306d5424f554463c162433384e000000000000000000000000cfb57e95cbab87bfd167b3eddd5c11e2d1613b2200000000000000000000000053789e39e3310737e8c8ced483032aac25b39ded000000000000000000000000cbf1639b8809adff74bd59ec292e436107852cc9000000000000000000000000a20182131658295f37c1a1efdbdc89eff97d9c58000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Deployed ByteCode

0x60806040526004361015610011575f80fd5b5f3560e01c80630423c7de1461027457806304f3bcec1461026f5780630d8912f31461026a578063137658381461026557806319ab453c14610260578063226112801461025b5780632f1969b0146102565780633075db56146102515780633659cfe61461024c5780633f4ba83a1461024757806340df9866146102425780634f1ef2861461023d57806352d1902d1461023857806359db6e85146102335780635c975abb1461022e5780635ccc1718146102295780636aa6a01a14610224578063715018a61461021f57806379ba50971461021a5780638301d56d146102155780638456cb59146102105780638abf60771461020b5780638da5cb5b146102065780639791e64414610201578063a834725a146101fc578063afb63ad4146101f7578063b28e824e146101f2578063c3f909d4146101ed578063d6dad060146101e8578063dbaf2145146101e3578063df596d9e146101de578063e3053335146101d9578063e30c3978146101d4578063ea191743146101cf578063edbacd44146101ca578063efba83c9146101c5578063f2fde38b146101c05763f954ab92146101bb575f80fd5b612896565b612826565b612789565b6126e1565b61209d565b612075565b611f82565b611e6f565b611c44565b611a37565b6116b8565b611482565b61140c565b6113bc565b61127e565b6111d9565b6111a5565b611139565b610f78565b610ef4565b610e8f565b610de6565b610db6565b610d88565b610c6e565b610bab565b610b18565b610942565b61085c565b6107ac565b61077d565b6106a0565b6105c7565b6104cf565b6103b0565b61030e565b6102ac565b610287565b5f91031261028357565b5f80fd5b34610283575f36600319011261028357602065ffffffffffff60fb5416604051908152f35b34610283575f366003190112610283576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b6001600160a01b0381160361028357565b359061030c826102f0565b565b3461028357602036600319011261028357604061035c600435610330816102f0565b6103386128de565b506103416128de565b506001600160a01b03165f9081526101016020526040902090565b65ffffffffffff82519161036f83610a08565b546001600160401b0381168352816020840191851c1681526001600160401b038451935116835251166020820152f35b6001600160401b0381160361028357565b34610283576020366003190112610283576004356103cd8161039f565b6103d5613408565b60025f5160206150b95f395f51905f525d33156104c0576103f98133610101614634565b335f9081526101016020526040902065ffffffffffff905460401c1661049c575b61044e61042682614688565b30337f000000000000000000000000a20182131658295f37c1a1efdbdc89eff97d9c586146ad565b6040516001600160401b03919091168152339081907fe5e95641fa87bdfef3ce0d39f0c9a37c200f3bf59f53623b3de21e03ed33e3d290602090a360015f5160206150b95f395f51905f525d005b335f90815261010160205260409020805465ffffffffffff60401b1916905561041a565b63e6c4247b60e01b5f5260045ffd5b34610283576020366003190112610283576004356104ec816102f0565b61053a5f549161052061050a6105068560ff9060081c1690565b1590565b809481956105b9575b8115610599575b506128f6565b82610531600160ff195f5416175f55565b61058257613492565b61054057005b61054e5f5461ff0019165f55565b604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989080602081015b0390a1005b6105946101005f5461ff001916175f55565b613492565b303b159150816105ab575b505f61051a565b60ff1660011490505f6105a4565b600160ff8216109150610513565b34610283575f366003190112610283576105df613408565b60025f5160206150b95f395f51905f525d335f9081526101016020526040902065ffffffffffff815460401c161561065957805465ffffffffffff60401b19169055337fc51fdb96728de385ec7859819e3997bc618362ef0dbca0ad051d856866cda3db5f80a260015f5160206150b95f395f51905f525d005b6387bdc6a960e01b5f5260045ffd5b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b90602061069d928181520190610668565b90565b346102835760a0366003190112610283576107796040516106c081610a23565b6004356106cc816108c7565b815261076c6106da36611dd3565b6020830190815261076661075e61074f6040608435946106f986612959565b818801958652610707612a31565b9765ffffffffffff60d01b905160d01b16602089015261ffff60f01b81515160f01b16602689015261ffff60f01b60208251015160f01b16602889015251015162ffffff1690565b60e81b602a860152602d850190565b915160ff1690565b906146f6565b506040519182918261068c565b0390f35b34610283575f366003190112610283576020600260ff5f5160206150b95f395f51905f525c1614604051908152f35b34610283576020366003190112610283576004356107c9816102f0565b6108207f000000000000000000000000cb84cf9bfae383b73dc23c5eff792929d714029a6001600160a01b03166108023082141561296f565b5f5160206150d95f395f51905f52546001600160a01b0316146129d0565b61082861396c565b6040516108559161083a602083610a59565b5f8252601f196108495f610ac7565b0136602084013761358a565b005b6109f4565b34610283575f36600319011261028357610886610881600260ff60c95460081c161490565b613712565b61010060c95461ff0019161760c9557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a161085561396c565b65ffffffffffff81160361028357565b359061030c826108c7565b9060608101918051926060835283518091526020608084019401905f5b81811061092c5750505065ffffffffffff60408262ffffff60208395015116602086015201511691015290565b82518652602095860195909201916001016108ff565b3461028357604036600319011261028357610974600435610962816108c7565b6024359061096f826108c7565b6138a2565b6040518091602082016020835281518091526040830190602060408260051b8601019301915f905b8282106109ab57505050500390f35b919360019193955060206109e48192603f198a82030186526040838a516001600160401b038151168452015191818582015201906108e2565b960192019201859493919261099c565b634e487b7160e01b5f52604160045260245ffd5b604081019081106001600160401b0382111761085757604052565b606081019081106001600160401b0382111761085757604052565b60c081019081106001600160401b0382111761085757604052565b90601f801991011681019081106001600160401b0382111761085757604052565b6040519061030c61012083610a59565b6040519061030c61024083610a59565b6040519061030c606083610a59565b6040519061030c60e083610a59565b6040519061030c604083610a59565b6001600160401b03811161085757601f01601f191660200190565b929192610aee82610ac7565b91610afc6040519384610a59565b829481845281830111610283578281602093845f960137010152565b604036600319011261028357600435610b30816102f0565b602435906001600160401b038211610283573660238301121561028357610b64610855923690602481600401359101610ae2565b90610b9e7f000000000000000000000000cb84cf9bfae383b73dc23c5eff792929d714029a6001600160a01b03166108023082141561296f565b610ba661396c565b613652565b34610283575f366003190112610283577f000000000000000000000000cb84cf9bfae383b73dc23c5eff792929d714029a6001600160a01b03163003610c03576040515f5160206150d95f395f51905f528152602090f35b60405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608490fd5b3461028357602036600319011261028357600435610c8a61396c565b65ffffffffffff60fb541660405190633dd0723360e21b825282600483015260248201525f8160448173b2c8e57eb1eb0b686b63f58e53f859bea615677b5af4918215610d8357610d3d61057d927fe4356761c97932c05c3ee0859fb1a5e4f91f7a1d7a3752c7d5a72d5cc6ecb2d2945f905f5f925f92610d4d575b610d3893945090610d2e610d339265ffffffffffff1665ffffffffffff1960fb54161760fb55565b612db0565b6139c4565b613ac0565b6040519081529081906020820190565b50505050610d38610d2e610d75610d33933d805f833e610d6d8183610a59565b810190612ce6565b909550859450925090610d06565b612da5565b34610283575f366003190112610283576020610dac600260ff60c95460081c161490565b6040519015158152f35b34610283575f3660031901126102835760406101005465ffffffffffff825191818116835260301c166020820152f35b34610283575f366003190112610283575f60a0604051610e0581610a3e565b828152826020820152826040820152826060820152826080820152015260c0610e2c612e43565b60a06040519165ffffffffffff815116835265ffffffffffff602082015116602084015265ffffffffffff604082015116604084015265ffffffffffff606082015116606084015265ffffffffffff6080820151166080840152015160a0820152f35b34610283575f36600319011261028357610ea761396c565b606580546001600160a01b03199081169091556033805491821690555f906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b34610283575f36600319011261028357606554336001600160a01b0390911603610f215761085533613b46565b60405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b6064820152608490fd5b34610283576020366003190112610283576004356001600160401b03811161028357604060031982360301126102835760405190610fb582610a08565b80600401356001600160401b038111610283576024610fdc60209260043691860101612f42565b92838552013592610fec84612abd565b0191825260c08101906110af61109261101261100d855151603a0260830190565b612a53565b9260a061108761107561105c61104f61104360208a01611038885165ffffffffffff1690565b60d01b815260060190565b60208781015182520190565b6040860151815260200190565b60608501516001600160a01b031660601b815260140190565b608084015165ffffffffffff16611038565b910151815260200190565b61109d845151614865565b83515161ffff1660f01b815260020190565b905f915b83518051841015611113576001916110ce8561110b93613303565b51805160601b6bffffffffffffffffffffffff19168252602081015160d01b6001600160d01b031916601483015260400151601a820152603a0190565b9201916110b3565b6107798361076c846111258a51151590565b15611132576001906146f6565b5f906146f6565b34610283575f3660031901126102835761116461115e600260ff60c95460081c161490565b15613712565b61020060c95461ff0019161760c9557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586020604051338152a161085561396c565b34610283575f366003190112610283575f5160206150d95f395f51905f52546040516001600160a01b039091168152602090f35b34610283575f366003190112610283576033546040516001600160a01b039091168152602090f35b9181601f84011215610283578235916001600160401b038311610283576020838186019501011161028357565b6040600319820112610283576004356001600160401b038111610283578161125891600401611201565b92909291602435906001600160401b0382116102835761127a91600401611201565b9091565b34610283576112bd6112b86112923661122e565b6112a0959395949294613408565b60025f5160206150b95f395f51905f525d3691610ae2565b613b99565b65ffffffffffff81511680159081156113b1575b50156113a25765ffffffffffff60016113336113509361139a9660fc54906112fe8265ffffffffffff1690565b978891611320603085901c65ffffffffffff169460601c65ffffffffffff1690565b9461132e8985161515612fc7565b613cbd565b93011665ffffffffffff1665ffffffffffff1960fc54161760fc55565b60fc80546bffffffffffff00000000000019164360301b6bffffffffffff00000000000016179055610d3861138b825165ffffffffffff1690565b61139483613f08565b90613a16565b610855614621565b63559895a360e01b5f5260045ffd5b90504211155f6112d1565b346102835760203660031901126102835760206113da600435612ff1565b604051908152f35b602060031982011261028357600435906001600160401b0382116102835761127a91600401611201565b346102835760a06114326112b8611422366113e2565b61142a61304c565b503691610ae2565b60ff604080519265ffffffffffff81511684526114786020820151602086019062ffffff6040809261ffff815116855261ffff6020820151166020860152015116910152565b0151166080820152f35b34610283576020366003190112610283576004356001600160401b038111610283576101206003198236030112610283576114bb610a7a565b906114c8816004016108d7565b82526114d6602482016108d7565b60208301526114e7604482016108d7565b60408301526114f860648201610301565b60608301526084810135608083015261151360a482016108d7565b60a083015260c481013560c083015261152e60e48201612964565b60e0830152610104810135916001600160401b0383116102835761155e610d3d9260046107799536920101613071565b610100820152613f08565b81516001600160a01b031681526102408101929161030c91906102209081906020818101516001600160a01b0316908501526040818101516001600160a01b0316908501526060818101516001600160a01b0316908501526080818101516001600160a01b03169085015260a0818101516001600160401b03169085015260c0818101516001600160401b03169085015260e08181015165ffffffffffff16908501526101008181015165ffffffffffff16908501526101208181015165ffffffffffff169085015261014081015161014085015261165461016082015161016086019060ff169052565b6101808101516101808501526116776101a08201516101a086019061ffff169052565b6101c0818101516001600160401b0316908501526101e0818101516001600160401b0316908501526102008181015161ffff1690850152015160ff16910152565b34610283575f366003190112610283576116d06131d4565b506107796116dc610a8a565b7f000000000000000000000000461461e95de3cc306d5424f554463c162433384e6001600160a01b031681527f000000000000000000000000cfb57e95cbab87bfd167b3eddd5c11e2d1613b226001600160a01b031660208201527f00000000000000000000000053789e39e3310737e8c8ced483032aac25b39ded6001600160a01b031660408201527f000000000000000000000000cbf1639b8809adff74bd59ec292e436107852cc96001600160a01b031660608201527f000000000000000000000000a20182131658295f37c1a1efdbdc89eff97d9c586001600160a01b031660808201526001600160401b037f00000000000000000000000000000000000000000000000000000000000000001660a08201526001600160401b037f00000000000000000000000000000000000000000000000000000000000000001660c082015265ffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660e082015265ffffffffffff7f0000000000000000000000000000000000000000000000000000000000001c201661010082015265ffffffffffff7f00000000000000000000000000000000000000000000000000000000000000b4166101208201527f000000000000000000000000000000000000000000000000000000000000006461014082015260ff7f000000000000000000000000000000000000000000000000000000000000004b166101608201527f000000000000000000000000000000000000000000000000000000000000000161018082015261ffff7f0000000000000000000000000000000000000000000000000000000000000000166101a08201526001600160401b037f0000000000000000000000000000000000000000000000000000000000989680166101c08201526001600160401b037f0000000000000000000000000000000000000000000000000000000000000032166101e082015261ffff7f00000000000000000000000000000000000000000000000000000000000001801661020082015260ff7f00000000000000000000000000000000000000000000000000000000000000051661022082015260405191829182611569565b604090600319011261028357600435611a2a816102f0565b9060243561069d8161039f565b3461028357611a4536611a12565b90611a4e613408565b60025f5160206150b95f395f51905f525d6001600160a01b038116156104c057335f90815261010160205260409020611b339190611aeb611acb8254611a9a816001600160401b031690565b6001600160401b03811697886001600160401b038216115f14611c3357508092839265ffffffffffff9060401c1690565b65ffffffffffff811615908115611bfb575b50611bb3575b505033614b73565b936001600160401b0385161480611b8e575b611b78575b50611b0c83614688565b907f000000000000000000000000a20182131658295f37c1a1efdbdc89eff97d9c58614be9565b6040516001600160401b03909116815233907f3362c96009316515fccd3dd29c7036c305ad9e892d83dd5681845ac9edb0c9a89080602081015b0390a2610855614621565b805465ffffffffffff60401b191690555f611b02565b508054611bac9060401c65ffffffffffff165b65ffffffffffff1690565b1515611afd565b611bf491611bc091613ffe565b6001600160401b03807f0000000000000000000000000000000000000000000000000000000000000000169116101561401e565b805f611ae3565b611c2b9150611ba1907f000000000000000000000000000000000000000000000000000000000000000090613fdb565b42105f611add565b92839260401c65ffffffffffff1690565b34610283575f36600319011261028357611c5c613408565b60025f5160206150b95f395f51905f525d335f90815261010160205260409020611c85906133db565b6001600160401b03611c9e82516001600160401b031690565b1615611dac57602081019065ffffffffffff611cc0835165ffffffffffff1690565b16611d9d574265ffffffffffff16909152611d2b90335f90815261010160205260409020815181546020909301516dffffffffffff000000000000000060409190911b166dffffffffffffffffffffffffffff199093166001600160401b0390911617919091179055565b611d60611ba165ffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001642614034565b60405165ffffffffffff909116815233907f3bbe41cfdd142e0f9b2224dac18c6efd2a6966e35a9ec23ab57ce63a60b33604908060208101611b6d565b63fb52063b60e01b5f5260045ffd5b634555262b60e01b5f5260045ffd5b62ffffff81160361028357565b359061030c82611dbb565b60609060231901126102835760405190611dec82610a23565b8160243561ffff8116810361028357815260443561ffff81168103610283576020820152604060643591611e1f83611dbb565b0152565b60609060031901126102835760405190611e3c82610a23565b8160043561ffff8116810361028357815260243561ffff81168103610283576020820152604060443591611e1f83611dbb565b606036600319011261028357611f1a6020611e8936611e23565b60015f5260fe602052611ebe7f457c8a48b4735f56b938837eb0a8a5f9c55f23c1a85767ce3b65c3e59d3d32b7541515613252565b604051809381926312b2aa9160e31b83527f00000000000000000000000000000000000000000000000000000000000000327f000000000000000000000000000000000000000000000000000000000098968060048501613277565b0381738bbdf7b3d44c1cf6aa64db449e93ad5c0d10e63c5af4908115610d83575f91611f53575b5080611f4957005b6108559033614041565b611f75915060203d602011611f7b575b611f6d8183610a59565b810190613268565b5f611f41565b503d611f63565b34610283575f366003190112610283576040516343c3d71960e01b815260ff60048201526001600160401b037f0000000000000000000000000000000000000000000000000000000000989680811660248301527f0000000000000000000000000000000000000000000000000000000000000032166044820152602081606481738bbdf7b3d44c1cf6aa64db449e93ad5c0d10e63c5af48015610d8357610779915f91612046575b506040516001600160401b0390911681529081906020820190565b612068915060203d60201161206e575b6120608183610a59565b8101906132c8565b5f61202b565b503d612056565b34610283575f366003190112610283576065546040516001600160a01b039091168152602090f35b34610283576120ab3661122e565b926120d16120cc6120bb3361407b565b926120c4612e43565b953691610ae2565b614183565b80516120dd81866142d9565b919365ffffffffffff83169788155f1461265a57612132602080870151935b61210c60a0850195865114613317565b60408801996121258b5161211f89612ff1565b1461332d565b1561264b575b0151151590565b9283156125ff575b83612511575b5f99600188146124bb575b5065ffffffffffff16604082018190529165ffffffffffff4216606083015260c08601968751905f190161217e91613303565b5160400151905261218e90612db0565b8351606080860180516040805165ffffffffffff9586168082529890980185166020890152949093169386019390935292151592840192909252916001600160a01b03909116907f7ca0f1e30099488c4ee24e86a6b2c6802e9add6d530919af7aa17db3bcc1cff190608090a261220482614489565b936040518061221f8782919060206040840193600181520152565b035f5160206150995f395f51905f5291a18251604080516002815265ffffffffffff90921660208301527f6f0efde8b0c0045e52dacc742e064d057851db770103fca4eca3691f06b1477491a1602083015160405161228b819282919060206040840193600381520152565b035f5160206150995f395f51905f5291a1516040516122b7819282919060206040840193600481520152565b035f5160206150995f395f51905f5291a15160408051600581526001600160a01b0390921660208301527f960d4d998d188d9c36e4f362ffd9f6ab7c6eb8e6fb06fed6ecc702f2821168ba91a16080810151604080516006815265ffffffffffff90921660208301527f6f0efde8b0c0045e52dacc742e064d057851db770103fca4eca3691f06b1477491a160a00151604051612361819282919060206040840193600781520152565b035f5160206150995f395f51905f5291a1805161237d906132f1565b516040015160405161239c819282919060206040840193600881520152565b035f5160206150995f395f51905f5291a180516123b8906132f1565b515160408051600981526001600160a01b0390921660208301527f960d4d998d188d9c36e4f362ffd9f6ab7c6eb8e6fb06fed6ecc702f2821168ba91a1516123ff906132f1565b5160209081015160408051600b815265ffffffffffff909216928201929092527f6f0efde8b0c0045e52dacc742e064d057851db770103fca4eca3691f06b147749190a17f000000000000000000000000461461e95de3cc306d5424f554463c162433384e6001600160a01b031690813b15610283575f93612497604051968795869485946314bcf3dd60e01b865260048601613363565b03915afa8015610d83576124a757005b806124b55f61085593610a59565b80610279565b65ffffffffffff919a506124ec611ba160206124de6125089460c08c0151613303565b51015165ffffffffffff1690565b612502611ba1606086015165ffffffffffff1690565b90614477565b4203999061214b565b60808601517f000000000000000000000000cbf1639b8809adff74bd59ec292e436107852cc96001600160a01b03169065ffffffffffff169060a0880151604061256360c08b01515f198d0190613303565b51015161257f612571610a9a565b65ffffffffffff9095168552565b60208401526040830152803b156102835760408051631934171960e31b8152835165ffffffffffff1660048201526020840151602482015292015160448301525f908290606490829084905af18015610d83576125eb575b504265ffffffffffff166080830152612140565b806124b55f6125f993610a59565b5f6125d7565b925065ffffffffffff61261b608083015165ffffffffffff1690565b61ffff7f00000000000000000000000000000000000000000000000000000000000001801601164210159261213a565b6126558789614391565b61212b565b6121326020604061267b60c089015165ffffffffffff5f198a011690613303565b510151936120fc565b90602080835192838152019201905f5b8181106126a15750505090565b825180516001600160a01b0316855260208181015165ffffffffffff16818701526040918201519186019190915260609094019390920191600101612694565b34610283576126fd6120cc6126f5366113e2565b61142a61337f565b604051809160208252610779602061277d60c0845160408488015265ffffffffffff8151166060880152838101516080880152604081015160a088015260018060a01b036060820151168288015265ffffffffffff60808201511660e088015260a0810151610100880152015160e0610120870152610140860190612684565b92015115156040840152565b346102835761279736611a12565b61279f613408565b60025f5160206150b95f395f51905f525d6001600160a01b0382169182156104c057816127ce91610101614634565b6127da61042682614688565b6040516001600160401b0391909116815233907fe5e95641fa87bdfef3ce0d39f0c9a37c200f3bf59f53623b3de21e03ed33e3d290602090a360015f5160206150b95f395f51905f525d005b3461028357602036600319011261028357600435612843816102f0565b61284b61396c565b606580546001600160a01b0319166001600160a01b039283169081179091556033549091167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227005f80a3005b34610283576020366003190112610283576004356001600160401b0381116102835760e06003198236030112610283576113da6128d96020923690600401612f42565b614489565b604051906128eb82610a08565b5f6020838281520152565b156128fd57565b60405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608490fd5b60ff81160361028357565b359061030c82612959565b1561297657565b60405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b19195b1959d85d1958d85b1b60a21b6064820152608490fd5b156129d757565b60405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b6163746976652070726f787960a01b6064820152608490fd5b60408051909190612a428382610a59565b600e815291601f1901366020840137565b90612a5d82610ac7565b612a6a6040519182610a59565b8281528092612a7b601f1991610ac7565b0190602036910137565b519061030c826108c7565b519061030c826102f0565b519061030c82612959565b6001600160401b0381116108575760051b60200190565b8015150361028357565b519061030c82611dbb565b9080601f83011215610283578151612ae981612aa6565b92612af76040519485610a59565b81845260208085019260051b820101908382116102835760208101925b828410612b2357505050505090565b83516001600160401b0381116102835782016040818703601f1901126102835760405190612b5082610a08565b6020810151612b5e81612abd565b825260408101516001600160401b0381116102835760209101016060818803126102835760405190612b8f82610a23565b80516001600160401b03811161028357810188601f8201121561028357805190612bb882612aa6565b91612bc66040519384610a59565b80835260208084019160051b830101918b831161028357602001905b828210612c255750505091612c11604060209694938796948452612c07878201612ac7565b8785015201612a85565b604082015283820152815201930192612b14565b8151815260209182019101612be2565b9190916101208184031261028357612c4b610a7a565b92612c5582612a85565b8452612c6360208301612a85565b6020850152612c7460408301612a85565b6040850152612c8560608301612a90565b606085015260808201516080850152612ca060a08301612a85565b60a085015260c082015160c0850152612cbb60e08301612a9b565b60e08501526101008201516001600160401b03811161028357612cde9201612ad2565b610100830152565b8082039261012084126102835760c08251612d00816108c7565b94601f19011261028357604051612d1681610a3e565b6020830151612d24816108c7565b81526040830151612d34816108c7565b60208201526060830151612d47816108c7565b60408201526080830151612d5a816108c7565b606082015260a0830151612d6d816108c7565b608082015260c083015160a08201529260e08301516001600160401b0381116102835761010091612d9f918501612c35565b92015190565b6040513d5f823e3d90fd5b805160fc805460208401516040850151606080870151608088015165ffffffffffff60c01b60c09190911b166001600160f01b031990951665ffffffffffff909716969096176bffffffffffff00000000000060309490941b9390931692909217911b65ffffffffffff60601b161760909390931b65ffffffffffff60901b169290921791909117905560a0015160fd55565b60405190612e5082610a3e565b81612e9b65ffffffffffff60fc548181168452818160301c166020850152818160601c16604085015281808260901c1616606085015260c01c16608083019065ffffffffffff169052565b60a060fd54910152565b81601f8201121561028357803590612ebc82612aa6565b92612eca6040519485610a59565b8284526020606081860194028301019181831161028357602001925b828410612ef4575050505090565b606084830312610283576020606091604051612f0f81610a23565b8635612f1a816102f0565b815282870135612f29816108c7565b8382015260408701356040820152815201930192612ee6565b91909160e08184031261028357612f57610aa9565b92612f61826108d7565b84526020820135602085015260408201356040850152612f8360608301610301565b6060850152612f94608083016108d7565b608085015260a082013560a085015260c08201356001600160401b03811161028357612fc09201612ea5565b60c0830152565b15612fce57565b63ba74d80f60e01b5f5260045ffd5b634e487b7160e01b5f52601260045260245ffd5b7f000000000000000000000000000000000000000000000000000000000000006490811561302957065f5260fe60205260405f205490565b612fdd565b6040519061303b82610a23565b5f6040838281528260208201520152565b6040519061305982610a23565b5f60408382815261306861302e565b60208201520152565b9080601f8301121561028357813561308881612aa6565b926130966040519485610a59565b81845260208085019260051b820101908382116102835760208101925b8284106130c257505050505090565b83356001600160401b0381116102835782016040818703601f19011261028357604051906130ef82610a08565b60208101356130fd81612abd565b825260408101356001600160401b038111610283576020910101606081880312610283576040519061312e82610a23565b80356001600160401b03811161028357810188601f820112156102835780359061315782612aa6565b916131656040519384610a59565b80835260208084019160051b830101918b831161028357602001905b8282106131c457505050916131b06040602096949387969484526131a6878201611dc8565b87850152016108d7565b6040820152838201528152019301926130b3565b8135815260209182019101613181565b6131dc610a8a565b905f82525f60208301525f60408301525f60608301525f60808301525f60a08301525f60c08301525f60e08301525f6101008301525f6101208301525f6101408301525f6101608301525f6101808301525f6101a08301525f6101c08301525f6101e08301525f6102008301525f610220830152565b1561325957565b63f37a8b1360e01b5f5260045ffd5b90816020910312610283575190565b6060906001600160401b0361030c94969593968160c084019860ff8552166020840152166040820152019062ffffff6040809261ffff815116855261ffff6020820151166020860152015116910152565b90816020910312610283575161069d8161039f565b634e487b7160e01b5f52603260045260245ffd5b8051156132fe5760200190565b6132dd565b80518210156132fe5760209160051b010190565b1561331e57565b63198070b360e01b5f5260045ffd5b1561333457565b63f904c2fd60e01b5f5260045ffd5b908060209392818452848401375f828201840152601f01601f1916010190565b61069d9492606092825260208201528160408201520191613343565b6040519061338c82610a08565b60405160e08101836001600160401b03821183831017610857575f9260209260405283815283838201528360408201528360608201528360808201528360a0820152606060c082015281520152565b906040516133e881610a08565b91546001600160401b038116835260401c65ffffffffffff166020830152565b600260ff5f5160206150b95f395f51905f525c161461342357565b63dfc60d8560e01b5f5260045ffd5b1561343957565b60405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608490fd5b6134ab60ff5f5460081c166134a681613432565b613432565b6001600160a01b0381166134d457506134c333613b46565b61010060c95461ff0019161760c955565b6134c390613b46565b156134e457565b60405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608490fd5b60809060208152602e60208201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960408201526d6f6e206973206e6f74205555505360901b60608201520190565b906135b67f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1690565b156135c5575061030c906147bd565b6040516352d1902d60e01b8152906020826004816001600160a01b0387165afa5f9281613631575b5061360f5760405162461bcd60e51b81528061360b6004820161353b565b0390fd5b61030c9261362c5f5160206150d95f395f51905f525f94146134dd565b6146ff565b61364b91935060203d602011611f7b57611f6d8183610a59565b915f6135ed565b9061367e7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1690565b1561368d575061030c906147bd565b6040516352d1902d60e01b8152906020826004816001600160a01b0387165afa5f92816136f1575b506136d35760405162461bcd60e51b81528061360b6004820161353b565b61030c9261362c5f5160206150d95f395f51905f52600194146134dd565b61370b91935060203d602011611f7b57611f6d8183610a59565b915f6136b5565b1561371957565b63bae6e2a960e01b5f5260045ffd5b6040519061373582610a23565b5f604083606081528260208201520152565b6040519061375482610a08565b815f81526020613762613728565b910152565b60405190613776602083610a59565b5f80835282815b82811061378957505050565b602090613794613747565b8282850101520161377d565b906137aa82612aa6565b6137b76040519182610a59565b82815280926137c8601f1991612aa6565b01905f5b8281106137d857505050565b6020906137e3613747565b828285010152016137cc565b906040516137fc81610a23565b80926040518060208354918281520190835f5260205f20905f5b81811061386357505050600161030c949383613839604095613856950382610a59565b8552015462ffffff8116602085015260181c65ffffffffffff1690565b65ffffffffffff16910152565b8254845260209093019260019283019201613816565b9060405161388681610a08565b6020613762600183956001600160401b038154168552016137ef565b6101005465ffffffffffff8281169493603083901c821693929091168510801561395a575b801561394a575b61393d576138e9929165ffffffffffff809216920316614859565b6138f2816137a0565b925f5b82811061390157505050565b8061392161391c846001940160ff905f5260205260405f2090565b613879565b61392b8288613303565b526139368187613303565b50016138f5565b505050905061069d613767565b5065ffffffffffff8116156138ce565b5065ffffffffffff83168510156138c7565b6033546001600160a01b0316330361398057565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b7f000000000000000000000000000000000000000000000000000000000000006415613029575f805260fe6020527f32796e36004994222362c2f9423d5e208bb848170964890784a8d59ed40f50af55565b7f00000000000000000000000000000000000000000000000000000000000000649081156130295765ffffffffffff16065f5260fe60205260405f2055565b9080602083519182815201916020808360051b8301019401925f915b838310613a8057505050505090565b9091929394602080613ab1600193601f198682030187526040838b51805115158452015191818582015201906108e2565b97019301930191939290613a71565b65ffffffffffff8151167f7c4c4523e17533e451df15762a093e0693a2cd8b279fe54c6cd3777ed577121360018060a01b03606084015116926080810151613b4165ffffffffffff6040840151169261010060ff60e08301511691015190604051948594855260208501526040840152608060608401526080830190613a55565b0390a3565b606580546001600160a01b0319908116909155603380549182166001600160a01b0393841690811790915591167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3565b9060ff602d613ba661304c565b93602081015160d01c8552602681015160f01c6020860190815152602882015160f01c6020825101526040602a83015160e81c91510152016001815160f81c915050166040830152565b6040519061012082018281106001600160401b03821117610857576040526060610100835f81525f60208201525f60408201525f838201525f60808201525f60a08201525f60c08201525f60e08201520152565b15613c4b57565b6349517a1d60e11b5f5260045ffd5b15613c6157565b63eaabac9b60e01b5f5260045ffd5b90816020910312610283575161069d816108c7565b6001600160a01b03909116815260406020820181905261069d93910191613343565b15613cae57565b63e92c469f60e01b5f5260045ffd5b9294613d1c90613ce365ffffffffffff613d239497613cda613bf0565b50164311613c44565b5f1965ffffffffffff918803821681019091167f0000000000000000000000000000000000000000000000000000000000000064030190565b1515613c5a565b613d7c613d536020613d4b613d45613d3f604088015160ff1690565b60ff1690565b336148ad565b940151614a44565b613d5b610ab8565b905f8252602082015283515f1981510191613d768383613303565b52613303565b505f92613d8f6105066020850151151590565b613e3c575b50505f19430190613deb613db265ffffffffffff5f19870116612ff1565b915193613dce613dc0610a7a565b65ffffffffffff9097168752565b4265ffffffffffff16602087015265ffffffffffff166040860152565b336060850152608084015265ffffffffffff811660a08401524060c083015260ff7f000000000000000000000000000000000000000000000000000000000000004b1660e083015261010082015290565b604051635600026d60e11b815292935060209183918291613e61913360048501613c85565b03815f7f000000000000000000000000cfb57e95cbab87bfd167b3eddd5c11e2d1613b226001600160a01b03165af1908115610d83575f91613ed9575b5090613ed2613ecd7f000000000000000000000000000000000000000000000000000000000000000033614b2d565b613ca7565b5f80613d94565b613efb915060203d602011613f01575b613ef38183610a59565b810190613c70565b5f613e9e565b503d613ee9565b604051613fc181613fb3610100602083019560208752613f3360408501825165ffffffffffff169052565b602081015165ffffffffffff166060850152604081015165ffffffffffff16608085015260608101516001600160a01b031660a0850152608081015160c085015260a081015165ffffffffffff1660e085015260c08101518483015260e081015160ff166101208501520151610120610140840152610160830190613a55565b03601f198101835282610a59565b51902090565b634e487b7160e01b5f52601160045260245ffd5b9065ffffffffffff8091169116019065ffffffffffff8211613ff957565b613fc7565b906001600160401b03809116911603906001600160401b038211613ff957565b1561402557565b6321f68cc160e21b5f5260045ffd5b91908201809211613ff957565b61030c915a91614c3a565b91908260409103126102835760208251612d9f81612abd565b1561406c57565b63c1a58f1960e01b5f5260045ffd5b7f00000000000000000000000053789e39e3310737e8c8ced483032aac25b39ded6001600160a01b031690811561412e5760408051633326844b60e11b81526001600160a01b0390921660048301529091829060249082905afa8015610d83575f915f916140fd575b50156140f8576140f390614065565b600190565b505f90565b9050614121915060403d604011614127575b6141198183610a59565b81019061404c565b5f6140e4565b503d61410f565b50505f90565b9061413e82612aa6565b61414b6040519182610a59565b828152809261415c601f1991612aa6565b01905f5b82811061416c57505050565b60209061417761302e565b82828501015201614160565b9061ffff6142476142336141cf61421f6142126141fe6141ea6141d96141cf6141be60206141af61337f565b9d01906006825160d01c920190565b91908d519065ffffffffffff169052565b9060208251920190565b9060208c5101529060208251920190565b9060408b510152906014825160601c920190565b919060608a51019060018060a01b03169052565b906006825160d01c920190565b919060808851019065ffffffffffff169052565b9060a086510152906002825160f01c920190565b911661425281614134565b60c0855101525f905b8082106142715750505160f81c15156020830152565b909161427e600191614c7d565b939061428f8260c089510151613303565b52019061425b565b1561429e57565b6363db3a4160e01b5f5260045ffd5b156142b457565b63677c56f160e01b5f5260045ffd5b156142ca57565b63181432e760e11b5f5260045ffd5b909165ffffffffffff60018160408501511601169260c08101515193841561438257614375611ba1836143288465ffffffffffff61432061069d985165ffffffffffff1690565b161115614297565b61435d614356611ba15f198b614347611ba1875165ffffffffffff1690565b0101995165ffffffffffff1690565b88106142ad565b614369848810156142c3565b5165ffffffffffff1690565b900365ffffffffffff1690565b63c2e5347d60e01b5f5260045ffd5b60c081019161441165ffffffffffff60206143b182875195168095613303565b5101511665ffffffffffff808060fc5460901c167f00000000000000000000000000000000000000000000000000000000000000b40116917f0000000000000000000000000000000000000000000000000000000000001c200116614477565b42111561447257606061443c61442e61444b9361030c9651613303565b51516001600160a01b031690565b9201516001600160a01b031690565b7f000000000000000000000000000000000000000000000000000000000000000091614cab565b505050565b9080821115614484575090565b905090565b60c081015180519061455160a06144b56003850260090190604051828193825260010160051b01604052565b602080820152946144db6144d2611ba1835165ffffffffffff1690565b60408801528690565b5060208101516060870152604081015160808701526060810151614522906145199061450d906001600160a01b031681565b6001600160a01b031690565b60a08801528690565b5061454561453c611ba1608084015165ffffffffffff1690565b60c08801528690565b50015160e08501528390565b5060e061010084015261012083018290525f9060095b83831061459f575050505061069d614586826020815160051b91012090565b918051604051828260010160051b011490151060061b52565b600360019161461760406145b38787613303565b5180516145dc906145ce9061450d906001600160a01b031681565b6001860160051b8c01528a90565b506146066145f6611ba1602084015165ffffffffffff1690565b60018689010160051b8c01528a90565b5001516003830160051b8901528790565b5001920191614567565b60015f5160206150b95f395f51905f525d565b6001600160a01b039091165f90815260209190915260409020906001600160401b03808354169116016001600160401b038111613ff957815467ffffffffffffffff19166001600160401b03909116179055565b6001600160401b0316633b9aca00810290808204633b9aca001490151715613ff95790565b6040516323b872dd60e01b60208201526001600160a01b03928316602482015292909116604483015260648083019390935291815261030c916146f1608483610a59565b614da9565b60019181530190565b91614709836147bd565b6001600160a01b0383167fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b5f80a2815115908115916147b5575b5061474c575050565b6147b2915f8060405193614761606086610a59565b602785527f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c6020860152660819985a5b195960ca1b6040860152602081519101845af46147ac614fd0565b91614fff565b50565b90505f614743565b803b156147fe5760018060a01b03166bffffffffffffffffffffffff60a01b5f5160206150d95f395f51905f525416175f5160206150d95f395f51905f5255565b60405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608490fd5b81811115614484575090565b61ffff1061486f57565b63161e7a6b60e11b5f5260045ffd5b6040519061488b82610a08565b5f602083606081520152565b1561489e57565b63014b3fdb60e11b5f5260045ffd5b919065ffffffffffff61030c916148c261487e565b94610100546148e86148d98265ffffffffffff1690565b9160301c65ffffffffffff1690565b916149158583850316918286115f146149e757829384915b61490c600184016137a0565b90818d52614e95565b9290947f00000000000000000000000000000000000000000000000000000000000000011191826149dd575b505061499f575b50501660ff7f00000000000000000000000000000000000000000000000000000000000000051661ffff7f000000000000000000000000000000000000000000000000000000000000000016020142116020840152565b6105066149d1916149d6937f000000000000000000000000000000000000000000000000000000000000000091614f92565b614897565b5f80614948565b1190505f80614941565b85938491614900565b156149f757565b63fdac229f60e01b5f5260045ffd5b90614a1082612aa6565b614a1d6040519182610a59565b8281528092612a7b601f1991612aa6565b15614a3557565b637bb2fa2f60e11b5f5260045ffd5b90614a4d613728565b506020820191614a6d61ffff614a65855161ffff1690565b1615156149f0565b614a8b614a86614a7f855161ffff1690565b61ffff1690565b614a06565b915f5b614a9d614a7f865161ffff1690565b811015614aef57614a7f600182614ac5614a9d94614ac0614a7f895161ffff1690565b614034565b49614ad08289613303565b52614ae6614ade8289613303565b511515614a2e565b01915050614a8e565b509250614b056040614b1c92015162ffffff1690565b614b0d610a9a565b92835262ffffff166020830152565b4265ffffffffffff16604082015290565b60018060a01b03165f526101016020526001600160401b0360405f205491166001600160401b03821610159081614b62575090565b65ffffffffffff915060401c161590565b6001600160a01b03165f9081526101016020526040902080549092916001600160401b039182169181168211614bc15750506001600160401b03825416916001600160401b03198154169055565b92614bcf8461030c93613ffe565b6001600160401b03166001600160401b0319825416179055565b60405163a9059cbb60e01b60208201526001600160a01b03909216602483015260448083019390935291815261030c916146f1606483610a59565b15614c2b57565b634c67134d60e11b5f5260045ffd5b919080156144725761030c925f92839260405192614c59602085610a59565b848452614c706001600160a01b0382161515614c24565b60208451940192f1614c24565b614c8561302e565b91815160601c8352601482015160d01c6020840152603a601a8301519201916040840152565b6001600160a01b0381165f908152610101602052604090209092919080546001600160401b039081169084168111614d945750805467ffffffffffffffff1981169091556001600160401b03165b6001600160401b03811615614d8e577faa22f5157944b5fa6846460e159d57ea9c3878e71fda274af372fa2ccf285aa0916001600160401b0382614d4d677fffffffffffffff60609560011c168092613ffe565b9080614d7c575b60408051978416885260208801919091529116908501526001600160a01b03908116941692a3565b614d898185610101614634565b614d54565b50505050565b90614da490614bcf858094613ffe565b614cf9565b90614e039160018060a01b03165f8060405193614dc7604086610a59565b602085527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564602086015260208151910182855af16147ac614fd0565b8051908115918215614e71575b505015614e1957565b60405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608490fd5b9091506020908201829003126102835760200151614e8e81612abd565b5f80614e10565b939190938315614f84575f5f5b858110614f0a575060406020614ed565ffffffffffff969798614ed08896633b9aca00614ee5970290614041565b6132f1565b510151015165ffffffffffff1690565b941601169061030c826101009065ffffffffffff1665ffffffffffff19825416179055565b90600190614f7c614f70614f318565ffffffffffff89160160ff905f5260205260405f2090565b614f39610ab8565b60018152614f488683016137ef565b6020820152614f57878d613303565b52614f62868c613303565b50546001600160401b031690565b6001600160401b031690565b019101614ea2565b5065ffffffffffff93509150565b65ffffffffffff8091169116811461412e575f5260ff60205265ffffffffffff600260405f20015460181c1690811561412e5761ffff160142101590565b3d15614ffa573d90614fe182610ac7565b91614fef6040519384610a59565b82523d5f602084013e565b606090565b919290156150615750815115615013575090565b3b1561501c5790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b8251909150156150745750805190602001fd5b60405162461bcd60e51b81526020600482015290819061360b90602483019061066856fe712de588b76f7fdb47439ab8677a0c8233392168ef0308d402c7b8d72138a080a5054f728453d3dbe953bdc43e4d0cb97e662ea32d7958190f3dc2da31d9721b360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca2646970667358221220f86c43e17817ce316cd3d772eaca06b07592db2cfd160e26ed1e615a9f74846a64736f6c634300081e0033

External libraries