Run-time Chain Upgradability

GovernanceV1 Contract

Overview

The GovernanceV1 contract is a sophisticated decentralized governance system that allows token holders to create and vote on proposals, with an additional council oversight layer for execution approval. The contract supports both BDAG and ERC20 token staking.

Key Features

  • Proposal Creation & Voting: Users can create proposals and vote with staked tokens/BDAG

  • Council Oversight: A council of trusted members provides an additional layer of approval

  • Stake-based Voting: Voting power is determined by the amount staked

  • Upgradeable: Uses OpenZeppelin's UUPS upgrade pattern

  • Security Features: Reentrancy protection, pausable functionality, and access controls


Contract Roles

1. DEFAULT_ADMIN_ROLE:

  • Can grant/revoke all roles, including ADMIN_ROLE.

  • It’s the “super admin”.

2. ADMIN_ROLE

  • Permissions: Ultimate authority over the contract

  • Can do:

  • Grant/revoke all other roles

  • Add/remove council members

  • Change voting parameters

  • Pause/unpause the contract

  • Authorize contract upgrades

3. PROPOSER_ROLE

  • Permissions: Can create new proposals

  • Requirements: Must stake the minimum threshold amount

4. EXECUTOR_ROLE

  • Permissions: Can execute approved proposals

  • Requirements: Proposal must pass council voting

5. COUNCIL_ROLE

  • Permissions: Council members who vote on proposal execution

  • Requirements: Minimum 5 council members required for the system to function

How Governance Works

Phase 1: Proposal Creation

  1. Proposer creates a proposal with a description

  2. Stake Required: Must deposit minimum threshold (BDAG or tokens)

  3. Voting Period: Starts immediately and runs for the set voting period

Phase 2: Community Voting

  1. Duration: Configured voting period (1 hour to 15 days)

  2. Participation: Any user can vote by staking tokens/BDAG

  3. Vote Types: FOR or AGAINST

  4. Requirements:

  5. Quorum must be met (total votes ≥ quorum threshold)

  6. Majority must vote FOR

Phase 3: Council Review (if proposal succeeds)

  1. Trigger: Any council member can start council voting

  2. Duration: Configured council voting window (1 hour to 7 days)

  3. Vote Types: FOR, AGAINST, or ABSTAIN

  4. Execution Requirements:

  5. 60% of active votes (FOR + AGAINST) must be FOR

  6. Abstain votes don't count toward quorum

Phase 4: Execution

  1. Who: Users with EXECUTOR_ROLE

  2. When: After council voting period ends and requirements are met

  3. Result: Proposal is executed and proposer gets deposit back


User Actions Guide

Creating a Proposal

Requirements:

  • Have PROPOSER_ROLE

  • Stake minimum threshold amount

  • Description ≤ 256 characters

Steps:

// For BDAG staking

propose("Proposal description") { value: stakingAmount }

// For ERC20 token staking

// 1. First approve tokens

token.approve(governanceContract, stakingAmount)

// 2. Then propose

propose("Proposal description")

Voting on Proposals

Requirements:

  • Proposal must be in Active state

  • Haven't voted on this proposal yet

  • Have tokens/BDAG to stake

Steps:

// Vote FOR with BDAG

vote(proposalId, VoteType.For, amount) { value: amount }

// Vote AGAINST with tokens

// 1. Approve tokens first

token.approve(governanceContract, amount)

// 2. Then vote

vote(proposalId, VoteType.Against, amount)

Council Voting (Council Members Only)

Requirements:

  • Have COUNCIL_ROLE

  • Proposal must be in CouncilVoting state

  • Haven't voted on this proposal yet

Steps:

// Vote options: CouncilType.Against (0), CouncilType.For (1), CouncilType.Abstain (2)

councilVoteToExecute(proposalId, CouncilType.For)

Withdrawing Stakes

When you can withdraw:

  • Proposal failed during voting

  • Proposal was canceled

  • Proposal was executed

  • Proposal succeeded but no council voting started within 7 days

  • Council voting failed

Steps:

withdrawStake(proposalId)

Withdrawing Proposer Deposit

When proposers can withdraw:

  • Proposal failed during community voting

  • Proposal succeeded but no council voting started within 7 days

Steps:

withdrawProposerDeposit(proposalId)


Proposal States Explained

State

Description

What Users Can Do

Pending

Before voting starts

Wait for voting to begin

Active

Community voting period

Vote with stakes

Succeeded

Passed community vote

Council can start council voting

Failed

Failed community vote

Withdraw stakes

CouncilVoting

Council review phase

Council members vote, others wait

Executed

Successfully executed

