LZBridgeAndDelegateConfig
Inherits: Policy, PolicyEnablerV2, TimelockBatchQueue, ILZBridgeAndDelegateConfig, IVersioned
Title: LZBridgeAndDelegateConfig
Timelock policy that owns LayerZero bridge configuration on behalf of an LZBridgeGateway, LZEndpointDelegate, and periphery LZCrossChainBridge triple.
The policy is intended to hold the bridge_configurator role on the
gateway/delegate and to be pinned as the periphery bridge's configurator. The
queue entry point packs one or more gateway/delegate/facilitator sub-actions into
a single atomic timelock entry; each sub-action's proposer role and payload shape is
validated at queue time and dispatched at execution time via a typed call against
the configured target. The policy's own configuration (target slots, timelock delay)
is managed through the typed queueSetTarget* and queueSetTimelockDelay helpers;
queue deliberately rejects self-targeted sub-actions so that these privileged
rotations cannot be smuggled into an arbitrary batch. Cancellation is gated to the
emergency role only, so the proposer cannot rescind its own queued action; the
emergency role is intended for a multisig veto independent of the proposer roles.
Disabling the policy suspends queueing and execution but does not clear queued
actions; before re-enabling, the emergency role must cancel any queued action that
should not become executable again.
Constants
MIN_TIMELOCK_DELAY
Minimum accepted timelock delay.
uint48 public constant override MIN_TIMELOCK_DELAY = 1 days;
Returns
| Name | Type | Description |
|---|---|---|
| <none> | uint48 |
MAX_TIMELOCK_DELAY
Maximum accepted timelock delay.
uint48 public constant override MAX_TIMELOCK_DELAY = 30 days;
Returns
| Name | Type | Description |
|---|---|---|
| <none> | uint48 |
EXECUTION_WINDOW
Length of the window after executableAt during which a queued action may be
executed before it expires.
uint48 public constant override EXECUTION_WINDOW = 3 days;
Returns
| Name | Type | Description |
|---|---|---|
| <none> | uint48 |
_LEN_SINGLE_WORD
Exact ABI-encoded length of a single static-word payload: (address),
(uint256), or (uint32).
uint256 internal constant _LEN_SINGLE_WORD = 32;
_LEN_SEND_LIBRARY
Exact ABI-encoded length of the setSendLibrary (uint32, address) payload.
uint256 internal constant _LEN_SEND_LIBRARY = 64;
_LEN_RECEIVE_LIBRARY
Exact ABI-encoded length of the setReceiveLibrary and
setReceiveLibraryTimeout (uint32, address, uint256) payload.
uint256 internal constant _LEN_RECEIVE_LIBRARY = 96;
_MIN_LEN_DYNAMIC_ARRAY
Minimal ABI-encoded length of a single dynamic-array payload (T[]): the head
offset word plus an empty array's length word.
uint256 internal constant _MIN_LEN_DYNAMIC_ARRAY = 64;
_MIN_LEN_ENDPOINT_CONFIG
Minimal ABI-encoded length of the setEndpointConfig
(address, SetConfigParam[]) payload: the address word, the array offset word,
and an empty array's length word.
uint256 internal constant _MIN_LEN_ENDPOINT_CONFIG = 96;
_KEYCODE_ROLES
Pre-computed keycode for the ROLES module dependency.
Avoids the runtime cost of toKeycode("ROLES") at the call site.
Keycode internal constant _KEYCODE_ROLES = Keycode.wrap(0x524F4C4553);
State Variables
gateway
The LZBridgeGateway this policy manages.
address public override gateway;
Returns
| Name | Type | Description |
|---|---|---|
| <none> | address |
delegate
The LZEndpointDelegate this policy manages.
address public override delegate;
Returns
| Name | Type | Description |
|---|---|---|
| <none> | address |
facilitator
The periphery LZCrossChainBridge this policy manages.
address public override facilitator;
Returns
| Name | Type | Description |
|---|---|---|
| <none> | address |
subActionTargetKind
Records, per queued sub-action, the TargetKind it was validated against at
queue time: subActionTargetKind[actionId][index].
Returns NONE for unknown action ids or indices. Entries are cleared when
consumed by _executeSubAction and on cancellation by _onActionCancelled, so
no stale entries remain once an action completes.
mapping(uint64 actionId_ => mapping(uint256 index_ => TargetKind)) public subActionTargetKind;
Functions
constructor
Reverts if any address argument is zero or the initial delay is outside
[MIN_TIMELOCK_DELAY, MAX_TIMELOCK_DELAY].
constructor(
Kernel kernel_,
address gateway_,
address delegate_,
address facilitator_,
uint48 initialTimelockDelay_
) Policy(kernel_) TimelockBatchQueue(initialTimelockDelay_);
Parameters
| Name | Type | Description |
|---|---|---|
| kernel_ | Kernel | Bophades kernel. |
| gateway_ | address | LZBridgeGateway to manage. |
| delegate_ | address | LZEndpointDelegate to manage. |
| facilitator_ | address | Periphery LZCrossChainBridge to manage. |
| initialTimelockDelay_ | uint48 | Initial timelock delay; validated by _validateTimelockDelay. |
configureDependencies
Define module dependencies for this policy.
function configureDependencies() external override returns (Keycode[] memory dependencies);
Returns
| Name | Type | Description |
|---|---|---|
| dependencies | Keycode[] | - Keycode array of module dependencies. |
requestPermissions
Function called by kernel to set module function permissions.
function requestPermissions() external pure override returns (Permissions[] memory);
Returns
| Name | Type | Description |
|---|---|---|
| <none> | Permissions[] | - Array of keycodes and function selectors for requested permissions. |
VERSION
Returns the version of the contract
function VERSION() external pure override returns (uint8 major, uint8 minor);
Returns
| Name | Type | Description |
|---|---|---|
| major | uint8 | - Major version upgrade indicates breaking change to the interface. |
| minor | uint8 | - Minor version change retains backward-compatible interface. |
queueSetTargetGateway
Queues a self-call updating the policy's gateway target slot.
Reverts if:
- The policy is disabled
- The caller does not have the
adminrole newGateway_is the zero address
function queueSetTargetGateway(
address newGateway_
) external override returns (uint64 actionId);
Parameters
| Name | Type | Description |
|---|---|---|
| newGateway_ | address | The new gateway address. |
Returns
| Name | Type | Description |
|---|---|---|
| actionId | uint64 | The queued action ID. |
queueSetTargetDelegate
Queues a self-call updating the policy's delegate target slot.
Reverts if:
- The policy is disabled
- The caller does not have the
adminrole newDelegate_is the zero address
function queueSetTargetDelegate(
address newDelegate_
) external override returns (uint64 actionId);
Parameters
| Name | Type | Description |
|---|---|---|
| newDelegate_ | address | The new delegate address. |
Returns
| Name | Type | Description |
|---|---|---|
| actionId | uint64 | The queued action ID. |
queueSetTargetFacilitator
Queues a self-call updating the policy's facilitator target slot.
Reverts if:
- The policy is disabled
- The caller does not have the
adminrole newFacilitator_is the zero address
function queueSetTargetFacilitator(
address newFacilitator_
) external override returns (uint64 actionId);
Parameters
| Name | Type | Description |
|---|---|---|
| newFacilitator_ | address | The new facilitator address. |
Returns
| Name | Type | Description |
|---|---|---|
| actionId | uint64 | The queued action ID. |
queueSetTimelockDelay
Queues a self-call updating the configured timelock delay.
Reverts if:
- The policy is disabled
- The caller does not have the
adminrole delay_is outside[MIN_TIMELOCK_DELAY, MAX_TIMELOCK_DELAY]
function queueSetTimelockDelay(uint48 delay_) external override returns (uint64 actionId);
Parameters
| Name | Type | Description |
|---|---|---|
| delay_ | uint48 | The new timelock delay in seconds. |
Returns
| Name | Type | Description |
|---|---|---|
| actionId | uint64 | The queued action ID. |
queue
Queues a batch of one or more gateway, delegate, or facilitator sub-actions for atomic timelocked execution.
Reverts if:
- The policy is disabled
- The batch is empty
- The batch exceeds the maximum batch size
- Any sub-action targets this policy (self-actions must use the typed
queueSetTarget*/queueSetTimelockDelayhelpers) - Any sub-action target is not the gateway, delegate, or facilitator
- The caller does not hold the proposer role required by any sub-action
- Any sub-action payload cannot be decoded into the expected types
function queue(
ITimelockBatchQueue.BatchAction[] memory actions_
) external override returns (uint64 actionId);
Parameters
| Name | Type | Description |
|---|---|---|
| actions_ | ITimelockBatchQueue.BatchAction[] | The sub-actions to queue. |
Returns
| Name | Type | Description |
|---|---|---|
| actionId | uint64 | The queued action ID. |
_onSubActionQueued
Validates the proposer's role and the (target, selector, payload) triple against
the supported action table, then records the resolved TargetKind.
Reverts if:
- The policy is disabled
- The action's target is unknown
- The proposer lacks the role required by the action
- The payload cannot be decoded into the expected types for the action
function _onSubActionQueued(
address caller_,
uint64 actionId_,
uint256 index_,
ITimelockBatchQueue.BatchAction memory action_
) internal override;
Parameters
| Name | Type | Description |
|---|---|---|
| caller_ | address | The account queueing the action. |
| actionId_ | uint64 | The id the batch will be stored under. |
| index_ | uint256 | The position of the sub-action within the batch. |
| action_ | ITimelockBatchQueue.BatchAction | The sub-action being queued. |
_validateExecution
Execution is permissionless once the timelock elapses; this hook only enforces
enabled status. The proposer was authorized at queue time by _onSubActionQueued,
and requiring an execution role would let an unavailable or compromised executor
block already-approved changes. The queue-to-execution target binding is enforced
per sub-action in _executeSubAction: dispatch is by the TargetKind recorded at
queue time.
Disabling the policy suspends execution but does not clear the queue: queued actions remain in storage and become executable again once the policy is re-enabled, for as long as their execution windows have not expired. Before re-enabling, the emergency role must therefore cancel every queued action that should not survive the disable, such as an action queued by a compromised proposer.
Reverts if:
- The policy is disabled
function _validateExecution(
address,
uint64,
ITimelockBatchQueue.QueuedAction storage
) internal view override;
Parameters
| Name | Type | Description |
|---|---|---|
| _ | address | The account executing the action. |
| _ | uint64 | The queued action ID. |
| _ | ITimelockBatchQueue.QueuedAction | The queued action storage reference, including the sub-actions. |
_validateCancellation
Cancellation is restricted to the emergency role; the proposer cannot rescind its own queued action. Intentionally permitted while the policy is disabled so stale or unwanted queued actions can be cleared before the policy is re-enabled.
Reverts if:
- The caller does not have the emergency role
function _validateCancellation(
address caller_,
uint64,
ITimelockBatchQueue.QueuedAction storage
) internal view override;
Parameters
| Name | Type | Description |
|---|---|---|
| caller_ | address | The account cancelling the action. |
| _ | uint64 | The queued action ID. |
| _ | ITimelockBatchQueue.QueuedAction | The queued action storage reference, including the sub-actions. |
_executeSubAction
Dispatches by the TargetKind recorded at queue time, and asserts the slot for
that kind still holds the queued address before forwarding the call.
The payload-shape checks performed at queue time are deliberately not re-run here,
since storage already holds the queued action and ABI decoding will revert on mismatch.
The recorded kind is consumed exactly once, so its entry is cleared before
dispatch; a revert in the dispatched call rolls the deletion back with the batch.
Reverts if:
- The recorded kind's target slot no longer holds the queued address
- No kind was recorded for the sub-action
function _executeSubAction(
uint64 actionId_,
uint256 index_,
ITimelockBatchQueue.BatchAction memory action_
) internal override;
Parameters
| Name | Type | Description |
|---|---|---|
| actionId_ | uint64 | The queued action ID. |
| index_ | uint256 | The position of the sub-action within the batch. |
| action_ | ITimelockBatchQueue.BatchAction | The sub-action to execute. |
_onActionCancelled
Hook invoked once when a queued action is cancelled, after the stored sub-actions have been cleared.
Clears the per-sub-action TargetKind entries recorded at queue time so no
stale entries remain after cancellation.
function _onActionCancelled(uint64 actionId_, uint256 subActionCount_) internal override;
Parameters
| Name | Type | Description |
|---|---|---|
| actionId_ | uint64 | The cancelled action ID. |
| subActionCount_ | uint256 | The number of sub-actions the action held before clearing. |
_requireTargetUnchanged
Reverts if the slot for a sub-action's recorded TargetKind no longer holds
the address the action was queued against.
function _requireTargetUnchanged(
uint64 actionId_,
uint256 index_,
address queued_,
address current_
) private pure;
Parameters
| Name | Type | Description |
|---|---|---|
| actionId_ | uint64 | |
| index_ | uint256 | |
| queued_ | address | |
| current_ | address |
_validateTimelockDelay
Validate a timelock delay.
Derived contracts must revert on failure.
function _validateTimelockDelay(uint48 delay_) internal pure override;
Parameters
| Name | Type | Description |
|---|---|---|
| delay_ | uint48 | The 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 pure override returns (uint48);
Returns
| Name | Type | Description |
|---|---|---|
| <none> | uint48 | The execution window in seconds. |
supportsInterface
Query if a contract implements an interface.
function supportsInterface(
bytes4 interfaceId_
) public view virtual override(EnablerV2, TimelockBatchQueue) returns (bool);
Parameters
| Name | Type | Description |
|---|---|---|
| interfaceId_ | bytes4 |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | bool |
_requireBridgeAdminProposer
Requires the caller to hold bridge_admin or admin.
function _requireBridgeAdminProposer(address caller_) private view;
Parameters
| Name | Type | Description |
|---|---|---|
| caller_ | address |
_requireRateLimiterProposer
Requires the caller to hold bridge_rate_limiter, bridge_admin, or admin.
function _requireRateLimiterProposer(address caller_) private view;
Parameters
| Name | Type | Description |
|---|---|---|
| caller_ | address |
_requireAdminProposer
Requires the caller to hold admin.
function _requireAdminProposer(address caller_) private view;
Parameters
| Name | Type | Description |
|---|---|---|
| caller_ | address |
_validateGatewaySubAction
function _validateGatewaySubAction(
address caller_,
ITimelockBatchQueue.BatchAction memory action_
) private view;
Parameters
| Name | Type | Description |
|---|---|---|
| caller_ | address | |
| action_ | ITimelockBatchQueue.BatchAction |
_validateDelegateSubAction
function _validateDelegateSubAction(
address caller_,
ITimelockBatchQueue.BatchAction memory action_
) private view;
Parameters
| Name | Type | Description |
|---|---|---|
| caller_ | address | |
| action_ | ITimelockBatchQueue.BatchAction |
_validateFacilitatorSubAction
function _validateFacilitatorSubAction(
address caller_,
ITimelockBatchQueue.BatchAction memory action_
) private view;
Parameters
| Name | Type | Description |
|---|---|---|
| caller_ | address | |
| action_ | ITimelockBatchQueue.BatchAction |
_validateSelfSubAction
function _validateSelfSubAction(
address caller_,
ITimelockBatchQueue.BatchAction memory action_
) private view;
Parameters
| Name | Type | Description |
|---|---|---|
| caller_ | address | |
| action_ | ITimelockBatchQueue.BatchAction |
_decodeGatewayRateLimitPayload
Decodes the payload of a rate-limit-related gateway sub-action.
Both shapes are a single dynamic-array argument. The payload must be at least the minimal empty-array encoding and must round-trip to its canonical ABI encoding, so trailing or non-canonical bytes are rejected at queue time. Only the shape is checked here; the target function validates the values.
function _decodeGatewayRateLimitPayload(
address target_,
bytes4 sel_,
bytes memory payload_
) private pure;
Parameters
| Name | Type | Description |
|---|---|---|
| target_ | address | |
| sel_ | bytes4 | |
| payload_ | bytes |
_decodeGatewayAdminPayload
Decodes the payload of a non-rate-limit gateway sub-action and forwards it to
the target's validate* mirror so payload invariants fail at queue time.
Every shape is a single static word, so the payload length must be exactly 32.
function _decodeGatewayAdminPayload(
address target_,
bytes4 sel_,
bytes memory payload_
) private view;
Parameters
| Name | Type | Description |
|---|---|---|
| target_ | address | |
| sel_ | bytes4 | |
| payload_ | bytes |
_decodeDelegatePayload
Decodes the payload of a delegate sub-action.
setSendLibrary and the receive-library helpers are fixed-size static tuples
with an exact length. setEndpointConfig carries a dynamic
(address, SetConfigParam[]) tuple, so it is bounded by its minimal empty-array
encoding and must round-trip to its canonical ABI encoding.
function _decodeDelegatePayload(
address target_,
bytes4 sel_,
bytes memory payload_
) private pure;
Parameters
| Name | Type | Description |
|---|---|---|
| target_ | address | |
| sel_ | bytes4 | |
| payload_ | bytes |
_decodeFacilitatorPayload
Decodes the payload of a facilitator sub-action that is not setConfigurator,
forwarding it to the target's validate* mirror where one exists so payload
invariants fail at queue time.
Every shape is a single static word, so the payload length must be exactly 32.
function _decodeFacilitatorPayload(
address target_,
bytes4 sel_,
bytes memory payload_
) private view;
Parameters
| Name | Type | Description |
|---|---|---|
| target_ | address | |
| sel_ | bytes4 | |
| payload_ | bytes |
_executeGatewaySubAction
function _executeGatewaySubAction(ITimelockBatchQueue.BatchAction memory action_) private;
Parameters
| Name | Type | Description |
|---|---|---|
| action_ | ITimelockBatchQueue.BatchAction |
_executeDelegateSubAction
function _executeDelegateSubAction(ITimelockBatchQueue.BatchAction memory action_) private;
Parameters
| Name | Type | Description |
|---|---|---|
| action_ | ITimelockBatchQueue.BatchAction |
_executeFacilitatorSubAction
function _executeFacilitatorSubAction(ITimelockBatchQueue.BatchAction memory action_) private;
Parameters
| Name | Type | Description |
|---|---|---|
| action_ | ITimelockBatchQueue.BatchAction |
_executeSelfSubAction
Queue-time validation in _validateSelfSubAction already enforces non-zero target
addresses and the timelock delay bounds, so this execute path trusts the decoded
payload and routes to the matching _setTarget* helper.
function _executeSelfSubAction(ITimelockBatchQueue.BatchAction memory action_) private;
Parameters
| Name | Type | Description |
|---|---|---|
| action_ | ITimelockBatchQueue.BatchAction |
_setTargetGateway
Writes the gateway target and emits TargetGatewaySet. Shared between the
constructor and the timelocked rotation path.
function _setTargetGateway(address gateway_) private;
Parameters
| Name | Type | Description |
|---|---|---|
| gateway_ | address |
_setTargetDelegate
Writes the delegate target and emits TargetDelegateSet. Shared between the
constructor and the timelocked rotation path.
function _setTargetDelegate(address delegate_) private;
Parameters
| Name | Type | Description |
|---|---|---|
| delegate_ | address |
_setTargetFacilitator
Writes the facilitator target and emits TargetFacilitatorSet. Shared between
the constructor and the timelocked rotation path.
function _setTargetFacilitator(address facilitator_) private;
Parameters
| Name | Type | Description |
|---|---|---|
| facilitator_ | address |
_validateGracePeriod
Mirrors the zero-period check performed by ReEnablerGracePeriod._setGracePeriod
so that a setGracePeriod sub-action is rejected at queue time rather than at
execution time.
function _validateGracePeriod(uint32 period_) private pure;
Parameters
| Name | Type | Description |
|---|---|---|
| period_ | uint32 |
_requireNonzeroAddress
function _requireNonzeroAddress(address address_, string memory parameter_) private pure;
Parameters
| Name | Type | Description |
|---|---|---|
| address_ | address | |
| parameter_ | string |
_revertActionInvalid
Reverts with ITimelockBatchQueue_ActionInvalid for an unsupported sub-action.
Centralizes the revert so the error encoding is emitted once instead of being inlined at every dispatch and payload-validation branch.
function _revertActionInvalid(address target_, bytes4 selector_) private pure;
Parameters
| Name | Type | Description |
|---|---|---|
| target_ | address | |
| selector_ | bytes4 |