Skip to main content

Overview

The FolioGovernor contract provides on-chain governance for Folio instances. It extends OpenZeppelin’s Governor framework with dynamic proposal thresholds based on token supply.

Key Features

  • Dynamic Proposal Threshold: Percentage-based threshold that scales with supply
  • Timelock Integration: All proposals execute through a timelock
  • Quorum Control: Configurable quorum as percentage of supply
  • Vote Delegation: Users can delegate voting power
  • Simple Counting: For/Against/Abstain voting

Architecture

FolioGovernor extends multiple OpenZeppelin governor modules:
FolioGovernor.sol

Initialization

IVotes
Voting token (typically StakingVault or Folio with voting enabled)
TimelockControllerUpgradeable
Timelock contract for proposal execution
uint48
Delay in seconds before voting starts after proposal
uint32
Duration in seconds that voting remains open
uint256
Percentage of supply required to propose (e.g., 0.01e18 = 1%)
uint256
Percentage of supply required for quorum (e.g., 0.04e18 = 4%)
FolioGovernor.sol

Governance Parameters

Proposal Threshold

The number of tokens required to create a proposal is dynamically calculated:
FolioGovernor.sol
The threshold is calculated as a percentage of the previous block’s supply, preventing manipulation through same-block minting.

Quorum

Quorum is calculated using the same percentage-based approach:
FolioGovernor.sol
uint256
E.g., 0.04e18 for 4% quorum requirement
uint256
default:"1e18"
Fixed at 1e18 for 18-decimal precision

Proposal Lifecycle

1. Create Proposal

Example Proposal

2. Voting Delay

After creation, there’s a delay before voting begins:
This delay allows users to acquire tokens and delegate voting power before the vote starts.

3. Active Voting

During the voting period, token holders can vote:
Cast Vote

4. Queue in Timelock

Successful proposals must be queued:
Queue Proposal

5. Execute After Timelock

Once the timelock delay passes:
Execute Proposal

Proposal States

Proposal States
state
Proposal created, waiting for voting delay
state
Voting is open
state
Vote passed, ready to be queued
state
In timelock, waiting for execution delay
state
Successfully executed

Voting Power

Token-Based Voting

Voting power comes from the voting token (IVotes):
Check Voting Power
Voting power is snapshotted at the proposal creation block to prevent double-voting.

Delegation

Users can delegate their voting power:
Delegate Votes
Tokens do not have voting power until delegated (even to yourself).

Timelock Integration

Execution Delay

All proposals execute through a timelock:
Timelock Flow

Cancellation Rights

Timelock guardians can cancel malicious proposals:
Guardian Cancel

Admin Functions

Governor settings can be updated via governance:

Set Voting Delay

FolioGovernor.sol

Set Voting Period

FolioGovernor.sol

Set Proposal Threshold

FolioGovernor.sol
Proposal threshold cannot exceed 100% (1e18). This prevents locking governance.

Update Quorum

FolioGovernor.sol

View Functions

Get Proposal State

FolioGovernor.sol

Check Voting

FolioGovernor.sol

Get Votes

FolioGovernor.sol

Events

event
Emitted when a new proposal is createdParameters:
  • proposalId - Unique proposal identifier
  • proposer - Address that created the proposal
  • targets - Target contract addresses
  • values - ETH values for calls
  • signatures - Function signatures
  • calldatas - Encoded function calls
  • startBlock - Voting start block
  • endBlock - Voting end block
  • description - Proposal description
event
Emitted when a vote is castParameters:
  • voter - Address that voted
  • proposalId - Proposal ID
  • support - Vote type (0=Against, 1=For, 2=Abstain)
  • weight - Voting power used
  • reason - Vote reason (if provided)
event
Emitted when proposal is queued in timelockParameters:
  • proposalId - Proposal ID
  • eta - Earliest execution time
event
Emitted when proposal is executedParameters:
  • proposalId - Proposal ID

Error Handling

error
Thrown when trying to set proposal threshold above 100%

Best Practices

Proposal Creation
  • Provide clear, detailed descriptions
  • Test proposal calldata on testnet first
  • Consider timelock delay in planning
  • Communicate with community before proposing
Voting
  • Delegate your tokens to activate voting power
  • Vote early to signal direction
  • Provide reasoning for transparency
  • Monitor proposals actively
Security
  • Use multisig or DAO for guardian role
  • Set reasonable timelock delays (2-7 days typical)
  • Keep proposal threshold accessible but meaningful (0.1-1%)
  • Monitor for malicious proposals