GovernorTimelockAccessUpgradeable
Inherits: Initializable, GovernorUpgradeable
This module connects a {Governor} instance to an {AccessManager} instance, allowing the governor to make calls
that are delay-restricted by the manager using the normal {queue} workflow. An optional base delay is applied to
operations that are not delayed externally by the manager. Execution of a proposal will be delayed as much as
necessary to meet the required delays of all of its operations.
This extension allows the governor to hold and use its own assets and permissions, unlike {GovernorTimelockControl}
and {GovernorTimelockCompound}, where the timelock is a separate contract that must be the one to hold assets and
permissions. Operations that are delay-restricted by the manager, however, will be executed through the
{AccessManager-execute} function.
==== Security Considerations
Some operations may be cancelable in the AccessManager
by the admin or a set of guardians, depending on the
restricted function being invoked. Since proposals are atomic, the cancellation by a guardian of a single operation
in a proposal will cause all of the proposal to become unable to execute. Consider proposing cancellable operations
separately.
By default, function calls will be routed through the associated AccessManager
whenever it claims the target
function to be restricted by it. However, admins may configure the manager to make that claim for functions that a
governor would want to call directly (e.g., token transfers) in an attempt to deny it access to those functions. To
mitigate this attack vector, the governor is able to ignore the restrictions claimed by the AccessManager
using
{setAccessManagerIgnored}. While permanent denial of service is mitigated, temporary DoS may still be technically
possible. All of the governor's own functions (e.g., {setBaseDelaySeconds}) ignore the AccessManager
by default.
NOTE: AccessManager
does not support scheduling more than one operation with the same target and calldata at
the same time. See {AccessManager-schedule} for a workaround.
State Variables
GovernorTimelockAccessStorageLocation
bytes32 private constant GovernorTimelockAccessStorageLocation =
0xb26e23d38df572f5669f6310d407229c15b4fb320cb19bf5e8c38856d28d0800;
Functions
_getGovernorTimelockAccessStorage
function _getGovernorTimelockAccessStorage() private pure returns (GovernorTimelockAccessStorage storage $);
__GovernorTimelockAccess_init
Initialize the governor with an {AccessManager} and initial base delay.
function __GovernorTimelockAccess_init(address manager, uint32 initialBaseDelay) internal onlyInitializing;
__GovernorTimelockAccess_init_unchained
function __GovernorTimelockAccess_init_unchained(address manager, uint32 initialBaseDelay) internal onlyInitializing;
accessManager
Returns the {AccessManager} instance associated to this governor.
function accessManager() public view virtual returns (IAccessManager);
baseDelaySeconds
Base delay that will be applied to all function calls. Some may be further delayed by their associated
AccessManager
authority; in this case the final delay will be the maximum of the base delay and the one
demanded by the authority.
NOTE: Execution delays are processed by the AccessManager
contracts, and according to that contract are
expressed in seconds. Therefore, the base delay is also in seconds, regardless of the governor's clock mode.
function baseDelaySeconds() public view virtual returns (uint32);
setBaseDelaySeconds
Change the value of baseDelaySeconds. This operation can only be invoked through a governance proposal.
function setBaseDelaySeconds(uint32 newBaseDelay) public virtual onlyGovernance;
_setBaseDelaySeconds
Change the value of baseDelaySeconds. Internal function without access control.
function _setBaseDelaySeconds(uint32 newBaseDelay) internal virtual;
isAccessManagerIgnored
Check if restrictions from the associated {AccessManager} are ignored for a target function. Returns true
when the target function will be invoked directly regardless of AccessManager
settings for the function.
See {setAccessManagerIgnored} and Security Considerations above.
function isAccessManagerIgnored(address target, bytes4 selector) public view virtual returns (bool);
setAccessManagerIgnored
Configure whether restrictions from the associated {AccessManager} are ignored for a target function. See Security Considerations above.
function setAccessManagerIgnored(address target, bytes4[] calldata selectors, bool ignored)
public
virtual
onlyGovernance;
_setAccessManagerIgnored
Internal version of setAccessManagerIgnored without access restriction.
function _setAccessManagerIgnored(address target, bytes4 selector, bool ignored) internal virtual;
proposalExecutionPlan
Public accessor to check the execution plan, including the number of seconds that the proposal will be
delayed since queuing, an array indicating which of the proposal actions will be executed indirectly through
the associated {AccessManager}, and another indicating which will be scheduled in {queue}. Note that
those that must be scheduled are cancellable by AccessManager
guardians.
function proposalExecutionPlan(uint256 proposalId)
public
view
returns (uint32 delay, bool[] memory indirect, bool[] memory withDelay);
proposalNeedsQueuing
module:core
Whether a proposal needs to be queued before execution.
function proposalNeedsQueuing(uint256 proposalId) public view virtual override returns (bool);
propose
Create a new proposal. Vote start after a delay specified by {IGovernor-votingDelay} and lasts for a
duration specified by {IGovernor-votingPeriod}.
Emits a {ProposalCreated} event.
NOTE: The state of the Governor and targets
may change between the proposal creation and its execution.
This may be the result of third party actions on the targeted contracts, or other governor proposals.
For example, the balance of this contract could be updated or its access control permissions may be modified,
possibly compromising the proposal's ability to execute successfully (e.g. the governor doesn't have enough
value to cover a proposal with multiple transfers).
function propose(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, string memory description)
public
virtual
override
returns (uint256);
_queueOperations
Mechanism to queue a proposal, potentially scheduling some of its operations in the AccessManager. NOTE: The execution delay is chosen based on the delay information retrieved in propose. This value may be off if the delay was updated since proposal creation. In this case, the proposal needs to be recreated.
function _queueOperations(
uint256 proposalId,
address[] memory targets,
uint256[] memory,
bytes[] memory calldatas,
bytes32
) internal virtual override returns (uint48);
_executeOperations
Mechanism to execute a proposal, potentially going through AccessManager-execute for delayed operations.
function _executeOperations(
uint256 proposalId,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32
) internal virtual override;
_cancel
Internal cancel mechanism with minimal restrictions. A proposal can be cancelled in any state other than Canceled, Expired, or Executed. Once cancelled a proposal can't be re-submitted. Emits a {IGovernor-ProposalCanceled} event.
function _cancel(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash)
internal
virtual
override
returns (uint256);
_getManagerData
Returns whether the operation at an index is delayed by the manager, and its scheduling nonce once queued.
function _getManagerData(ExecutionPlan storage plan, uint256 index)
private
view
returns (bool controlled, bool withDelay, uint32 nonce);
_setManagerData
Marks an operation at an index as permissioned by the manager, potentially delayed, and when delayed sets its scheduling nonce.
function _setManagerData(ExecutionPlan storage plan, uint256 index, bool withDelay, uint32 nonce) private;
_getManagerDataIndices
Returns bucket and subindex for reading manager data from the packed array mapping.
function _getManagerDataIndices(uint256 index) private pure returns (uint256 bucket, uint256 subindex);
Events
BaseDelaySet
event BaseDelaySet(uint32 oldBaseDelaySeconds, uint32 newBaseDelaySeconds);
AccessManagerIgnoredSet
event AccessManagerIgnoredSet(address target, bytes4 selector, bool ignored);
Errors
GovernorUnmetDelay
error GovernorUnmetDelay(uint256 proposalId, uint256 neededTimestamp);
GovernorMismatchedNonce
error GovernorMismatchedNonce(uint256 proposalId, uint256 expectedNonce, uint256 actualNonce);
GovernorLockedIgnore
error GovernorLockedIgnore();
Structs
ExecutionPlan
struct ExecutionPlan {
uint16 length;
uint32 delay;
mapping(uint256 operationBucket => uint32[8]) managerData;
}
GovernorTimelockAccessStorage
Note: storage-location: erc7201:openzeppelin.storage.GovernorTimelockAccess
struct GovernorTimelockAccessStorage {
mapping(address target => mapping(bytes4 selector => bool)) _ignoreToggle;
mapping(uint256 proposalId => ExecutionPlan) _executionPlan;
uint32 _baseDelay;
IAccessManager _manager;
}