Voting & Governance

Aave Governance V2 is an exciting new evolution of on-chain governance, allowing unique features such as delegated voting and proposition powers, rapid protocol upgrades via short time lock executors, and governance upgrades via long time lock executors.

This ensures the protocol can rapidly adjust to changing market conditions, as well as upgrade core parts of the protocol as time goes on.

This section is for developers and technical users. For a non-technical overview, see the Protocol Governance section of Aavenomics or the Governance Docs.

Overview

AAVE and/or stkAAVE token holders receive governance powers proportionally to the sum of their balance.

There are initially two powers associated with each governance token:

  • The proposal power that gives access to creating and sustaining a proposal.

  • The voting power which is used to vote for or against existing proposals.

Any user can chose to delegate one or both of the governance powers associated with a token, either through our governance portal or programatically.

A user that has received delegated power can not forward this delegated power to another delegatee. I.e. delegated power cannot be passed on further.

The code for Aave Governance V2 can be found on Github.

Deployed Contracts

Audits

Proposal Types

There are two types of proposals with different parameters which affect the length and execution of a proposal, i.e. critical proposals that affect governance consensus require more voting time and a higher vote differential, whereas proposals affecting only protocol parameters require less voting time and can be quickly implemented.

As an initial safeguard to the protocol, a guardian account, controlled by a community multisig, is able to cancel a proposal before the proposal is executed.

Each type of proposal can only be validated and executed by a certain executor.

Short time lock executor

The short time lock executor can execute proposals that change parts of the Aave protocol or the Ecosystem reserve that require quick intervention.

Long time lock executor

The long time lock executor can execute proposals that change parts of the Aave protocol that affect governance consensus.

Proposition/Voting Power

An account's proposition/voting power at a given block is equal to the snapshot of that account's AAVE/stkAAVE balances plus the balances of all delegators.

An account's balance contributes to both proposition and voting power while delegators can choose to delegate proposition power, voting power or both to another account.

A creator must have proposition power higher than PROPOSITION_THRESHOLD at the block before the proposal is created and until the proposal is executed.

A user can vote only once. The weight of this vote is equal to the user's voting power at the block when submitVote() is called.

Both AAVE and stkAAVE maintain _propositionSnapshots/_votingSnapshots mappings. New snapshots are taken on every call to:

Proposition/Voting power available at a specified block can be fetched from AaveGovernanceStrategy

Proposal Life Cycle

0) Off-chain process

The ARC and AIP process should be followed, with a resulting AIP and payload ready to be used for the proposal. Learn more about the ARC and AIP process here.

The AIP should be merged into the AIP repository, with an associated IPFS hash of the parsed AIP file, before the next steps are taken.

1) Proposal Creation

A proposal can be created by calling create(), with the following caveats:

  • The proposer must have a proposal power higher than PROPOSITION_THRESHOLD.

  • The proposer needs to maintain the proposal power threshold or higher until the proposal is actually executed (i.e. during the vote and until the actual execution of the proposal)

The proposal is now in a PENDING state until the vote begins.

2) Proposal Voting

If votingDelay = 0, then the voting period begins at the next block. Otherwise the voting begins after the votingDelay. The votingDelay value can be fetched from getVotingDelay(). A snapshot of voting powers is taken and can no longer be delegated/transferred for the proposal being voted on.

The proposal state is ACTIVE and users can submit a vote for or against the proposal, weighted by the users total voting power (tokens + delegated voting power), within the allotted VOTING_DURATION.

3) End of Voting Period

For a proposal to pass:

  • The voting power (in % of total voting power) of for-votes needs to reach the quorum set by the MINIMUM_QUORUM parameter, and

  • The difference between for-votes and against-votes (in % of total voting power) needs to exceed the vote differential threshold set by the VOTE_DIFFERENTIAL parameter.

If the proposal has passed, then the proposal state becomes SUCCEEDED, otherwise it is FAILED

4) Proposal Queuing and Execution

A SUCCEEDED proposal can be queued and will be executed after the execution delay and before grace period expiration. The delay can be fetched from getDelay() and the GRACE_PERIOD can be fetched from GRACE_PERIOD().

The validation and execution of the proposal is performed by the time lock executor.

A queued proposal state is QUEUED.

A successfully executed proposal state is EXECUTED.

If a queued proposal has not been executed before expiration, then the proposal state is EXPIRED.

(Optional) Proposal Canceling

If the proposal creator's proposal power decrease and no longer meet the PROPOSITION_THRESHOLD, any user can cancel the proposal.

In addition as an initial safeguard to the protocol, a guardian account, controlled by a communtity multisig, is able to cancel a proposal before a proposal is executed.

A cancelled proposal state is CANCELED.

Integrating Governance

Delegation

To perform delegation in your integration, call the function delegate() or delegateByType() on the AAVE and/or the stkAAVE token contracts to delegate one or both of the voting and proposition powers.

Voting

To enable your users to vote:

  1. Retrieve a list of proposals and associated details. This can be done via the subgraph or directly from the on-chain governance contracts.

  2. Vote on the proposals by using submitVote().

  3. Fetch the state of the proposal via the subgraph or directly on-chain.

Proposals

To fetch a proposal and its associated details, call getProposal() or getProposals().

To get the token power of an address, call getTokenPower().

