Skip to content

Token Governance System

Introduction

Token governance systems enable decentralized decision-making in blockchain projects. This tutorial explains how to implement a comprehensive governance system using smart contracts.

Features

  • Proposal creation and voting
  • Token-weighted voting power
  • Time-locked execution
  • Delegation mechanism
  • Vote tracking and history

Contract Implementation

solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";

contract GovernanceToken is ERC20, Ownable {
    constructor(string memory name, string memory symbol)
        ERC20(name, symbol) {}
    
    function mint(address to, uint256 amount) external onlyOwner {
        _mint(to, amount);
    }
}

contract Governance is ReentrancyGuard {
    using SafeMath for uint256;

    // Governance token
    GovernanceToken public token;
    
    // Proposal struct
    struct Proposal {
        uint256 id;
        address proposer;
        string description;
        uint256 startBlock;
        uint256 endBlock;
        uint256 forVotes;
        uint256 againstVotes;
        bool executed;
        mapping(address => Receipt) receipts;
    }

    // Vote receipt
    struct Receipt {
        bool hasVoted;
        bool support;
        uint256 votes;
    }

    // Voting parameters
    uint256 public votingDelay = 1;      // blocks before voting starts
    uint256 public votingPeriod = 17280; // blocks for voting (approximately 3 days)
    uint256 public proposalThreshold;     // minimum tokens to create proposal
    uint256 public quorumVotes;          // minimum votes for proposal to pass

    // Proposal tracking
    mapping(uint256 => Proposal) public proposals;
    uint256 public proposalCount;

    // Events
    event ProposalCreated(uint256 id, address proposer, string description);
    event VoteCast(address voter, uint256 proposalId, bool support, uint256 votes);
    event ProposalExecuted(uint256 id);

    constructor(
        address _token,
        uint256 _proposalThreshold,
        uint256 _quorumVotes
    ) {
        token = GovernanceToken(_token);
        proposalThreshold = _proposalThreshold;
        quorumVotes = _quorumVotes;
    }

    // Create a proposal
    function propose(string memory description) external returns (uint256) {
        require(
            token.balanceOf(msg.sender) >= proposalThreshold,
            "Insufficient tokens to propose"
        );

        uint256 startBlock = block.number.add(votingDelay);
        uint256 endBlock = startBlock.add(votingPeriod);

        proposalCount++;
        Proposal storage proposal = proposals[proposalCount];
        proposal.id = proposalCount;
        proposal.proposer = msg.sender;
        proposal.description = description;
        proposal.startBlock = startBlock;
        proposal.endBlock = endBlock;

        emit ProposalCreated(proposalCount, msg.sender, description);
        return proposalCount;
    }

    // Cast a vote
    function castVote(uint256 proposalId, bool support) external {
        require(state(proposalId) == ProposalState.Active, "Voting is closed");
        Proposal storage proposal = proposals[proposalId];
        Receipt storage receipt = proposal.receipts[msg.sender];
        require(!receipt.hasVoted, "Already voted");

        uint256 votes = token.balanceOf(msg.sender);
        require(votes > 0, "No voting power");

        if (support) {
            proposal.forVotes = proposal.forVotes.add(votes);
        } else {
            proposal.againstVotes = proposal.againstVotes.add(votes);
        }

        receipt.hasVoted = true;
        receipt.support = support;
        receipt.votes = votes;

        emit VoteCast(msg.sender, proposalId, support, votes);
    }

    // Execute a proposal
    function execute(uint256 proposalId) external {
        require(state(proposalId) == ProposalState.Succeeded, "Proposal not passed");
        Proposal storage proposal = proposals[proposalId];
        proposal.executed = true;
        emit ProposalExecuted(proposalId);
        // Execute proposal actions
    }

    // Get proposal state
    function state(uint256 proposalId) public view returns (ProposalState) {
        require(proposalId <= proposalCount && proposalId > 0, "Invalid proposal");
        Proposal storage proposal = proposals[proposalId];

        if (proposal.executed) {
            return ProposalState.Executed;
        }

        if (block.number <= proposal.startBlock) {
            return ProposalState.Pending;
        }

        if (block.number <= proposal.endBlock) {
            return ProposalState.Active;
        }

        if (proposal.forVotes <= proposal.againstVotes || 
            proposal.forVotes < quorumVotes) {
            return ProposalState.Defeated;
        }

        return ProposalState.Succeeded;
    }

    // Get voting power at a specific block
    function getVotes(address account, uint256 blockNumber) 
        public view returns (uint256) 
    {
        return token.balanceOf(account);
    }
}

