Skip to content
Last updated: February 06, 2026

SCWE-100: Missing Quorum Validation in Governance Execution

Stable Version v1.0

This content is in the version-(v1.0) and still under active development, so it is subject to change any time (e.g. structure, IDs, content, URLs, etc.).

Send Feedback

Relationships

Description

Governance systems that allow proposal execution based solely on vote counts (e.g., "for" > "against") without enforcing a minimum participation threshold (quorum) can execute proposals with negligible community participation. A proposal may "pass" with only a handful of votes if quorum is not checked, allowing a small group or attacker with accumulated tokens to push through changes that lack legitimate community mandate.

Remediation

  • Enforce a minimum quorum (e.g., percentage of total supply or voting power) before allowing execution.
  • Require both vote majority and quorum to be satisfied; revert execution if quorum is not met.
  • Consider time-weighted or participation-based quorum to prevent last-block manipulation.

Examples

Vulnerable

pragma solidity ^0.8.0;

contract VulnerableGov {
    mapping(uint256 => uint256) public forVotes;
    mapping(uint256 => uint256) public againstVotes;
    uint256 public totalSupply;

    function execute(uint256 proposalId) external {
        require(forVotes[proposalId] > againstVotes[proposalId], "proposal failed");
        // No quorum check — can execute with 2 for, 1 against even if totalSupply is 1M
        _executeProposal(proposalId);
    }
}

Fixed

pragma solidity ^0.8.0;

contract SecureGov {
    mapping(uint256 => uint256) public forVotes;
    mapping(uint256 => uint256) public againstVotes;
    uint256 public totalSupply;
    uint256 public constant QUORUM_BPS = 400; // 4%

    function execute(uint256 proposalId) external {
        uint256 totalVotes = forVotes[proposalId] + againstVotes[proposalId];
        require(forVotes[proposalId] > againstVotes[proposalId], "proposal failed");
        require(totalVotes * 10000 >= totalSupply * QUORUM_BPS, "quorum not met");
        _executeProposal(proposalId);
    }
}