Subgraphs

The governance subgraph gives access to three main objects:

  • Proposals with their states and votes

  • Available executors and their parameters

  • Votes

Subgraphs on the graph explorer:

Example query for fetching active proposals

{
  proposals(where: {state: Active}) {
    id
    state
    ipfsHash
    creator
    executor {
      id
      authorized
      propositionThreshold
      votingDuration
      voteDifferential
    }
    votes(first: 5) {
      id
      voter
      votingPower
      support    
  	}
  }
}

Relevant Methods

create()

Contract: AaveGovernanceV2

function create(address executor, address[] memory targets, uint256[] memory values, string[] memory signatures, bytes[] memory calldatas, bool[] memory withDelegatecalls, bytes32 ipfsHash) external returns (uint256 proposalId)

Creates a proposal for a specific executor. A proposal includes a list of underlying transactions.

The caller must have the necessary proposition power to create a proposal.

return values

PROPOSITION_THRESHOLD()

Contract: ProposalValidator (Executor)

function PROPOSITION_THRESHOLD()

Returns the minimum percentage of the voting token supply needed to submit a proposal (in BPS, e.g. 1 bps = 0.01%, 10,000 bps = 100%) in the Proposal Creation step.

Currently the Short time lock executor is 0.5% and the Long time lock executor is 2%.

getVotingDelay()

Contract: AaveGovernanceV2

function getVotingDelay()

Returns the current delay before a created proposal can be voted on by the community in the Proposal Creation phase.

VOTING_DURATION()

Contract: ProposalValidator (Executor)

function VOTING_DURATION()

Returns the duration of the voting period (in blocks) in the Proposal Creation phase.

Currently the Short time lock executor is 3 days and the Long time lock executor is 10 days.

MINIMUM_QUORUM()

Contract: ProposalValidator (Executor)

function MINIMUM_QUORUM()

Returns the minimum percentage of the voting token supply of 'for' (i.e. positive) votes of a proposal to successfully pass (in BPS, e.g. 1 bps = 0.01%, 10,000 bps = 100%), in End of Voting phase.

Currently the Short time lock executor is 2% and the Long time lock executor is 20%.

VOTE_DIFFERENTIAL()

Contract: ProposalValidator (Executor)

function VOTE_DIFFERENTIAL()

Returns the percentage of the voting token supply of 'for' (i.e. positive) votes needed over 'against' (i.e.negative) votes for a proposal to successfully pass (in BPS, e.g. 1 bps = 0.01%, 10,000 bps = 100%), in End of Voting phase.

Currently the Short time lock executor is 0.5% and the Long time lock executor is 15%.

getDelay()

Contract: ExecutorWithTimeLock (Executor)

function getDelay()

Returns the delay between queuing and execution of a proposal (in seconds) in Proposal Queueing and Execution Period.

Currently the Short time lock executor is 1 day and the Long time lock executor is 7 days.

GRACE_PERIOD()

Contract: ExecutorWithTimeLock (Executor)

function GRACE_PERIOD()

Returns the time after delay (getDelay()) in seconds when a proposal can be executed in Proposal Queueing and Execution Period.

Currently the Short time lock executor is 5 days and the Long time lock executor is 5 days.

delegate()

Contracts: AAVE, stkAAVE

function delegate(address delegatee)

Delegate both powers of a token (vote and proposition) to a delegatee

delegateByType()

Contracts: AAVE, stkAAVE

function delegateByType(address delegatee, uint8 delegationType)

Delegate one specific power of a token (vote or proposition) to a delegatee

To reset delegation, set the delegatee address to the delegator address.

submitVote()

Contract: AaveGovernanceV2``

submitVote(uint256 proposalId, bool support)

Submits a vote by the caller.

getDelegateeByType()

Contracts: AAVE, stkAAVE

function getDelegateeByType(address delegator, uint8 delegationType) returns(address delegatee)

Returns the address of the delegatee for a delegator

If the return value is the delegator address, then there is no delegation.

getVotingPowerAt(), getPropositionPowerAt()

Contract: AaveGovernanceStrategy

function get{Voting,Proposition}PowerAt(address user, uint256 blockNumber) returns(power uint256)

Returns the Voting/Proposition power of the user at a specified block

When submitting a vote, the voting power is calculated at the time of the beginning of the vote.

getTotalVotingSupplyAt(), getTotalPropositionSupplyAt()

Contract: AaveGovernanceStrategy

function getTotal{Voting,Proposition}SupplyAt(uint256 blockNumber) returns(totalSupply uint256)

Returns the total Voting/Proposition power available at a specified block

The total available power is equal to the total supply of not staked AAVE + the total supply of staked AAVE = total supply of AAVE

getProposal()

Contract: GovV2Helper

function getProposal(uint256 id, IAaveGovernanceV2 governance)

Returns the details of a proposal.

getProposals()

Contract: GovV2Helper

function getProposals(uint256 skip, uint256 limit, IAaveGovernanceV2 governance)

Returns an array of proposals with associated details.

getTokensPower()

Contract: GovV2Helper

function getTokensPower(address user, address[] memory tokens)

Return the power (voting and proposition) of the user.

Returns the votingPower, delegatedAddressVotingPower, propositionPower, delegatedAddressPropositionPower.

Last updated