// Proposal states
enum ProposalState {
    Pending,
    Active,
    Defeated,
    Succeeded,
    Executed
}

Core Concepts

1. Governance Token

The governance token represents voting power in the system:

  • One token equals one vote
  • Tokens can be delegated
  • Token balance determines proposal rights
  • Voting power is snapshot at proposal creation

2. Proposal Lifecycle

A proposal goes through several states:

  1. Pending - Waiting for voting to start
  2. Active - Open for voting
  3. Defeated - Failed to reach quorum or majority
  4. Succeeded - Passed but not executed
  5. Executed - Successfully implemented

3. Voting Mechanism

The voting process includes:

  • Token-weighted voting
  • Quorum requirements
  • Time-bound voting periods
  • Vote delegation options

4. Execution Process

Proposal execution involves:

  • Timelock delay
  • Security checks
  • Action implementation
  • State updates

Security Considerations

  1. Access Control

    • Proposal thresholds
    • Voting power verification
    • Execution permissions
    • Delegation rules
  2. Time Management

    • Voting delays
    • Voting periods
    • Execution timelock
    • Block number tracking
  3. Vote Integrity

    • Double voting prevention
    • Vote weight calculation
    • Delegation tracking
    • Snapshot mechanism
  4. Economic Security

    • Quorum requirements
    • Proposal thresholds
    • Vote locking
    • Incentive alignment

Best Practices

  1. Implementation

    • Use standard libraries
    • Implement safeguards
    • Follow patterns
    • Document thoroughly
  2. Testing

    • Unit tests
    • Integration tests
    • Scenario testing
    • Security audits
  3. Deployment

    • Parameter setting
    • Gradual rollout
    • Emergency procedures
    • Monitoring systems
  4. Maintenance

    • Upgrades
    • Parameter adjustments
    • Bug fixes
    • Community feedback

Extended Features

  1. Advanced Voting

    • Quadratic voting
    • Ranked choice
    • Vote delegation
    • Vote escrow
  2. Proposal Enhancement

    • Multiple actions
    • Conditional execution
    • Batch proposals
    • Amendment process
  3. Integration

    • Multi-chain governance
    • DAO frameworks
    • DeFi protocols
    • NFT voting
  4. Analytics

    • Voting patterns
    • Participation metrics
    • Proposal success rates
    • Voter behavior

FAQ

General Questions

Q: What is token governance?

A: Token governance is a system that enables:

  • Decentralized decision-making
  • Community participation
  • Transparent voting
  • Automated execution

Q: Why use token governance?

A: Benefits include:

  • Community ownership
  • Decentralized control
  • Transparent decisions
  • Automated enforcement

Technical Questions

Q: How to handle vote delegation?

A: Delegation involves:

  • Power transfer tracking
  • Delegation history
  • Vote weight calculation
  • Revocation mechanism

Q: What about vote manipulation?

A: Prevention measures:

  • Snapshot mechanisms
  • Vote locking
  • Quorum requirements
  • Activity monitoring

Implementation Questions

Q: How to set parameters?

A: Consider these factors:

  • Community size
  • Token distribution
  • Voting patterns
  • Security needs

Q: What about upgrades?

A: Upgrade strategy should include:

  • Proxy patterns
  • Testing procedures
  • Community approval
  • Gradual rollout

Released under the MIT License by Vogeb.