Governance

This crate includes primitives for on-chain governance.

Timelock

In a governance system, TimelockControllerComponent is in charge of introducing a delay between a proposal and its execution.

ITimelock

use openzeppelin::governance::timelock::interface::ITimelock;

Functions

is_operation(id: felt252) → bool external

Returns whether id corresponds to a registered operation. This includes the OperationStates: Waiting, Ready, and Done.

is_operation_pending(id: felt252) → bool external

Returns whether the id OperationState is pending or not. Note that a pending operation may be either Waiting or Ready.

is_operation_ready(id: felt252) → bool external

Returns whether the id OperationState is Ready or not.

is_operation_done(id: felt252) → bool external

Returns whether the id OperationState is Done or not.

get_timestamp(id: felt252) → u64 external

Returns the timestamp at which id becomes Ready.

0 means the OperationState is Unset and 1 means the OperationState is Done.

get_operation_state(id: felt252) → OperationState external

Returns the OperationState for id.

get_min_delay() → u64 external

Returns the minimum delay in seconds for an operation to become valid. This value can be changed by executing an operation that calls update_delay.

hash_operation(call: Call, predecessor: felt252, salt: felt252) external

Returns the identifier of an operation containing a single transaction.

hash_operation_batch(calls: Span<Call>, predecessor: felt252, salt: felt252) external

Returns the identifier of an operation containing a batch of transactions.

schedule(call: Call, predecessor: felt252, salt: felt252, delay: u64) external

Schedule an operation containing a single transaction.

Requirements:

  • the caller must have the PROPOSER_ROLE role.

Emits CallScheduled event. If salt is not zero, emits CallSalt event.

schedule_batch(calls: Span<Call>, predecessor: felt252, salt: felt252, delay: u64) external

Schedule an operation containing a batch of transactions.

Requirements:

  • The caller must have the PROPOSER_ROLE role.

Emits one CallScheduled event for each transaction in the batch. If salt is not zero, emits CallSalt event.

cancel(id: felt252) external

Cancel an operation.

Requirements:

  • The caller must have the CANCELLER_ROLE role.

  • id must be an operation.

Emits a CallCancelled event.

execute(call: Call, predecessor: felt252, salt: felt252) external

Execute a (Ready) operation containing a single Call.

Requirements:

  • Caller must have EXECUTOR_ROLE.

  • id must be in Ready OperationState.

  • predecessor must either be 0 or in Done OperationState.

Emits a CallExecuted event.

This function can reenter, but it doesn’t pose a risk because _after_call(self: @ContractState, id: felt252) internal checks that the proposal is pending, thus any modifications to the operation during reentrancy should be caught.

execute_batch(calls: Span<Call>, predecessor: felt252, salt: felt252) external

Execute a (Ready) operation containing a batch of Calls.

Requirements:

  • Caller must have EXECUTOR_ROLE.

  • id must be in Ready OperationState.

  • predecessor must either be 0 or in Done OperationState.

Emits a CallExecuted event for each Call.

This function can reenter, but it doesn’t pose a risk because _after_call checks that the proposal is pending, thus any modifications to the operation during reentrancy should be caught.

update_delay(new_delay: u64) external

Changes the minimum timelock duration for future operations.

Requirements:

  • The caller must be the timelock itself. This can only be achieved by scheduling and later executing an operation where the timelock is the target and the data is the serialized call to this function.

Emits a MinDelayChanged event.

Events

CallScheduled(id: felt252, index: felt252, call: Call, predecessor: felt252, delay: u64) event

Emitted when call is scheduled as part of operation id.

CallExecuted(id: felt252, index: felt252, call: Call) event

Emitted when call is performed as part of operation id.

CallSalt(id: felt252, salt: felt252) event

Emitted when a new proposal is scheduled with non-zero salt.

CallCancelled(id: felt252) event

Emitted when operation id is cancelled.

MinDelayChanged(old_duration: u64, new_duration: u64) event

Emitted when the minimum delay for future operations is modified.

TimelockControllerComponent

use openzeppelin::governance::timelock::TimelockControllerComponent;

Functions

is_operation(self: @ContractState, id: felt252) → bool external

Returns whether id corresponds to a registered operation. This includes the OperationStates: Waiting, Ready, and Done.

is_operation_pending(self: @ContractState, id: felt252) → bool external

Returns whether the id OperationState is pending or not. Note that a pending operation may be either Waiting or Ready.

is_operation_ready(self: @ContractState, id: felt252) → bool external

Returns whether the id OperationState is Ready or not.

is_operation_done(self: @ContractState, id: felt252) → bool external

Returns whether the id OperationState is Done or not.

get_timestamp(self: @ContractState, id: felt252) → u64 external

Returns the timestamp at which id becomes Ready.

0 means the OperationState is Unset and 1 means the OperationState is Done.

get_operation_state(self: @ContractState, id: felt252) → OperationState external

Returns the OperationState for id.

get_min_delay(self: @ContractState) → u64 external

Returns the minimum delay in seconds for an operation to become valid. This value can be changed by executing an operation that calls update_delay.

hash_operation(self: @ContractState, call: Call, predecessor: felt252, salt: felt252) external

Returns the identifier of an operation containing a single transaction.

hash_operation_batch(self: @ContractState, calls: Span<Call>, predecessor: felt252, salt: felt252) external

Returns the identifier of an operation containing a batch of transactions.

schedule(ref self: ContractState, call: Call, predecessor: felt252, salt: felt252, delay: u64) external

Schedule an operation containing a single transaction.

Requirements:

  • the caller must have the PROPOSER_ROLE role.

