Home

Awesome

Governor

Motivation

Agora's governor powers communities like Optimism, helping the collective move towards onchain governance. The initial version of the governance system is used for signalling purposes only and is designed to be upgraded in the future.

Overview

The governance contract is upgradeable. The proxy is owned by the admin address, which is currently the Optimism multisig. The admin address can upgrade the implementation to a new version, and transfer ownership to a new address.

The core governor implementation is based on OpenZeppelin's Governor.

The contract has been modified to support the following features:

Roles

The contracts in this repo are designed to be used by the following roles:

Versions

6 versions of the OP governor implementation have been deployed.

V1

Main implementation

V2

V3

V4

V5

V6

Deployment

See Also

Audits

Data and event interpretation guidelines

The latest versions of the governor introduced changes that may affect how clients interpret onchain functions and events. Below are some notes and suggestions on how to handle them.

Propose with modules

GovernorV5 introduced the proposeWithModule function, allowing to attach voting modules to proposals.

When a proposal with module is created, a new ProposalCreated event is emitted which includes the votingModule address and proposalData.

Clients are able to determine if a proposal is standard, approval voting, optimistic or else by checking the module emitted in the event, as well as use the PROPOSAL_DATA_ENCODING function in the module to decode proposalData (see modules section for more details).

Modules

Agora modules adhere to the VotingModule interface.

Clients should particularly be aware of 2 functions:

Votes (modules)

Votes for proposals with modules may hold additional data in params.

Agora modules expose a read function VOTE_PARAMS_ENCODING that returns the expected types, which can then be used by clients to decode the params.

For example this is the encoding used by the Approval Voting module

See the modules section for more details.

Partial delegations

Alligator introduced partial delegations, or subdelegations, as an alternative way to delegate fractional amounts of voting power to multiple delegates.

Each partial delegation emits a Subdelegation or Subdelegations event, respectively for single and batched operations. Clients should use these events to reconstruct the allowances of each address.

Each Subdelegation contains a delegator, delegate and rules.

Specifically with respect to partial delegations, rules contain allowances, which represent the maximum amount of voting power a delegate can use over the delegator's proxy. They can be defined either in absolute or relative amounts (when relative, a value of 1e5 or higher represents 100%).

Caveat: A delegator can subdelegate more than 100% of their voting power. Due to how alligator works, deriving partially delegated voting power is non-trivial so we suggest waiting for the Agora API, or ask clarification to Agora.

Votes (partial)

Each vote cast emits a VoteCast or VoteCastWithParams event, same as with previous implementations.

Since GovernorV6 voters can cast votes not just with their normal delegations, but also via Alligator contract using partial delegations. As a result clients should be aware that multiple VoteCast events can be emitted for the same voter and proposal.

Proposal types and approval thresholds

GovernorV6 introduced proposal types, which define quorum and approval threshold based on the type of the proposal.

Proposal types are stored in the ProposalTypesConfigurator contract.

Proposal types can be tracked from ProposalTypeSet events or directly from the proposalTypes(uint256 proposalTypeId) function.

Values are scaled by 1e4, so that

Proposals by default use proposal type with id 0, currently with quorum and approval threshold at 50%.

Quorum, onchain read function

From GovernorV6, quorum accepts proposalId as params instead of blockNumber.