Execution strategies
Execution Strategies have two key roles:
determining the status of a proposal at any time,
and executing the payload of a proposal if it has been accepted.
Each proposal should have an Execution strategy set when it is created. This consists of a strategy contract address, along with an execution payload.
This page provides more details on the Execution strategies along with the implementations that we offer.
Proposal status
Every execution strategy should have a public view function getProposalStatus
with the following interface:
This function takes the proposal state as input and returns the proposal status defined by a ProposalStatus
enum. This enum contains all of the possible states the proposal can be in:
Note that because of having separate minVotingDuration
and maxVotingDuration
, we have two separate statuses for inside the voting period: VotingPeriod
and VotingPeriodAccepted
. Refer to the Space section for more information on this.
Abstracting status functionality outside of the space contract allows far greater flexibility in governance mechanisms since users can define their own logic on exactly how the status is determined. We provide the following implementations:
A proposal is accepted if FOR
votes exceed AGAINST
votes and the total votes (FOR
+ AGAINST
+ ABSTAIN
) exceed the quorum
.
Has a single parameter quorum
which is set when the strategy is deployed.
This is the standard approach that we expect to be used most often.
A proposal is rejected if AGAINST
votes exceed the quorum
, otherwise, it is accepted.
It has a single parameter quorum
that is set when the strategy is deployed.
This approach unlocks optimistic governance mechanisms where proposals are assumed to be accepted unless DAO members choose otherwise by voting against. This can lead to a far higher level of governance efficiency as it reduces the number of on-chain transactions for 'non-controversial' proposals.
It has two parameters: quorum
and emergencyQuorum
, where emergencyQuorum
should be set greater than quorum
.
If the total votes are less than emergencyQuorum
, then the proposal status is computed in the same way as Simple Quorum with the quorum
parameter. However if the higher emergencyQuorum
is met, then the minVotingDuration
is ignored and a proposal can be executed early.
This can be useful for emergency actions in response to critical events such as hacks, where one can expect much higher participation in the governance vote than during normal processes, and therefore a 'tradeoff' between proposal duration and proposal participation can be made.
Proposal execution
If the proposal status is Accepted
(or VotingPeriodAccepted
) the Execution strategy should then execute the proposal payload. We provide the following payload executor implementations:
An execution strategy that allows proposals to execute transactions from a specified target
Avatar contract, the most popular one being a Gnosis Safe.
To use this strategy in a proposal, you must whitelist the space in the strategy, this can either be done at deployment or using the enableSpace
function. The proposal payload should consist of an ABI encoded array of type MetaTransaction[]
with the following format:
An execution strategy that is itself a Timelock contract. A timelockDelay
is specified when the Timelock is deployed. When a proposal with this strategy is executed, the proposal transactions are queued in the Timelock for timelockDelay
seconds before they can be executed. The proposal payload should consist of an ABI encoded array of type MetaTransaction[]
with the following format:
There is also an optional vetoGuardian
role that has the power to veto
a queued proposal.
Cross chain execution (coming soon)
An execution strategy that forwards an execution payload to another chain to be executed there.
And more!
Feel free to create your own Execution strategies! The interface of a strategy can be found here.
Last updated