Skip to main content

TimelockBatchQueue

Git Source

Inherits: ITimelockBatchQueue, ERC165

Title: TimelockBatchQueue

Reusable queue implementation for atomic batched timelocked actions.

Every queued action is a batch of one or more BatchAction sub-actions. A batch of length one behaves like a single timelocked action. Batches are atomic by construction: a revert in any sub-action validator or executor rolls back the entire batch.

Sub-actions execute in array order within a batch, but no ordering is enforced across separately queued actions: execution is permissionless once a timelock elapses, so independently queued batches may execute in any order. Actions with execution-order dependencies must be queued within a single batch.

Lifecycle:

  • _queueAction enforces the configured batch size bounds, calls _onSubActionQueued per sub-action and _onBatchQueued once for cross-sub invariants, stores the batch metadata and sub-actions, emits one TimelockSubActionQueued per sub-action, then emits TimelockActionQueued to close the batch.
  • executeQueuedAction validates standard executable state, delegates implementation-specific execution authorization to _validateExecution, marks the action executed, and runs the execution loop in the base contract: each iteration calls _executeSubAction and then emits TimelockSubActionExecuted, interleaving the per-sub event with any events emitted by the sub-action target. After the loop _onActionExecuted runs once, the stored sub-actions are cleared, and a single TimelockActionExecuted event is emitted.
  • cancelQueuedAction validates standard cancellable state, delegates implementation-specific cancellation authorization to _validateCancellation, clears the stored sub-actions, calls _onActionCancelled so derived contracts can clear per-sub-action state recorded at queue time, and emits TimelockActionCancelled.

Derived contracts must implement the virtual hooks by reverting on failure. Hooks should not return booleans; a successful return means the hook accepted the operation.

State Variables​

timelockDelay​

Current timelock delay in seconds.

uint48 public timelockDelay;

Returns

NameTypeDescription
<none>uint48

nextActionId​

Next queued action ID.

uint64 public nextActionId;

Returns

NameTypeDescription
<none>uint64

_queuedActions​

Queued timelock actions.

mapping(uint64 actionId => ITimelockBatchQueue.QueuedAction queuedAction)
internal _queuedActions;

Functions​

constructor​

Initialize the timelock queue.

Delegates to _setTimelockDelay, which calls the virtual _validateTimelockDelay. Derived implementations should ensure that override does not depend on derived-contract constructor-initialized storage.

constructor(uint48 initialTimelockDelay_);

Parameters

NameTypeDescription
initialTimelockDelay_uint48Initial timelock delay in seconds.

getQueuedAction​

Get a queued action.

Reverts if:

  • The action does not exist
function getQueuedAction(
uint64 actionId_
) external view returns (ITimelockBatchQueue.QueuedAction memory action);

Parameters

NameTypeDescription
actionId_uint64The queued action ID.

Returns

NameTypeDescription
actionITimelockBatchQueue.QueuedActionThe queued action.

getQueuedActionLength​

Get the number of sub-actions stored for a queued action.

Reverts if:

  • The action does not exist
  • The action has already been executed
  • The action has been cancelled
function getQueuedActionLength(uint64 actionId_) external view returns (uint256 length);

Parameters

NameTypeDescription
actionId_uint64The queued action ID.

Returns

NameTypeDescription
lengthuint256The number of sub-actions stored for the action.

getQueuedSubAction​

Get a single sub-action of a queued action.

Reverts if:

  • The action does not exist
  • The action has already been executed
  • The action has been cancelled
  • The sub-action index is out of bounds
function getQueuedSubAction(
uint64 actionId_,
uint256 index_
) external view returns (address target, bytes4 selector, bytes memory payload);

Parameters

NameTypeDescription
actionId_uint64The queued action ID.
index_uint256The sub-action index.

Returns

NameTypeDescription
targetaddressThe contract expected to receive the sub-action.
selectorbytes4The function selector for the sub-action.
payloadbytesEncoded parameters for the sub-action.

executeQueuedAction​

Reverts if:

  • The action does not exist
  • The action has already been executed
  • The action has been cancelled
  • The action is still timelocked (the block timestamp is before executableAt)
  • The action has expired (the block timestamp is past expiresAt, the last executable timestamp)
  • _validateExecution reverts
  • _executeSubAction reverts for any sub-action
  • _onActionExecuted reverts

In both _queueAction and execution the per-sub-action events precede the single action-level event that closes the batch. At execution time each TimelockSubActionExecuted is emitted inside the loop, immediately after the corresponding _executeSubAction call, so it interleaves with any events the sub-action target emits and the log preserves real execution order; TimelockActionExecuted is then emitted once after the loop. At queue time there is no nested call to interleave with, so the TimelockSubActionQueued events form a uniform group followed by TimelockActionQueued.