Emits CallScheduled event. If salt is not zero, emits CallSalt event.

schedule_batch(ref self: ContractState, calls: Span<Call>, predecessor: felt252, salt: felt252, delay: u64) external

Schedule an operation containing a batch of transactions.

Requirements:

  • The caller must have the PROPOSER_ROLE role.

Emits one CallScheduled event for each transaction in the batch. If salt is not zero, emits CallSalt event.

cancel(ref self: ContractState, id: felt252) external

Cancel an operation.

Requirements:

  • The caller must have the CANCELLER_ROLE role.

  • id must be an operation.

Emits a CallCancelled event.

execute(ref self: ContractState, call: Call, predecessor: felt252, salt: felt252) external

Execute a (Ready) operation containing a single Call.

Requirements:

  • Caller must have EXECUTOR_ROLE.

  • id must be in Ready OperationState.

  • predecessor must either be 0 or in Done OperationState.

Emits a CallExecuted event.

This function can reenter, but it doesn’t pose a risk because _after_call(self: @ContractState, id: felt252) internal checks that the proposal is pending, thus any modifications to the operation during reentrancy should be caught.

execute_batch(ref self: ContractState, calls: Span<Call>, predecessor: felt252, salt: felt252) external

Execute a (Ready) operation containing a batch of Calls.

Requirements:

  • Caller must have EXECUTOR_ROLE.

  • id must be in Ready OperationState.

  • predecessor must either be 0 or in Done OperationState.

Emits a CallExecuted event for each Call.

This function can reenter, but it doesn’t pose a risk because _after_call checks that the proposal is pending, thus any modifications to the operation during reentrancy should be caught.

update_delay(ref self: ContractState, new_delay: u64) external

Changes the minimum timelock duration for future operations.

Requirements:

  • The caller must be the timelock itself. This can only be achieved by scheduling and later executing an operation where the timelock is the target and the data is the serialized call to this function.

Emits a MinDelayChanged event.

Internal functions

initializer(ref self: ContractState, min_delay: u64, proposers: Span<ContractAddress>, executors: Span<ContractState>, admin: ContractAddress) internal

Initializes the contract by registering support for SRC5 and AccessControl.

This function also configures the contract with the following parameters:

  • min_delay: initial minimum delay in seconds for operations.

  • proposers: accounts to be granted proposer and canceller roles.

  • executors: accounts to be granted executor role.

  • admin: optional account to be granted admin role; disable with zero address.

The optional admin can aid with initial configuration of roles after deployment without being subject to delay, but this role should be subsequently renounced in favor of administration through timelocked proposals.

Emits two IAccessControl::RoleGranted events for each account in proposers with PROPOSER_ROLE and CANCELLER_ROLE roles.

Emits a IAccessControl::RoleGranted event for each account in executors with EXECUTOR_ROLE role.

May emit a IAccessControl::RoleGranted event for admin with DEFAULT_ADMIN_ROLE role (if admin is not zero).

Emits MinDelayChanged event.

assert_only_role(self: @ContractState, role: felt252) internal

Validates that the caller has the given role. Otherwise it panics.

assert_only_role_or_open_role(self: @ContractState, role: felt252) internal

Validates that the caller has the given role. If role is granted to the zero address, then this is considered an open role which allows anyone to be the caller.

assert_only_self(self: @ContractState) internal

Validates that the caller is the timelock contract itself. Otherwise it panics.

_before_call(self: @ContractState, id: felt252, predecessor: felt252) internal

Private function that checks before execution of an operation’s calls.

Requirements:

  • id must be in the Ready OperationState.

  • predecessor must either be zero or be in the Done OperationState.

_after_call(self: @ContractState, id: felt252) internal

Private function that checks after execution of an operation’s calls and sets the OperationState of id to Done.

Requirements:

  • id must be in the Ready OperationState.

_schedule(ref self: ContractState, id: felt252, delay: u64) internal

Private function that schedules an operation that is to become valid after a given delay.

_execute(ref self: ContractState, call: Call) internal

Private function that executes an operation’s calls.

Events

CallScheduled(id: felt252, index: felt252, call: Call, predecessor: felt252, delay: u64) event

Emitted when call is scheduled as part of operation id.

CallExecuted(id: felt252, index: felt252, call: Call) event

Emitted when call is performed as part of operation id.

CallSalt(id: felt252, salt: felt252) event

Emitted when a new proposal is scheduled with non-zero salt.

CallCancelled(id: felt252) event

Emitted when operation id is cancelled.

MinDelayChanged(old_duration: u64, new_duration: u64) event

Emitted when the minimum delay for future operations is modified.

Utils

IVotes

use openzeppelin::governance::utils::interfaces::IVotes;

Common interface for Votes-enabled contracts. For an implementation example see ERC20VotesComponent.

Functions

get_votes(account: ContractAddress) → u256 external

Returns the current amount of votes that account has.

get_past_votes(account: ContractAddress, timepoint: u64) → u256 external

Returns the amount of votes that account had at a specific moment in the past.

get_past_total_supply(timepoint: u64) → u256 external

Returns the total supply of votes available at a specific moment in the past.

This value is the sum of all available votes, which is not necessarily the sum of all delegated votes. Votes that have not been delegated are still part of total supply, even though they would not participate in a vote.

delegates(account: ContractAddress) → ContractAddress external

Returns the delegate that account has chosen.

delegate(delegatee: ContractAddress) external

Delegates votes from the sender to delegatee.

delegate_by_sig(delegator: ContractAddress, delegatee: ContractAddress, nonce: felt252, expiry: u64, signature: Array<felt252>) external

Delegates votes from delegator to delegatee.