Withdraw stakes

Canceled

Proposal canceled

Withdraw stakes (proposer gets partial refund)


Important Parameters

Voting Parameters

  • Voting Period: 1 hour to 15 days

  • Council Voting Window: 1 hour to 7 days

  • Minimum Proposal Threshold: 0.1 BDAG (configurable for tokens)

  • Council Execution Quorum: 60% of active votes must be FOR

Limits

  • Maximum Description Length: 256 characters

  • Maximum Council Size: 100 members

  • Minimum Council Members: 5 (required for functionality)

  • Slash Percentage: 50% (applied to canceled proposal deposits)

Timeouts

  • Council Voting Deadline: 7 days after proposal ends to start council voting

  • Stake Withdrawal: Available immediately after final state is reached


Key Functions Reference

Core Functions

  • propose(description) - Create a new proposal

  • vote(proposalId, voteType, amount) - Vote on a proposal

  • startCouncilVoting(proposalId) - Start council review phase

  • councilVoteToExecute(proposalId, councilVote) - Council member votes

  • execute(proposalId) - Execute approved proposal

  • cancel(proposalId) - Cancel proposal (admin/council only)

Stake Management

  • withdrawStake(proposalId) - Withdraw voting stakes

  • withdrawProposerDeposit(proposalId) - Withdraw proposal deposit

View Functions

  • getProposal(proposalId) - Get complete proposal information

  • getProposalState(proposalId) - Get current proposal state

  • canExecute(proposalId) - Check if proposal can be executed

  • getCouncilMembers() - Get list of council members

  • getCouncilVoteInfo(proposalId, member) - Get council member's vote


Security Features

Access Controls

  • Role-based permissions for different actions

  • Multi-signature style council approval for execution

  • Proposer deposits to prevent spam

Economic Security

  • Stake-based voting aligns incentives

  • Slashing mechanism for canceled proposals (50% penalty)

  • Deposit requirements prevent frivolous proposals

Technical Security

  • Reentrancy protection on all state-changing functions

  • Pausable functionality for emergency situations

  • Upgradeable design for future improvements

  • Safe token transfers using OpenZeppelin libraries


Common Scenarios

Scenario 1: Successful Proposal Flow

  1. User creates proposal with required stake

  2. Community votes and proposal passes quorum + majority

  3. Council member starts council voting

  4. Council votes and 60%+ vote FOR

  5. Executor executes the proposal

  6. All participants withdraw their stakes

Scenario 2: Failed Proposal

  1. User creates proposal

  2. Community votes but fails to meet quorum or majority votes AGAINST

  3. Proposer and voters can withdraw stakes immediately

  4. Proposer gets full deposit back

Scenario 3: Council Rejection

  1. Proposal passes community voting

  2. Council voting starts but fails to get 60% FOR votes

  3. Proposal can be canceled after council voting ends

  4. Proposer gets 50% deposit back (50% slashed to treasury)

  5. Voters can withdraw full stakes


Best Practices

For Proposers

  1. Write clear, concise descriptions (≤256 characters)

  2. Ensure you meet the threshold before proposing

  3. Monitor your proposal through all phases

  4. Withdraw deposits promptly when eligible

For Voters

  1. Vote with appropriate amounts based on conviction

  2. Monitor proposal progress to know when to withdraw

  3. Participate actively in governance for healthy ecosystem

  4. Understand the risks - stakes are locked until completion

For Council Members

  1. Vote responsibly on execution decisions

  2. Start council voting promptly for successful proposals

  3. Consider community sentiment when making decisions

  4. Maintain active participation to ensure system functionality


Error Messages & Troubleshooting

Common Errors

  • "Invalid proposal" - Proposal ID doesn't exist

  • "Not active" - Trying to vote on non-active proposal

  • "Already voted" - Attempting to vote twice on same proposal

  • "Insufficient BDAG/tokens" - Not enough stake provided

  • "Cannot withdraw yet" - Proposal not in final state

  • "Cannot execute" - Council voting requirements not met


Integration Guide for Developers

Contract Address & ABI

  • Deploy the contract with proper initialization parameters

  • Grant appropriate roles to initial users

  • Set up proper monitoring for governance events

Event Monitoring

Key events to monitor:

  • ProposalCreated - New proposals

  • VoteCast - Voting activity

  • CouncilVotingStarted - Council phase begins

  • CouncilExecutionVote - Council member votes

  • ProposalExecuted - Successful execution

  • ProposalCanceled - Canceled proposals

This governance system provides a robust framework for decentralized decision-making with appropriate checks and balances through the council system.

Last updated

Was this helpful?