function executeQueuedAction(uint64 actionId_) external;

Parameters

NameTypeDescription
actionId_uint64The queued action ID.

cancelQueuedAction​

Cancel a queued action.

Reverts if:

  • The action does not exist
  • The action has already been executed
  • The action has been cancelled
  • _validateCancellation reverts
  • _onActionCancelled reverts
function cancelQueuedAction(uint64 actionId_) external;

Parameters

NameTypeDescription
actionId_uint64The queued action ID.

_queueAction​

Queue a batched timelocked action.

Calls _onSubActionQueued per sub-action and _onBatchQueued once after, so derived contracts cannot use this helper without passing their implementation specific authorization and payload checks.

Reverts if:

  • The batch is empty
  • The batch exceeds _maxBatchSize()
  • _onSubActionQueued reverts for any sub-action
  • _onBatchQueued reverts
function _queueAction(
ITimelockBatchQueue.BatchAction[] memory actions_
) internal returns (uint64 actionId);

Parameters

NameTypeDescription
actions_ITimelockBatchQueue.BatchAction[]The sub-actions of the batch.

Returns

NameTypeDescription
actionIduint64The queued action ID.

_queueAction​

Queue a single timelocked action.

Convenience wrapper that forwards a single (target, selector, payload) triple as a length-1 batch and delegates to the batch overload. The derived contract's _onSubActionQueued hook is invoked once and _onBatchQueued is invoked once with a length-1 array.

function _queueAction(
address target_,
bytes4 selector_,
bytes memory payload_
) internal returns (uint64 actionId);

Parameters

NameTypeDescription
target_addressThe contract expected to receive the queued action.
selector_bytes4The function selector for the queued action.
payload_bytesEncoded parameters for the action.

Returns

NameTypeDescription
actionIduint64The queued action ID.

_setTimelockDelay​

Set the timelock delay.

Reverts if _validateTimelockDelay rejects the new delay.

function _setTimelockDelay(uint48 delay_) internal;

Parameters

NameTypeDescription
delay_uint48The new timelock delay in seconds.

_validateExecutableState​

Validate standard executable state for a queued action.

Reverts on failure. The action is executable at any block timestamp in the closed window [executableAt, expiresAt]: expiresAt is the last executable timestamp, inclusive, and the action is expired only once the block timestamp is past it.

function _validateExecutableState(
uint64 actionId_,
ITimelockBatchQueue.QueuedAction storage action_
) internal view;

Parameters

NameTypeDescription
actionId_uint64The queued action ID.
action_ITimelockBatchQueue.QueuedActionThe queued action storage reference.

_validateCancellableState​

Validate standard cancellable state for a queued action.

Reverts on failure.

function _validateCancellableState(
uint64 actionId_,
ITimelockBatchQueue.QueuedAction storage action_
) internal view;

Parameters

NameTypeDescription
actionId_uint64The queued action ID.
action_ITimelockBatchQueue.QueuedActionThe queued action storage reference.

_requireActionAccessible​

Reverts if the action does not exist, has been executed, or has been cancelled.

Common precondition for lifecycle validators and for the view functions that expose sub-action data. Sub-action arrays are cleared on execute and cancel while the corresponding flags remain set, so this helper distinguishes "never queued" from "already executed" from "already cancelled" with explicit reverts.

function _requireActionAccessible(
uint64 actionId_,
ITimelockBatchQueue.QueuedAction storage action_
) internal view;

Parameters

NameTypeDescription
actionId_uint64The queued action ID.
action_ITimelockBatchQueue.QueuedActionThe queued action storage reference.

_onSubActionQueued​

Hook invoked once per sub-action at queue time, before the batch is stored.

Derived contracts must revert on failure. Implementations are expected to validate the target, selector, and payload of the sub-action in isolation, and may record per-sub-action state. Cross sub-action invariants belong in _onBatchQueued. The caller is passed explicitly for clarity and to support derived contracts that centralize authorization around actor params.

function _onSubActionQueued(
address caller_,
uint64 actionId_,
uint256 index_,
ITimelockBatchQueue.BatchAction memory action_
) internal virtual;

Parameters

NameTypeDescription
caller_addressThe account queueing the action.
actionId_uint64The id the batch will be stored under.
index_uint256The position of the sub-action within the batch.
action_ITimelockBatchQueue.BatchActionThe sub-action being queued.

_onBatchQueued​

Hook invoked once per batch at queue time, after every _onSubActionQueued.

