Proposing and voting on actions

The Powers protocol provides a governance mechanism for actions that require community consensus. This is implemented through a proposal and voting system, similar to other governance protocols but with key differences in role-based access control and law-specific validation.

When to Use Proposals

Proposals should be used when:

  • An action requires community consensus

  • The law's conditions specify a quorum > 0

  • The action needs to be transparent and auditable

  • Multiple stakeholders need to vote on the action

Proposal Flow

1. Creating a Proposal

A user creates a proposal by calling the propose function in Powers.sol with:

  • lawId: The ID of the law that will be called

  • lawCalldata: The encoded function call data

  • nonce: A random nonce to ensure uniqueness

  • uriAction: A description or URI to proposal details

The function:

  • Verifies the law is active

  • Checks if the caller has the appropriate role

  • Validates that the law requires voting (quorum > 0)

  • Creates a unique actionId by hashing lawId, lawCalldata, and nonce

  • Stores the proposal details in the _actions mapping

  • Sets the voting period based on the law's conditions

  • Emits a ProposedActionCreated event

2. Voting Period

Once created, the proposal enters a voting period where:

  • The voting period is determined by the law's votingPeriod condition

  • Voting starts at the block where the proposal was created

  • Voting ends at voteStart + voteDuration

  • During this period, eligible voters can cast their votes

3. Casting Votes

Voters can cast votes in two ways:

  1. castVote(actionId, support): Simple vote

  2. castVoteWithReason(actionId, support, reason): Vote with explanation

Where support can be:

  • 0: Against

  • 1: For

  • 2: Abstain

The voting process:

  • Verifies the proposal is active

  • Checks if the voter has the appropriate role

  • Ensures the voter hasn't voted before

  • Records the vote in the proposal's state

  • Emits a VoteCast event

4. Proposal Resolution

A proposal can end in several states:

Success

  • Voting period has ended

  • Quorum has been reached (_quorumReached returns true)

  • Required threshold of "For" votes has been met (_voteSucceeded returns true)

  • State changes to Succeeded

Defeat

  • Voting period has ended

  • Either quorum wasn't reached or required threshold wasn't met

  • State changes to Defeated

Cancellation

  • Original proposer can cancel the proposal using cancel

  • State changes to Cancelled

Important Considerations

1. Role-Based Access

  • Only accounts with the appropriate role can propose

  • Only accounts with the appropriate role can vote

  • Role checks happen at both proposal creation and voting

2. Quorum and Thresholds

  • Quorum is defined in the law's conditions

  • Success threshold is defined in the law's conditions

  • Both are expressed as percentages of total role holders

3. Gas Optimization

  • Votes are stored as uint32 (not uint256) since they're not weighted

  • Proposal data is stored on-chain for transparency

  • Failed proposals still consume gas up to the point of failure

4. Common Pitfalls

  • Proposals cannot be modified after creation

  • Votes cannot be changed once cast

  • Proposals cannot be re-submitted if cancelled

  • The same action with the same nonce cannot be proposed twice

  • Voting period is fixed and cannot be extended

5. Security Considerations

  • Role assignments should be carefully managed

  • Law conditions should be well-thought-out

  • Quorum and threshold values should be appropriate for the community size

  • Proposal descriptions should be clear and detailed

Last updated