{"sources":{"@openzeppelin/contracts/access/Ownable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\n\npragma solidity ^0.8.20;\n\nimport {Context} from \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * The initial owner is set to the address provided by the deployer. This can\n * later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n    address private _owner;\n\n    /**\n     * @dev The caller account is not authorized to perform an operation.\n     */\n    error OwnableUnauthorizedAccount(address account);\n\n    /**\n     * @dev The owner is not a valid owner account. (eg. `address(0)`)\n     */\n    error OwnableInvalidOwner(address owner);\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\n     */\n    constructor(address initialOwner) {\n        if (initialOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(initialOwner);\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        if (owner() != _msgSender()) {\n            revert OwnableUnauthorizedAccount(_msgSender());\n        }\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        if (newOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"},"@openzeppelin/contracts/access/Ownable2Step.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.20;\n\nimport {Ownable} from \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This extension of the {Ownable} contract includes a two-step mechanism to transfer\n * ownership, where the new owner must call {acceptOwnership} in order to replace the\n * old one. This can help prevent common mistakes, such as transfers of ownership to\n * incorrect accounts, or to contracts that are unable to interact with the\n * permission system.\n *\n * The initial owner is specified at deployment time in the constructor for `Ownable`. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n    address private _pendingOwner;\n\n    event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Returns the address of the pending owner.\n     */\n    function pendingOwner() public view virtual returns (address) {\n        return _pendingOwner;\n    }\n\n    /**\n     * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n     * Can only be called by the current owner.\n     *\n     * Setting `newOwner` to the zero address is allowed; this can be used to cancel an initiated ownership transfer.\n     */\n    function transferOwnership(address newOwner) public virtual override onlyOwner {\n        _pendingOwner = newOwner;\n        emit OwnershipTransferStarted(owner(), newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual override {\n        delete _pendingOwner;\n        super._transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev The new owner accepts the ownership transfer.\n     */\n    function acceptOwnership() public virtual {\n        address sender = _msgSender();\n        if (pendingOwner() != sender) {\n            revert OwnableUnauthorizedAccount(sender);\n        }\n        _transferOwnership(sender);\n    }\n}\n"},"@openzeppelin/contracts/utils/Context.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n"},"@openzeppelin/contracts/utils/ReentrancyGuard.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at,\n * consider using {ReentrancyGuardTransient} instead.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n    // Booleans are more expensive than uint256 or any type that takes up a full\n    // word because each write operation emits an extra SLOAD to first read the\n    // slot's contents, replace the bits taken up by the boolean, and then write\n    // back. This is the compiler's defense against contract upgrades and\n    // pointer aliasing, and it cannot be disabled.\n\n    // The values being non-zero value makes deployment a bit more expensive,\n    // but in exchange the refund on every call to nonReentrant will be lower in\n    // amount. Since refunds are capped to a percentage of the total\n    // transaction's gas, it is best to keep them low in cases like this one, to\n    // increase the likelihood of the full refund coming into effect.\n    uint256 private constant NOT_ENTERED = 1;\n    uint256 private constant ENTERED = 2;\n\n    uint256 private _status;\n\n    /**\n     * @dev Unauthorized reentrant call.\n     */\n    error ReentrancyGuardReentrantCall();\n\n    constructor() {\n        _status = NOT_ENTERED;\n    }\n\n    /**\n     * @dev Prevents a contract from calling itself, directly or indirectly.\n     * Calling a `nonReentrant` function from another `nonReentrant`\n     * function is not supported. It is possible to prevent this from happening\n     * by making the `nonReentrant` function external, and making it call a\n     * `private` function that does the actual work.\n     */\n    modifier nonReentrant() {\n        _nonReentrantBefore();\n        _;\n        _nonReentrantAfter();\n    }\n\n    function _nonReentrantBefore() private {\n        // On the first call to nonReentrant, _status will be NOT_ENTERED\n        if (_status == ENTERED) {\n            revert ReentrancyGuardReentrantCall();\n        }\n\n        // Any calls to nonReentrant after this point will fail\n        _status = ENTERED;\n    }\n\n    function _nonReentrantAfter() private {\n        // By storing the original value once again, a refund is triggered (see\n        // https://eips.ethereum.org/EIPS/eip-2200)\n        _status = NOT_ENTERED;\n    }\n\n    /**\n     * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n     * `nonReentrant` function in the call stack.\n     */\n    function _reentrancyGuardEntered() internal view returns (bool) {\n        return _status == ENTERED;\n    }\n}\n"},"contracts/interfaces/IGenericTimelock.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\n/// @title IGenericTimelock\n/// @notice Events and errors emitted by GenericTimelock. Split out so external\n///         monitors, indexers, and other contracts can reference the shapes\n///         without importing the full implementation.\ninterface IGenericTimelock {\n    // ============ Events ============\n\n    /// @notice Emitted on constructor init (previousDelay == 0) and when a\n    ///         previously-scheduled delay change is applied by executeDelayChange.\n    event DelayUpdated(uint256 previousDelay, uint256 newDelay);\n\n    /// @notice Emitted when a delay change is scheduled by the owner.\n    /// @param newDelay The delay that will be applied once eta is reached.\n    /// @param eta Earliest timestamp at which executeDelayChange can succeed\n    ///        (block.timestamp + current delay).\n    event DelayChangeScheduled(uint256 indexed newDelay, uint256 eta);\n\n    /// @notice Emitted when a pending delay change is cancelled before execute.\n    event DelayChangeCancelled(uint256 pendingDelay);\n\n    /// @notice Emitted when a call is queued for delayed execution.\n    event OperationQueued(\n        bytes32 indexed opHash,\n        address indexed target,\n        uint256 value,\n        string signature,\n        bytes data,\n        uint256 eta\n    );\n\n    /// @notice Emitted after a queued operation is successfully executed.\n    event OperationExecuted(\n        bytes32 indexed opHash,\n        address indexed target,\n        uint256 value,\n        string signature,\n        bytes data,\n        bytes returnData\n    );\n\n    /// @notice Emitted when a queued operation is cancelled (before or after expiry).\n    event OperationCancelled(bytes32 indexed opHash);\n\n    // ============ Errors ============\n\n    /// @notice Given delay is outside [MIN_DELAY, MAX_DELAY].\n    error DelayOutOfBounds(uint256 given, uint256 min, uint256 max);\n\n    /// @notice queue: `eta` must be at least `block.timestamp + delay`.\n    error EtaTooSoon(uint256 eta, uint256 minEta);\n\n    /// @notice Cannot queue: the identical operation is already queued.\n    error OperationAlreadyQueued(bytes32 opHash);\n\n    /// @notice Cannot execute/cancel: no such operation is currently queued.\n    error OperationNotQueued(bytes32 opHash);\n\n    /// @notice execute: current time has not yet reached `eta`.\n    error OperationNotReady(uint256 eta, uint256 nowTs);\n\n    /// @notice execute: current time is past `eta + GRACE_PERIOD`.\n    error OperationExpired(uint256 eta, uint256 gracePeriodEnd, uint256 nowTs);\n\n    /// @notice execute: `msg.value` did not match the value queued for this op.\n    error ValueMismatch(uint256 given, uint256 expected);\n\n    /// @notice executeDelayChange / cancelDelayChange: no pending delay change.\n    error NoPendingDelayChange();\n\n    /// @notice scheduleDelayChange: a delay change is already queued.\n    ///         Cancel it before scheduling a new one.\n    error DelayChangeAlreadyPending(uint256 pendingDelay, uint256 pendingEta);\n\n    /// @notice executeDelayChange: current time has not yet reached the pending\n    ///         delay change's eta. Distinct from OperationNotReady so decoders\n    ///         attribute the revert to delay administration, not the op pipeline.\n    error DelayChangeNotReady(uint256 eta, uint256 nowTs);\n\n    /// @notice execute: the forwarded target call reverted. `returnData` is the\n    ///         raw revert payload — decode it with the target contract's ABI.\n    error CallReverted(bytes returnData);\n\n    // (NotSelf was removed — setDelay is no longer routed through queue/execute;\n    //  the dedicated schedule/execute/cancel functions above have the logic\n    //  directly.)\n}\n"},"contracts/periphery/GenericTimelock.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"../interfaces/IGenericTimelock.sol\";\n\n/// @title GenericTimelock\n/// @notice Queues arbitrary (target, value, signature, data, eta) calls and\n///         executes them after a configurable delay. The owner can queue,\n///         execute, and cancel operations. Every executed call is forwarded\n///         from this contract's context, so target contracts that gate on\n///         `msg.sender == address(this timelock)` are supported.\n///\n/// Delay guarantees an integrator should reason about:\n///   - MIN_DELAY = 2 days. Hard floor on every operation; no configuration\n///     can go below it.\n///   - Changing the delay is a dedicated two-step flow with the delay itself\n///     applied to the change: scheduleDelayChange(newDelay) records the\n///     request, executeDelayChange() applies it once the CURRENT delay has\n///     elapsed since scheduling. Reducing the delay from N to M thus takes\n///     at least N seconds. A compromised owner cannot instantly drop the\n///     delay to accelerate a follow-up attack.\n///   - Ownership rotation on this contract uses Ownable2Step (transfer +\n///     accept) but is NOT timelocked; who operates the timelock is\n///     considered a governance-level decision, not an on-chain action the\n///     timelock guards against itself.\ncontract GenericTimelock is Ownable2Step, ReentrancyGuard, IGenericTimelock {\n    // ============ Constants ============\n\n    /// @notice Minimum acceptable delay between queue and execute.\n    uint256 public constant MIN_DELAY = 2 days;\n\n    /// @notice Maximum acceptable delay between queue and execute.\n    uint256 public constant MAX_DELAY = 30 days;\n\n    /// @notice Window after `eta` during which an execution is still accepted.\n    ///         Past this, `execute` reverts `OperationExpired`. The queued\n    ///         flag remains set for the expired opHash but has no on-chain\n    ///         effect — that opHash can never execute (eta is in the past)\n    ///         and cannot be re-queued (same eta trips `EtaTooSoon`).\n    ///         To retry the operation, queue it again with a fresh `eta`;\n    ///         the new opHash is independent.\n    uint256 public constant GRACE_PERIOD = 14 days;\n\n    // ============ Storage ============\n\n    /// @notice Current queue-to-execute delay.\n    uint256 public delay;\n\n    /// @notice Pending delay change (0 if none scheduled).\n    uint256 public pendingDelay;\n\n    /// @notice Earliest timestamp at which the pending delay change may be\n    ///         executed. 0 iff no change is pending.\n    uint256 public pendingDelayEta;\n\n    /// @notice opHash => queued flag. True once queued, false after execute/cancel.\n    mapping(bytes32 => bool) public queued;\n\n    // ============ Constructor ============\n\n    /// @param initialOwner Address that can queue / execute / cancel operations\n    ///        and scheduleDelayChange / executeDelayChange / cancelDelayChange\n    ///        the delay itself.\n    /// @param initialDelay Delay in seconds; must satisfy MIN_DELAY <= x <= MAX_DELAY.\n    constructor(address initialOwner, uint256 initialDelay) Ownable(initialOwner) {\n        if (initialDelay < MIN_DELAY || initialDelay > MAX_DELAY) {\n            revert DelayOutOfBounds(initialDelay, MIN_DELAY, MAX_DELAY);\n        }\n        delay = initialDelay;\n        emit DelayUpdated(0, initialDelay);\n    }\n\n    // ============ Delay management (self-timelocked, explicit two-step) ============\n\n    /// @notice Schedule a change to the timelock delay. The change cannot be\n    ///         applied until the CURRENT delay has elapsed since scheduling —\n    ///         so reducing the delay takes at least the current delay.\n    /// @param newDelay New delay in seconds. Must be in [MIN_DELAY, MAX_DELAY].\n    /// @dev At most one delay change can be pending at a time. Use\n    ///      cancelDelayChange first to replace a pending one.\n    function scheduleDelayChange(uint256 newDelay) external onlyOwner {\n        if (newDelay < MIN_DELAY || newDelay > MAX_DELAY) {\n            revert DelayOutOfBounds(newDelay, MIN_DELAY, MAX_DELAY);\n        }\n        if (pendingDelayEta != 0) {\n            revert DelayChangeAlreadyPending(pendingDelay, pendingDelayEta);\n        }\n        uint256 eta = block.timestamp + delay;\n        pendingDelay = newDelay;\n        pendingDelayEta = eta;\n        emit DelayChangeScheduled(newDelay, eta);\n    }\n\n    /// @notice Apply the pending delay change once the CURRENT delay has elapsed.\n    /// @dev Only affects operations queued AFTER this call; already-queued ops\n    ///      keep their original `eta`.\n    function executeDelayChange() external onlyOwner {\n        uint256 eta = pendingDelayEta;\n        if (eta == 0) revert NoPendingDelayChange();\n        if (block.timestamp < eta) revert DelayChangeNotReady(eta, block.timestamp);\n\n        uint256 previousDelay = delay;\n        uint256 newDelay = pendingDelay;\n        delay = newDelay;\n        delete pendingDelay;\n        delete pendingDelayEta;\n        emit DelayUpdated(previousDelay, newDelay);\n    }\n\n    /// @notice Cancel a pending delay change before it is executed.\n    function cancelDelayChange() external onlyOwner {\n        if (pendingDelayEta == 0) revert NoPendingDelayChange();\n        uint256 cancelledDelay = pendingDelay;\n        delete pendingDelay;\n        delete pendingDelayEta;\n        emit DelayChangeCancelled(cancelledDelay);\n    }\n\n    // ============ Queue / Execute / Cancel ============\n\n    /// @notice Queue an operation for later execution.\n    /// @param target Contract to call.\n    /// @param value ETH to send with the call. `msg.value` at `execute` time must equal this.\n    /// @param signature Textual function signature (e.g. \"setFoo(uint256)\"). Pass empty\n    ///        string to treat `data` as raw calldata.\n    /// @param data ABI-encoded arguments (without the 4-byte selector) when `signature` is\n    ///        non-empty, else raw calldata.\n    /// @param eta Earliest timestamp at which the operation may execute. Must satisfy\n    ///        `eta >= block.timestamp + delay` at queue time.\n    /// @return opHash Unique identifier for this operation.\n    function queue(\n        address target,\n        uint256 value,\n        string calldata signature,\n        bytes calldata data,\n        uint256 eta\n    ) external onlyOwner returns (bytes32 opHash) {\n        uint256 minEta = block.timestamp + delay;\n        if (eta < minEta) revert EtaTooSoon(eta, minEta);\n\n        opHash = hashOperation(target, value, signature, data, eta);\n        if (queued[opHash]) revert OperationAlreadyQueued(opHash);\n        queued[opHash] = true;\n\n        emit OperationQueued(opHash, target, value, signature, data, eta);\n    }\n\n    /// @notice Cancel a queued operation. Callable at any time before execute.\n    ///         Also callable on an already-expired op, but this only clears\n    ///         a mapping entry that has no effect either way — the expired\n    ///         opHash can already never execute and can never be re-queued.\n    /// @param target Same as `queue`.\n    /// @param value Same as `queue`.\n    /// @param signature Same as `queue`.\n    /// @param data Same as `queue`.\n    /// @param eta Same as `queue`.\n    function cancel(\n        address target,\n        uint256 value,\n        string calldata signature,\n        bytes calldata data,\n        uint256 eta\n    ) external onlyOwner {\n        bytes32 opHash = hashOperation(target, value, signature, data, eta);\n        if (!queued[opHash]) revert OperationNotQueued(opHash);\n        delete queued[opHash];\n        emit OperationCancelled(opHash);\n    }\n\n    /// @notice Execute a queued operation once its `eta` has passed and before\n    ///         `eta + GRACE_PERIOD`.\n    /// @param target Same as `queue`.\n    /// @param value Same as `queue`. `msg.value` must equal this exactly.\n    /// @param signature Same as `queue`.\n    /// @param data Same as `queue`.\n    /// @param eta Same as `queue`.\n    /// @return returnData Raw return data from the underlying target call.\n    function execute(\n        address target,\n        uint256 value,\n        string calldata signature,\n        bytes calldata data,\n        uint256 eta\n    ) external payable onlyOwner nonReentrant returns (bytes memory returnData) {\n        bytes32 opHash = hashOperation(target, value, signature, data, eta);\n        if (!queued[opHash]) revert OperationNotQueued(opHash);\n        if (block.timestamp < eta) revert OperationNotReady(eta, block.timestamp);\n        uint256 gracePeriodEnd = eta + GRACE_PERIOD;\n        if (block.timestamp > gracePeriodEnd) {\n            revert OperationExpired(eta, gracePeriodEnd, block.timestamp);\n        }\n        if (msg.value != value) revert ValueMismatch(msg.value, value);\n\n        delete queued[opHash];\n\n        bytes memory callData = _buildCalldata(signature, data);\n        bool ok;\n        (ok, returnData) = target.call{value: value}(callData);\n        if (!ok) revert CallReverted(returnData);\n\n        emit OperationExecuted(opHash, target, value, signature, data, returnData);\n    }\n\n    // ============ Views ============\n\n    /// @notice Deterministic identifier for an operation. Two operations with\n    ///         identical params share the same hash and cannot be queued\n    ///         simultaneously.\n    function hashOperation(\n        address target,\n        uint256 value,\n        string calldata signature,\n        bytes calldata data,\n        uint256 eta\n    ) public pure returns (bytes32) {\n        return keccak256(abi.encode(target, value, signature, data, eta));\n    }\n\n    /// @notice Preview the exact bytes forwarded to `target` at execute time.\n    function buildCalldata(\n        string calldata signature,\n        bytes calldata data\n    ) external pure returns (bytes memory) {\n        return _buildCalldata(signature, data);\n    }\n\n    // ============ Internal ============\n\n    function _buildCalldata(\n        string calldata signature,\n        bytes calldata data\n    ) internal pure returns (bytes memory) {\n        if (bytes(signature).length == 0) return data;\n        return bytes.concat(bytes4(keccak256(bytes(signature))), data);\n    }\n\n    // Intentionally no receive/fallback: this contract does not spend from\n    // its own balance. All ETH for value>0 executions must be supplied via\n    // `msg.value` at `execute` time.\n}\n"}},"abi":[{"type":"constructor","inputs":[{"name":"initialOwner","type":"address","internalType":"address"},{"name":"initialDelay","type":"uint256","internalType":"uint256"}],"stateMutability":"nonpayable"},{"name":"CallReverted","type":"error","inputs":[{"name":"returnData","type":"bytes","internalType":"bytes"}]},{"name":"DelayChangeAlreadyPending","type":"error","inputs":[{"name":"pendingDelay","type":"uint256","internalType":"uint256"},{"name":"pendingEta","type":"uint256","internalType":"uint256"}]},{"name":"DelayChangeNotReady","type":"error","inputs":[{"name":"eta","type":"uint256","internalType":"uint256"},{"name":"nowTs","type":"uint256","internalType":"uint256"}]},{"name":"DelayOutOfBounds","type":"error","inputs":[{"name":"given","type":"uint256","internalType":"uint256"},{"name":"min","type":"uint256","internalType":"uint256"},{"name":"max","type":"uint256","internalType":"uint256"}]},{"name":"EtaTooSoon","type":"error","inputs":[{"name":"eta","type":"uint256","internalType":"uint256"},{"name":"minEta","type":"uint256","internalType":"uint256"}]},{"name":"NoPendingDelayChange","type":"error","inputs":[]},{"name":"OperationAlreadyQueued","type":"error","inputs":[{"name":"opHash","type":"bytes32","internalType":"bytes32"}]},{"name":"OperationExpired","type":"error","inputs":[{"name":"eta","type":"uint256","internalType":"uint256"},{"name":"gracePeriodEnd","type":"uint256","internalType":"uint256"},{"name":"nowTs","type":"uint256","internalType":"uint256"}]},{"name":"OperationNotQueued","type":"error","inputs":[{"name":"opHash","type":"bytes32","internalType":"bytes32"}]},{"name":"OperationNotReady","type":"error","inputs":[{"name":"eta","type":"uint256","internalType":"uint256"},{"name":"nowTs","type":"uint256","internalType":"uint256"}]},{"name":"OwnableInvalidOwner","type":"error","inputs":[{"name":"owner","type":"address","internalType":"address"}]},{"name":"OwnableUnauthorizedAccount","type":"error","inputs":[{"name":"account","type":"address","internalType":"address"}]},{"name":"ReentrancyGuardReentrantCall","type":"error","inputs":[]},{"name":"ValueMismatch","type":"error","inputs":[{"name":"given","type":"uint256","internalType":"uint256"},{"name":"expected","type":"uint256","internalType":"uint256"}]},{"name":"DelayChangeCancelled","type":"event","inputs":[{"name":"pendingDelay","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"DelayChangeScheduled","type":"event","inputs":[{"name":"newDelay","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"eta","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"DelayUpdated","type":"event","inputs":[{"name":"previousDelay","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"newDelay","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"OperationCancelled","type":"event","inputs":[{"name":"opHash","type":"bytes32","indexed":true,"internalType":"bytes32"}],"anonymous":false},{"name":"OperationExecuted","type":"event","inputs":[{"name":"opHash","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"target","type":"address","indexed":true,"internalType":"address"},{"name":"value","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"signature","type":"string","indexed":false,"internalType":"string"},{"name":"data","type":"bytes","indexed":false,"internalType":"bytes"},{"name":"returnData","type":"bytes","indexed":false,"internalType":"bytes"}],"anonymous":false},{"name":"OperationQueued","type":"event","inputs":[{"name":"opHash","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"target","type":"address","indexed":true,"internalType":"address"},{"name":"value","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"signature","type":"string","indexed":false,"internalType":"string"},{"name":"data","type":"bytes","indexed":false,"internalType":"bytes"},{"name":"eta","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"OwnershipTransferStarted","type":"event","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"OwnershipTransferred","type":"event","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"GRACE_PERIOD","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"MAX_DELAY","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"MIN_DELAY","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"acceptOwnership","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"buildCalldata","type":"function","inputs":[{"name":"signature","type":"string","internalType":"string"},{"name":"data","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"","type":"bytes","internalType":"bytes"}],"stateMutability":"pure"},{"name":"cancel","type":"function","inputs":[{"name":"target","type":"address","internalType":"address"},{"name":"value","type":"uint256","internalType":"uint256"},{"name":"signature","type":"string","internalType":"string"},{"name":"data","type":"bytes","internalType":"bytes"},{"name":"eta","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"cancelDelayChange","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"delay","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"execute","type":"function","inputs":[{"name":"target","type":"address","internalType":"address"},{"name":"value","type":"uint256","internalType":"uint256"},{"name":"signature","type":"string","internalType":"string"},{"name":"data","type":"bytes","internalType":"bytes"},{"name":"eta","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"returnData","type":"bytes","internalType":"bytes"}],"stateMutability":"payable"},{"name":"executeDelayChange","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"hashOperation","type":"function","inputs":[{"name":"target","type":"address","internalType":"address"},{"name":"value","type":"uint256","internalType":"uint256"},{"name":"signature","type":"string","internalType":"string"},{"name":"data","type":"bytes","internalType":"bytes"},{"name":"eta","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"pure"},{"name":"owner","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"pendingDelay","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"pendingDelayEta","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"pendingOwner","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"queue","type":"function","inputs":[{"name":"target","type":"address","internalType":"address"},{"name":"value","type":"uint256","internalType":"uint256"},{"name":"signature","type":"string","internalType":"string"},{"name":"data","type":"bytes","internalType":"bytes"},{"name":"eta","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"opHash","type":"bytes32","internalType":"bytes32"}],"stateMutability":"nonpayable"},{"name":"queued","type":"function","inputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"renounceOwnership","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"scheduleDelayChange","type":"function","inputs":[{"name":"newDelay","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"transferOwnership","type":"function","inputs":[{"name":"newOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"}],"metadata":{"compiler":{"version":"0.8.28+commit.7893614a"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"address","name":"initialOwner","type":"address"},{"internalType":"uint256","name":"initialDelay","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"bytes","name":"returnData","type":"bytes"}],"name":"CallReverted","type":"error"},{"inputs":[{"internalType":"uint256","name":"pendingDelay","type":"uint256"},{"internalType":"uint256","name":"pendingEta","type":"uint256"}],"name":"DelayChangeAlreadyPending","type":"error"},{"inputs":[{"internalType":"uint256","name":"eta","type":"uint256"},{"internalType":"uint256","name":"nowTs","type":"uint256"}],"name":"DelayChangeNotReady","type":"error"},{"inputs":[{"internalType":"uint256","name":"given","type":"uint256"},{"internalType":"uint256","name":"min","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"name":"DelayOutOfBounds","type":"error"},{"inputs":[{"internalType":"uint256","name":"eta","type":"uint256"},{"internalType":"uint256","name":"minEta","type":"uint256"}],"name":"EtaTooSoon","type":"error"},{"inputs":[],"name":"NoPendingDelayChange","type":"error"},{"inputs":[{"internalType":"bytes32","name":"opHash","type":"bytes32"}],"name":"OperationAlreadyQueued","type":"error"},{"inputs":[{"internalType":"uint256","name":"eta","type":"uint256"},{"internalType":"uint256","name":"gracePeriodEnd","type":"uint256"},{"internalType":"uint256","name":"nowTs","type":"uint256"}],"name":"OperationExpired","type":"error"},{"inputs":[{"internalType":"bytes32","name":"opHash","type":"bytes32"}],"name":"OperationNotQueued","type":"error"},{"inputs":[{"internalType":"uint256","name":"eta","type":"uint256"},{"internalType":"uint256","name":"nowTs","type":"uint256"}],"name":"OperationNotReady","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[{"internalType":"uint256","name":"given","type":"uint256"},{"internalType":"uint256","name":"expected","type":"uint256"}],"name":"ValueMismatch","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"pendingDelay","type":"uint256"}],"name":"DelayChangeCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"newDelay","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"eta","type":"uint256"}],"name":"DelayChangeScheduled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"previousDelay","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newDelay","type":"uint256"}],"name":"DelayUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"opHash","type":"bytes32"}],"name":"OperationCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"opHash","type":"bytes32"},{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"string","name":"signature","type":"string"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"returnData","type":"bytes"}],"name":"OperationExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"opHash","type":"bytes32"},{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"string","name":"signature","type":"string"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"eta","type":"uint256"}],"name":"OperationQueued","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"GRACE_PERIOD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_DELAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_DELAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"signature","type":"string"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"buildCalldata","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"string","name":"signature","type":"string"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"eta","type":"uint256"}],"name":"cancel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cancelDelayChange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"delay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"string","name":"signature","type":"string"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"eta","type":"uint256"}],"name":"execute","outputs":[{"internalType":"bytes","name":"returnData","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"executeDelayChange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"string","name":"signature","type":"string"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"eta","type":"uint256"}],"name":"hashOperation","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingDelayEta","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"string","name":"signature","type":"string"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"eta","type":"uint256"}],"name":"queue","outputs":[{"internalType":"bytes32","name":"opHash","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"queued","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newDelay","type":"uint256"}],"name":"scheduleDelayChange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"errors":{"OwnableInvalidOwner(address)":[{"details":"The owner is not a valid owner account. (eg. `address(0)`)"}],"OwnableUnauthorizedAccount(address)":[{"details":"The caller account is not authorized to perform an operation."}],"ReentrancyGuardReentrantCall()":[{"details":"Unauthorized reentrant call."}]},"events":{"DelayChangeScheduled(uint256,uint256)":{"params":{"eta":"Earliest timestamp at which executeDelayChange can succeed        (block.timestamp + current delay).","newDelay":"The delay that will be applied once eta is reached."}}},"kind":"dev","methods":{"acceptOwnership()":{"details":"The new owner accepts the ownership transfer."},"cancel(address,uint256,string,bytes,uint256)":{"params":{"data":"Same as `queue`.","eta":"Same as `queue`.","signature":"Same as `queue`.","target":"Same as `queue`.","value":"Same as `queue`."}},"constructor":{"params":{"initialDelay":"Delay in seconds; must satisfy MIN_DELAY <= x <= MAX_DELAY.","initialOwner":"Address that can queue / execute / cancel operations        and scheduleDelayChange / executeDelayChange / cancelDelayChange        the delay itself."}},"execute(address,uint256,string,bytes,uint256)":{"params":{"data":"Same as `queue`.","eta":"Same as `queue`.","signature":"Same as `queue`.","target":"Same as `queue`.","value":"Same as `queue`. `msg.value` must equal this exactly."},"returns":{"returnData":"Raw return data from the underlying target call."}},"executeDelayChange()":{"details":"Only affects operations queued AFTER this call; already-queued ops      keep their original `eta`."},"owner()":{"details":"Returns the address of the current owner."},"pendingOwner()":{"details":"Returns the address of the pending owner."},"queue(address,uint256,string,bytes,uint256)":{"params":{"data":"ABI-encoded arguments (without the 4-byte selector) when `signature` is        non-empty, else raw calldata.","eta":"Earliest timestamp at which the operation may execute. Must satisfy        `eta >= block.timestamp + delay` at queue time.","signature":"Textual function signature (e.g. \"setFoo(uint256)\"). Pass empty        string to treat `data` as raw calldata.","target":"Contract to call.","value":"ETH to send with the call. `msg.value` at `execute` time must equal this."},"returns":{"opHash":"Unique identifier for this operation."}},"renounceOwnership()":{"details":"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."},"scheduleDelayChange(uint256)":{"details":"At most one delay change can be pending at a time. Use      cancelDelayChange first to replace a pending one.","params":{"newDelay":"New delay in seconds. Must be in [MIN_DELAY, MAX_DELAY]."}},"transferOwnership(address)":{"details":"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. Setting `newOwner` to the zero address is allowed; this can be used to cancel an initiated ownership transfer."}},"title":"GenericTimelock","version":1},"userdoc":{"errors":{"CallReverted(bytes)":[{"notice":"execute: the forwarded target call reverted. `returnData` is the         raw revert payload — decode it with the target contract's ABI."}],"DelayChangeAlreadyPending(uint256,uint256)":[{"notice":"scheduleDelayChange: a delay change is already queued.         Cancel it before scheduling a new one."}],"DelayChangeNotReady(uint256,uint256)":[{"notice":"executeDelayChange: current time has not yet reached the pending         delay change's eta. Distinct from OperationNotReady so decoders         attribute the revert to delay administration, not the op pipeline."}],"DelayOutOfBounds(uint256,uint256,uint256)":[{"notice":"Given delay is outside [MIN_DELAY, MAX_DELAY]."}],"EtaTooSoon(uint256,uint256)":[{"notice":"queue: `eta` must be at least `block.timestamp + delay`."}],"NoPendingDelayChange()":[{"notice":"executeDelayChange / cancelDelayChange: no pending delay change."}],"OperationAlreadyQueued(bytes32)":[{"notice":"Cannot queue: the identical operation is already queued."}],"OperationExpired(uint256,uint256,uint256)":[{"notice":"execute: current time is past `eta + GRACE_PERIOD`."}],"OperationNotQueued(bytes32)":[{"notice":"Cannot execute/cancel: no such operation is currently queued."}],"OperationNotReady(uint256,uint256)":[{"notice":"execute: current time has not yet reached `eta`."}],"ValueMismatch(uint256,uint256)":[{"notice":"execute: `msg.value` did not match the value queued for this op."}]},"events":{"DelayChangeCancelled(uint256)":{"notice":"Emitted when a pending delay change is cancelled before execute."},"DelayChangeScheduled(uint256,uint256)":{"notice":"Emitted when a delay change is scheduled by the owner."},"DelayUpdated(uint256,uint256)":{"notice":"Emitted on constructor init (previousDelay == 0) and when a         previously-scheduled delay change is applied by executeDelayChange."},"OperationCancelled(bytes32)":{"notice":"Emitted when a queued operation is cancelled (before or after expiry)."},"OperationExecuted(bytes32,address,uint256,string,bytes,bytes)":{"notice":"Emitted after a queued operation is successfully executed."},"OperationQueued(bytes32,address,uint256,string,bytes,uint256)":{"notice":"Emitted when a call is queued for delayed execution."}},"kind":"user","methods":{"GRACE_PERIOD()":{"notice":"Window after `eta` during which an execution is still accepted.         Past this, `execute` reverts `OperationExpired`. The queued         flag remains set for the expired opHash but has no on-chain         effect — that opHash can never execute (eta is in the past)         and cannot be re-queued (same eta trips `EtaTooSoon`).         To retry the operation, queue it again with a fresh `eta`;         the new opHash is independent."},"MAX_DELAY()":{"notice":"Maximum acceptable delay between queue and execute."},"MIN_DELAY()":{"notice":"Minimum acceptable delay between queue and execute."},"buildCalldata(string,bytes)":{"notice":"Preview the exact bytes forwarded to `target` at execute time."},"cancel(address,uint256,string,bytes,uint256)":{"notice":"Cancel a queued operation. Callable at any time before execute.         Also callable on an already-expired op, but this only clears         a mapping entry that has no effect either way — the expired         opHash can already never execute and can never be re-queued."},"cancelDelayChange()":{"notice":"Cancel a pending delay change before it is executed."},"delay()":{"notice":"Current queue-to-execute delay."},"execute(address,uint256,string,bytes,uint256)":{"notice":"Execute a queued operation once its `eta` has passed and before         `eta + GRACE_PERIOD`."},"executeDelayChange()":{"notice":"Apply the pending delay change once the CURRENT delay has elapsed."},"hashOperation(address,uint256,string,bytes,uint256)":{"notice":"Deterministic identifier for an operation. Two operations with         identical params share the same hash and cannot be queued         simultaneously."},"pendingDelay()":{"notice":"Pending delay change (0 if none scheduled)."},"pendingDelayEta()":{"notice":"Earliest timestamp at which the pending delay change may be         executed. 0 iff no change is pending."},"queue(address,uint256,string,bytes,uint256)":{"notice":"Queue an operation for later execution."},"queued(bytes32)":{"notice":"opHash => queued flag. True once queued, false after execute/cancel."},"scheduleDelayChange(uint256)":{"notice":"Schedule a change to the timelock delay. The change cannot be         applied until the CURRENT delay has elapsed since scheduling —         so reducing the delay takes at least the current delay."}},"notice":"Queues arbitrary (target, value, signature, data, eta) calls and         executes them after a configurable delay. The owner can queue,         execute, and cancel operations. Every executed call is forwarded         from this contract's context, so target contracts that gate on         `msg.sender == address(this timelock)` are supported. Delay guarantees an integrator should reason about:   - MIN_DELAY = 2 days. Hard floor on every operation; no configuration     can go below it.   - Changing the delay is a dedicated two-step flow with the delay itself     applied to the change: scheduleDelayChange(newDelay) records the     request, executeDelayChange() applies it once the CURRENT delay has     elapsed since scheduling. Reducing the delay from N to M thus takes     at least N seconds. A compromised owner cannot instantly drop the     delay to accelerate a follow-up attack.   - Ownership rotation on this contract uses Ownable2Step (transfer +     accept) but is NOT timelocked; who operates the timelock is     considered a governance-level decision, not an on-chain action the     timelock guards against itself.","version":1}},"settings":{"compilationTarget":{"contracts/periphery/GenericTimelock.sol":"GenericTimelock"},"evmVersion":"paris","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":true,"runs":100},"remappings":[]},"sources":{"@openzeppelin/contracts/access/Ownable.sol":{"keccak256":"0xff6d0bb2e285473e5311d9d3caacb525ae3538a80758c10649a4d61029b017bb","license":"MIT","urls":["bzz-raw://8ed324d3920bb545059d66ab97d43e43ee85fd3bd52e03e401f020afb0b120f6","dweb:/ipfs/QmfEckWLmZkDDcoWrkEvMWhms66xwTLff9DDhegYpvHo1a"]},"@openzeppelin/contracts/access/Ownable2Step.sol":{"keccak256":"0xdcad8898fda432696597752e8ec361b87d85c82cb258115427af006dacf7128c","license":"MIT","urls":["bzz-raw://e2c9d517f0c136d54bd00cd57959d25681d4d6273f5bbbc263afe228303772f0","dweb:/ipfs/QmReNFjXBiufByiAAzfSQ2SM5r3qeUErn46BmN3yVRvrek"]},"@openzeppelin/contracts/utils/Context.sol":{"keccak256":"0x493033a8d1b176a037b2cc6a04dad01a5c157722049bbecf632ca876224dd4b2","license":"MIT","urls":["bzz-raw://6a708e8a5bdb1011c2c381c9a5cfd8a9a956d7d0a9dc1bd8bcdaf52f76ef2f12","dweb:/ipfs/Qmax9WHBnVsZP46ZxEMNRQpLQnrdE4dK8LehML1Py8FowF"]},"@openzeppelin/contracts/utils/ReentrancyGuard.sol":{"keccak256":"0x11a5a79827df29e915a12740caf62fe21ebe27c08c9ae3e09abe9ee3ba3866d3","license":"MIT","urls":["bzz-raw://3cf0c69ab827e3251db9ee6a50647d62c90ba580a4d7bbff21f2bea39e7b2f4a","dweb:/ipfs/QmZiKwtKU1SBX4RGfQtY7PZfiapbbu6SZ9vizGQD9UHjRA"]},"contracts/interfaces/IGenericTimelock.sol":{"keccak256":"0x3ef5df9338d2ea1a2fb93700c5f23551832e48580086c5438c652e4be24e73e0","license":"MIT","urls":["bzz-raw://f77b37cfdcfe92b56d01366a9a82712c760fd477967e7e0a7dc089d63c384833","dweb:/ipfs/QmbuFgZzS8eo1qf7ooNez3dp9Z2hFPCxFufVBkFg7NfKHT"]},"contracts/periphery/GenericTimelock.sol":{"keccak256":"0x0a2cb460b06ad5be4f8964f589977aa44c7342a508dc16371d7c26222f7b0a02","license":"MIT","urls":["bzz-raw://442e7501c591ef8bb3bd15e468b965712b21dcdef94332d812ea44a23055bd6b","dweb:/ipfs/QmYBMGphA2nWL4Zabx3DBqyDoUgfYnsbBYBDQHnjodhEym"]}},"version":1},"matchId":"42968173","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-07-28T10:54:16Z","match":"exact_match","chainId":"1","address":"0x36857EF0B10A61A68d58C29eE256990fa9699722"}