Default implementation is a no-op. Derived contracts override only when invariants spanning multiple sub-actions are required (e.g. forbidding duplicate or conflicting sub-actions inside one batch).

function _onBatchQueued(
address /* caller_ */,
uint64 /* actionId_ */,
ITimelockBatchQueue.BatchAction[] memory /* actions_ */
) internal virtual;

Parameters

NameTypeDescription
_address
_uint64
_ITimelockBatchQueue.BatchAction[]

_validateExecution​

Validate implementation-specific execution rules for the entire batch.

Derived contracts must revert on failure. Standard queued-action state and timestamp checks have already passed when this hook is called, and no sub-action has been executed yet. This hook is the right place for batch-level execution gates (e.g. requiring an execution role, checking that the policy is enabled). Per-sub-action execution behavior belongs in _executeSubAction.

function _validateExecution(
address caller_,
uint64 actionId_,
ITimelockBatchQueue.QueuedAction storage action_
) internal view virtual;

Parameters

NameTypeDescription
caller_addressThe account executing the action.
actionId_uint64The queued action ID.
action_ITimelockBatchQueue.QueuedActionThe queued action storage reference, including the sub-actions.

_validateCancellation​

Validate implementation-specific cancellation rules.

Derived contracts must revert on failure. Standard queued-action state checks have already passed when this hook is called.

function _validateCancellation(
address caller_,
uint64 actionId_,
ITimelockBatchQueue.QueuedAction storage action_
) internal view virtual;

Parameters

NameTypeDescription
caller_addressThe account cancelling the action.
actionId_uint64The queued action ID.
action_ITimelockBatchQueue.QueuedActionThe queued action storage reference, including the sub-actions.

_onActionCancelled​

Hook invoked once when a queued action is cancelled, after the stored sub-actions have been cleared.

Default implementation is a no-op. Derived contracts override to clear any per-sub-action state recorded at queue time by _onSubActionQueued. The sub-action count is captured before the stored array is deleted, so implementations can iterate the indices that were recorded.

function _onActionCancelled(uint64 actionId_, uint256 subActionCount_) internal virtual;

Parameters

NameTypeDescription
actionId_uint64The cancelled action ID.
subActionCount_uint256The number of sub-actions the action held before clearing.

_onActionExecuted​

Hook invoked once after every sub-action has executed successfully and before the stored sub-actions are cleared.

Default implementation is a no-op. A revert rolls back the complete batch, including target state changes and the action's executed flag. Derived contracts may use this hook to clear state that must remain available throughout execution.

function _onActionExecuted(uint64 actionId_, uint256 subActionCount_) internal virtual;

Parameters

NameTypeDescription
actionId_uint64The executed action ID.
subActionCount_uint256The number of successfully executed sub-actions.

_executeSubAction​

Execute a single sub-action of a batched queued action.

Derived contracts must revert on failure. Called by the base contract once per sub-action in array order; the action has already been marked executed, so a revert in any iteration reverts the entire batch and rolls back that flag. Derived contracts must not rely on the base contract calling this hook in any other order.

function _executeSubAction(
uint64 actionId_,
uint256 index_,
ITimelockBatchQueue.BatchAction memory action_
) internal virtual;

Parameters

NameTypeDescription
actionId_uint64The queued action ID.
index_uint256The position of the sub-action within the batch.
action_ITimelockBatchQueue.BatchActionThe sub-action to execute.

_validateTimelockDelay​

Validate a timelock delay.

Derived contracts must revert on failure.

function _validateTimelockDelay(uint48 delay_) internal view virtual;

Parameters

NameTypeDescription
delay_uint48The delay to validate.

_executionWindow​

Return the execution window for queued actions.

An action queued at queuedAt stores executableAt = queuedAt + timelockDelay and expiresAt = executableAt + executionWindow, the last executable timestamp, inclusive.

function _executionWindow() internal view virtual returns (uint48 executionWindow);

Returns

NameTypeDescription
executionWindowuint48The execution window in seconds.

_maxBatchSize​

Maximum number of sub-actions allowed in a single batch.

Default protects against batches that cannot be executed within the block gas limit. Derived contracts whose sub-actions are unusually expensive or cheap may override.

function _maxBatchSize() internal view virtual returns (uint256 maxBatchSize);

Returns

NameTypeDescription
maxBatchSizeuint256The maximum number of sub-actions allowed in a single batch.

supportsInterface​

Query if a contract implements an interface.

Does not revert.

function supportsInterface(bytes4 interfaceId_) public view virtual override returns (bool);

Parameters

NameTypeDescription
interfaceId_bytes4The interface identifier, as specified in ERC-165.

Returns

NameTypeDescription
<none>boolbool True if the contract implements interfaceId_.