Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
LABS
Guides

Launching a Quadratic Voting Implementation

A technical tutorial for implementing quadratic voting in a smart contract. Covers the mathematical model, Sybil resistance integration, vote cost calculation, and gas optimization strategies.
Chainscore Š 2026
introduction
IMPLEMENTATION GUIDE

Launching a Quadratic Voting Implementation

A technical walkthrough for developers building a secure and effective quadratic voting system, from core mechanics to smart contract considerations.

Quadratic voting (QV) is a collective decision-making mechanism where participants allocate a budget of voice credits to express the intensity of their preferences. Unlike one-person-one-vote, QV uses a quadratic cost function: the cost to cast n votes for a single proposal is n². This structure makes it exponentially more expensive to concentrate votes, which mitigates Sybil attacks and whale dominance, promoting more equitable outcomes. It's widely used in decentralized governance, like Gitcoin Grants for public goods funding, where it helps surface projects with broad, genuine community support rather than those backed by a few large donors.

Implementing QV begins with defining the voting parameters. You must decide on the total voice credit budget per voter (e.g., 100 credits), the voting period, and the mechanism for voter authentication (e.g., token-gated, proof-of-personhood). The core logic calculates the cost of a voter's allocation. If a voter spreads 5 credits to option A and 10 credits to option B, the cost is 5² + 10² = 125 credits, exceeding a 100-credit budget and thus invalid. This check is fundamental to the contract's vote function. Off-chain, a user interface should clearly show the quadratic cost of potential allocations in real-time.

For on-chain implementation, a smart contract must securely manage the credit accounting. A basic Solidity structure includes mapping voters to their remaining credits and proposals to their received vote power (the square root of the sum of cast credits). The critical function is castVotes(uint[] memory proposalIds, uint[] memory credits), which must: 1) verify the sender has enough budget (sum(credits[i]²) <= remainingCredits[sender]), 2) update the vote power for each proposal (votePower[proposalId] += sqrt(credits[i])), and 3) deduct the total cost from the voter's balance. Use OpenZeppelin's libraries for secure math operations to prevent overflows.

Several design choices impact security and usability. Commit-reveal schemes can prevent tactical voting by hiding votes until the reveal phase. Batching votes with Merkle trees, as used by clr.fund, reduces gas costs. You must also decide how to handle the final tally: the winning proposal can be the one with the highest sum of square roots, or you can implement a quadratic funding model where a matching pool is distributed proportionally to the square of the votes received. Auditing is non-negotiable; consider formal verification for the cost calculation logic, as errors here break the system's economic guarantees.

After deployment, focus on voter education and data transparency. Provide clear documentation explaining why a vote for 4 credits costs 16 from their budget. Use subgraphs or indexers to make vote histories and results easily queryable. Analyze round data to detect anomalies or collusion. Successful QV implementations, like those coordinating millions in ecosystem funding, demonstrate that technical rigor must be paired with community understanding. The code is just the first step; fostering informed participation is what unlocks quadratic voting's potential for fairer governance and resource allocation.

prerequisites
QUADRATIC VOTING

Prerequisites and Setup

Before deploying a quadratic voting system, you need the right tools, accounts, and a foundational understanding of the underlying smart contract architecture.

The core technical prerequisite is a development environment for writing and testing smart contracts. You will need Node.js (v18 or later) and a package manager like npm or yarn. For Ethereum-based implementations, the Hardhat or Foundry frameworks are essential for compiling, deploying, and testing your contracts. You should also install the OpenZeppelin Contracts library, which provides secure, audited base contracts for voting and governance. A basic understanding of Solidity and the ERC-20 token standard is required, as most quadratic voting systems use a governance token for voting power.

You will need access to blockchain networks for deployment and testing. Set up a MetaMask wallet and fund it with test ETH. For development, use a local Hardhat network or public testnets like Sepolia or Goerli. You'll also need an Alchemy or Infura account to get RPC endpoints for connecting to these networks. For on-chain data and event listening, consider setting up The Graph for subgraph development or using an indexer like Covalent. These tools are crucial for building a frontend that displays real-time voting results and proposal data.

The smart contract foundation typically involves three main components: a voting token (ERC-20 or ERC-1155 for non-transferable votes), a proposal manager contract to create and track votes, and a quadratic voting logic contract that calculates costs and tallies results. The voting logic implements the key formula: cost = (votes)^2. Use OpenZeppelin's Votes and Governor contracts as a starting point for token-weighted governance, then extend them with custom quadratic math. Always write comprehensive tests for edge cases, like preventing users from exceeding their token balance when calculating quadratic costs.

For the application frontend, you'll need a framework like Next.js or Vite and a Web3 library such as wagmi and viem. These libraries simplify connecting wallets, reading contract state, and sending transactions. You must design your UI to clearly explain the quadratic cost to voters—showing how a vote of 2 costs 4 tokens, a vote of 3 costs 9 tokens, and so on. Integrate a block explorer API like Etherscan to verify transactions. Finally, plan your deployment strategy, including contract verification and frontend hosting on platforms like Vercel or Fleek.

mathematical-model
IMPLEMENTATION GUIDE

Launching a Quadratic Voting Implementation

A technical guide to implementing the quadratic voting mathematical model for governance, funding, and collective decision-making.

Quadratic voting (QV) is a collective decision-making mechanism where participants allocate a budget of voice credits to express the intensity of their preferences. The core mathematical model dictates that the cost of additional votes for a single option increases quadratically. For example, casting 1 vote costs 1 credit, 2 votes cost 4 credits, and 3 votes cost 9 credits. This cost = votes² formula is designed to prevent a single wealthy participant from dominating an outcome, as the cost of marginal influence escalates rapidly. The model aims to maximize the sum of the square roots of the credits spent, aligning outcomes more closely with aggregate welfare than simple one-person-one-vote systems.

To implement QV, you first define the voting parameters: the total credit allocation per voter, the list of proposals or options, and the voting period. A common approach is to use a commit-reveal scheme to prevent strategic voting based on early results. Voters submit a cryptographic commitment of their votes, and only reveal them after the voting deadline. The on-chain verification then calculates the sum of square roots: sum(sqrt(votes_i)) for each option i. The winning option is the one with the highest sum. Smart contracts for QV, like those used by Gitcoin Grants for funding public goods, manage credit distribution, vote tallying, and result finalization autonomously.

A critical implementation detail is preventing sybil attacks, where a user creates multiple identities to gain more voice credits. This requires a robust identity verification layer, such as proof-of-personhood protocols like Worldcoin or BrightID, or binding votes to a soulbound token (SBT). The cost function must be enforced programmatically; each vote transaction should check that total_cost = sum(votes_option²) does not exceed the voter's remaining credit balance. Libraries like MACI (Minimal Anti-Collusion Infrastructure) can be integrated to add privacy and collusion resistance to the QV process, ensuring voters cannot prove how they voted to third parties.

For developers, a basic QV smart contract structure in Solidity involves a Voting contract that maps voter addresses to their remaining credits and a nested mapping for their votes per proposal. The core function, castVotes(uint[] memory proposalIds, uint[] memory voteCounts), would iterate through the arrays, calculate the quadratic cost, and deduct it from the voter's balance. After the reveal phase, a tallyResults() function calculates the sum of square roots for each proposal using a fixed-point math library like ABDKMathQuad for precision, as Ethereum does not natively support square root operations for integers.

Testing and auditing are paramount. Use frameworks like Foundry or Hardhat to simulate voting scenarios, including edge cases where a voter exhausts credits or attempts to overflow calculations. Analyze the economic incentives: does the implemented model truly make it prohibitively expensive for a whale to swing a vote? Deploying a QV system often involves a governance token for credit distribution, requiring careful tokenomics design. Real-world data from platforms like Gitcoin shows QV effectively funds a broader set of projects compared to linear voting, making it a powerful tool for DAOs, grant committees, and any community seeking fairer resource allocation.

sybil-resistance-options
QUADRATIC VOTING

Sybil Resistance Mechanisms

Quadratic voting (QV) is a governance mechanism that allocates voting power based on the square root of a user's token holdings, reducing the influence of large token whales. This guide covers the core concepts and practical steps for implementing a QV system on-chain.

01

Understanding Quadratic Voting Math

The core formula calculates a voter's power as the square root of their token balance. For example, a user with 100 tokens gets 10 votes (√100), while a user with 10,000 tokens gets only 100 votes (√10,000). This drastically reduces whale dominance compared to linear (1 token = 1 vote) systems. Key considerations include:

  • Cost function: The total cost for n votes is n², making additional votes exponentially more expensive.
  • Precision: Use fixed-point math libraries (like ABDKMath64x64 or PRBMath) to handle square roots accurately on-chain.
  • Rounding: Decide on rounding rules (floor, ceil) for the square root result to prevent manipulation.
02

Designing the Voting Contract

Build a smart contract that enforces quadratic cost and vote allocation. Essential functions include:

  • getVotingPower(address voter): Returns the square root of the voter's token balance at a specific snapshot block.
  • castVote(uint proposalId, uint voteAmount): Deducts a quadratic cost (voteAmount²) from the voter's power.
  • Security checks: Prevent double voting and ensure votes cannot exceed calculated power.
  • Gas optimization: Store vote power snapshots to avoid expensive square root calculations in every transaction. Use OpenZeppelin's Snapshot module or a similar pattern for efficient state management.
04

Mitigating Sybil Attacks with Proof of Personhood

Pure token-based QV is vulnerable to Sybil attacks where users split funds across many addresses. Combine QV with proof-of-personhood (PoP) to ensure one-human-one-identity. Implementation options:

  • BrightID: Integrate verification to grant a base voting power multiplier only to verified humans.
  • Worldcoin: Use the World ID protocol for global, privacy-preserving proof of personhood.
  • Gitcoin Passport: Aggregate decentralized identity stamps to compute a unique humanness score. This creates a hybrid model: Voting Power = sqrt(balance) * PoP_multiplier.
05

Auditing and Cost Analysis

Before mainnet deployment, conduct thorough audits focusing on:

  • Math precision: Ensure square root calculations are correct and not susceptible to rounding attacks.
  • Gas costs: Profile the gas consumption of voting functions; a complex QV contract can be expensive.
  • Vote buying: Assess risks of off-chain vote markets and consider implementing commit-reveal schemes or minimum vote duration to mitigate.
  • Third-party audit: Engage firms like OpenZeppelin, Trail of Bits, or Code4rena to review the contract logic and economic assumptions.
contract-architecture
CORE SMART CONTRACT ARCHITECTURE

Launching a Quadratic Voting Implementation

A technical guide to building a secure and efficient quadratic voting system on Ethereum, covering contract design, cost optimization, and attack mitigation.

Quadratic voting is a governance mechanism where the cost of votes increases quadratically with the number of votes cast, mathematically expressed as cost = votes². This design, popularized by projects like Gitcoin Grants, mitigates whale dominance by making it exponentially expensive to concentrate voting power. A core smart contract must manage three primary functions: registering proposals, distributing a voting credit allowance (often called voice credits) to participants, and tallying results using the quadratic formula. The contract state typically tracks a mapping of address => uint256 for remaining credits and a nested mapping of proposalId => address => uint256 for votes cast.

The most critical architectural decision is the vote funding model. You can implement a one-time grant of credits (e.g., 99 per user), a continuous stream via a vesting contract, or a purchase mechanism using a bonding curve. For cost efficiency, avoid storing individual vote counts on-chain during the voting period. Instead, have users submit a signed message (or commit) of their vote allocation. Only after the voting deadline should they reveal their votes, submitting the data needed for the contract to verify the commitment and calculate the quadratic cost. This commit-reveal scheme prevents front-running and reduces gas fees for voters.

A secure implementation must guard against common attacks. Use OpenZeppelin's EIP-712 typed structured data signing for commitments to prevent replay attacks across chains. Implement a synchronization barrier to ensure users cannot vote with credits they have already spent in a previous transaction within the same block. Crucially, the contract must validate the quadratic cost calculation during the reveal phase, ensuring spentCredits = sum(votes_i²) for all a user's votes. Failing to properly validate this allows an attacker to allocate more voting power than their credits permit. Always include a timelock or governance delay on executing winning proposals to allow for community review.

For development and testing, use the @openzeppelin/contracts library for secure primitives and Hardhat or Foundry for your environment. Write comprehensive tests that simulate edge cases: a user trying to reveal an incorrect commitment, voting after the deadline, or exceeding their credit allowance. Estimate gas costs for key functions; a well-optimized reveal function should cost under 150k gas. Once audited, you can deploy using a proxy upgrade pattern (like TransparentUpgradeableProxy) to allow for future fixes. The final contract should emit clear events for VoteCommitted, VoteRevealed, and ProposalTallied for easy off-chain indexing.

gas-optimization
SMART CONTRACT DEVELOPMENT

Gas Optimization Strategies for Quadratic Voting

Implementing quadratic voting on-chain requires careful gas management. This guide covers key optimization techniques to reduce deployment and transaction costs for your voting contracts.

Quadratic voting, where a voter's cost scales quadratically with the number of votes they allocate, introduces computational complexity. On Ethereum and other EVM chains, each operation consumes gas. Inefficient implementations can make voting prohibitively expensive. The primary cost drivers are storage writes, loop iterations over arrays of voters or proposals, and complex mathematical operations like square roots for calculating costs. Optimizing these areas is essential for a usable, cost-effective governance system.

Minimize Storage Operations: Storage (SSTORE) is the most expensive EVM operation. Instead of storing a user's voting power or vote count multiple times, use a single packed storage slot or in-memory calculations. For tracking votes, consider using a mapping(address => uint256) for vote credits and deducting quadratically. Avoid storing entire vote histories on-chain; emit events for transparency and store only the final aggregated results or a cryptographic commitment like a Merkle root.

Optimize Loops and Data Structures: Looping over arrays of participants to calculate totals or check eligibility is a gas trap. Use pull-over-push patterns where voters claim their outcomes, shifting computation cost. For tallying, consider using incremental tallying where the contract maintains a running total that updates with each vote: totalCost += (newVotesSquared - oldVotesSquared). This replaces an O(n) loop with an O(1) update. Use uint256 for all math and beware of overflows—use SafeMath libraries or solidity 0.8.x's built-in checks.

Batch Operations and Gas Refunds: If your design allows, implement batch voting where users can vote on multiple proposals in a single transaction, amortizing the fixed 21,000 gas base cost. Furthermore, leverage storage gas refunds. By clearing storage slots (setting them to zero) when a voting round concludes, you can trigger a gas refund. For example, deleting a mapping of votes for a concluded proposal can offset some of the transaction's cost, though refunds are capped at 50% of the gas used.

Mathematical Optimizations: Calculating sqrt(x) for quadratic cost is expensive. Pre-calculate costs off-chain and have users submit the result with a signature, verifying it cheaply on-chain with ecrecover. Alternatively, use a lookup table for common values or approximate integer square roots like Babylonian method with a fixed number of iterations. For voting power, consider using a simplified model where cost = votes² * basePrice, and store the basePrice as a constant to avoid redundant calculations.

Testing and Tools: Use Foundry's gas snapshot feature (forge snapshot) or Hardhat Gas Reporter to benchmark each function. Profile operations in a local fork. Consider layer-2 solutions like Arbitrum or Optimism for the main voting logic, where gas costs are substantially lower, and use Ethereum mainnet only for final result settlement or high-value execution. Always conduct a gas audit before mainnet deployment to identify unexpected cost spikes.

ARCHITECTURE COMPARISON

Quadratic Voting Implementation Approaches

A technical comparison of common methods for implementing quadratic voting on-chain, focusing on trade-offs for developers.

Implementation FeatureOn-Chain NativeLayer 2 RollupZero-Knowledge Proof

Gas Cost per Vote

$10-50

$0.05-0.50

$2-5 (proof generation)

Vote Privacy

Real-Time Tally Updates

Implementation Complexity

Low

Medium

High

Smart Contract Language

Solidity/Vyper

Solidity/Cairo

Circom/Noir

Trust Assumptions

Ethereum L1 Security

Sequencer + L1 Security

Cryptographic + L1 Security

Time to Finality

~5-15 minutes

~1-5 minutes

~10-20 minutes

Suitable For

Small DAOs, High-Value Votes

General DAOs, Frequent Voting

Private/Corporate Governance

step-by-step-deployment
STEP-BY-STEP DEPLOYMENT GUIDE

Launching a Quadratic Voting Implementation

A practical guide to deploying a secure and functional quadratic voting system on a blockchain, covering smart contract development, frontend integration, and key security considerations.

Quadratic voting (QV) is a collective decision-making mechanism where participants allocate a budget of voice credits to express the intensity of their preferences. Unlike one-person-one-vote, QV uses a quadratic cost function: the cost to cast n votes for a single proposal is n². This design makes it exponentially expensive to concentrate votes, promoting more equitable outcomes by protecting minority interests. It's widely used for decentralized governance, grant funding (like Gitcoin Grants), and preference aggregation. To implement QV, you'll need a smart contract to manage the voting logic, a token or credit system for participants, and a frontend interface for user interaction.

Start by writing and testing the core smart contract. For an Ethereum-based implementation using Solidity and Foundry, you'll define key structures and functions. The contract must securely manage a voting session: initializing proposals, distributing voice credits, processing votes with quadratic cost validation, and tallying results. Critical functions include castVote(uint256 proposalId, uint256 voteAmount) which deducts voteAmount² credits from the user's balance, and a final tallyResults() function. Always use OpenZeppelin libraries for access control and security. Thorough unit and fork tests are essential to prevent vulnerabilities like integer overflow or reentrancy attacks.

After auditing the contract, deploy it to your chosen network. For a test deployment, use Sepolia or Goerli. For production, consider layer-2 solutions like Arbitrum or Optimism to reduce gas costs for users. The deployment script will handle constructor arguments, such as the voting period duration and the total credit supply. Once deployed, verify the contract source code on a block explorer like Etherscan to establish transparency. Store the contract address and ABI securely, as your frontend application will need these to interact with the voting system.

The final step is building or integrating a frontend. Use a framework like Next.js with wagmi and viem for Ethereum interaction. The UI should allow users to connect their wallet (e.g., via MetaMask), view their credit balance, see active proposals, and cast their quadratic votes. Implement real-time updates for vote tallies using an event listener or by polling the contract. For a complete example, you can fork and adapt the frontend from the clr.fund repository, an open-source quadratic funding platform. Ensure your application is responsive and provides clear instructions on how quadratic voting works to guide users through the process.

QUADRATIC VOTING

Common Errors and Troubleshooting

Debugging issues with your quadratic voting smart contracts and frontend. This guide covers common pitfalls in gas estimation, vote calculation, and contract interaction.

Gas estimation failures in quadratic voting contracts are often due to complex state changes or unbounded loops.

Common causes:

  • Iterating over large arrays: If your contract loops through all voters or proposals to calculate results, gas costs scale linearly and can exceed block limits. Use mappings and store intermediate results.
  • Incorrect cost estimation: Frontends like Ethers.js or web3.js may underestimate gas for state-heavy functions. Always add a 20-30% buffer.
  • Revert in logic: Check for require/assert statements failing, such as voting period being closed or insufficient voice credits.

How to fix:

  1. Off-chain computation: Move vote tallying and quadratic calculations off-chain (e.g., using The Graph for indexing) and only commit results on-chain.
  2. Batch operations: Use patterns like checkpoints to incrementally update totals instead of recalculating from scratch.
  3. Test gas usage: Use Hardhat's gasReporter or Foundry's forge test --gas-report to identify expensive functions.
QUADRATIC VOTING

Frequently Asked Questions

Common technical questions and troubleshooting for developers implementing quadratic voting on-chain.

Quadratic funding is a mechanism for optimally allocating a matching pool of funds to public goods based on community contributions. It uses a quadratic formula to calculate the matching amount, where the sum of the square roots of individual contributions is squared. This amplifies the influence of many small donors.

Quadratic voting is a broader decision-making mechanism where participants allocate a budget of voice credits to vote on multiple proposals. The cost of votes increases quadratically (e.g., 1 vote costs 1 credit, 2 votes cost 4 credits). This makes it expensive to concentrate voting power on a single option.

The key difference is the application: funding vs. general decision-making. However, the core mathematical principle—using a quadratic cost function to prevent Sybil attacks and promote pluralism—is shared. Most on-chain implementations, like those using the MACI (Minimal Anti-Collusion Infrastructure) framework, can be adapted for both use cases.

conclusion-next-steps
IMPLEMENTATION SUMMARY

Conclusion and Next Steps

You have successfully built a foundational quadratic voting system. This guide covered core concepts, smart contract development, and a basic frontend. The next phase involves hardening security, scaling the system, and exploring advanced governance applications.

Your implementation demonstrates the core mechanics of quadratic voting (QV): using a credits-based system where vote cost equals the square of the vote weight. This structure effectively surfaces community consensus by making strong preferences expensive. The smart contract handles credit allocation, vote casting with quadratic cost validation, and result tallying. The frontend connects a wallet, fetches proposals, and allows users to cast their weighted votes, providing a complete proof-of-concept.

For a production deployment, several critical enhancements are necessary. Security audits are non-negotiable; engage firms like OpenZeppelin or ConsenSys Diligence to review your QuadraticVoting contract for logic errors and vulnerabilities. Implement upgradeability patterns (e.g., Transparent Proxy) to allow for future improvements without losing state. Add comprehensive event logging for all key actions (credit grants, votes cast) to enable off-chain analytics and dispute resolution. Finally, integrate a robust frontend framework like Next.js with proper error handling and transaction state management.

To scale and extend your QV system, consider these advanced features: - Sybil resistance: Integrate with proof-of-personhood protocols like Worldcoin or BrightID to prevent credit farming. - Delegation: Allow users to delegate their voting credits to representatives, creating a fluid representative democracy layer. - Cross-chain voting: Use a cross-chain messaging protocol (e.g., Axelar, LayerZero) to enable voting across multiple EVM chains from a single interface. - Quadratic funding: Adapt the contract for grants distribution, where community donations are matched based on the square root of contributor counts.

Explore real-world applications beyond simple polls. QV is powerful for DAO treasury management, helping prioritize budget allocations for proposals. It can govern protocol parameter adjustments (e.g., fee changes, reward rates) in DeFi projects. Research platforms like Gitcoin Grants use quadratic funding, a close relative of QV, to democratically allocate matching funds to public goods. Your implementation is a stepping stone to building these more complex, impactful governance mechanisms.

Continue your learning with these resources: Study the OpenZeppelin Governor contract suite for industry-standard governance patterns. Review the MACI (Minimal Anti-Collusion Infrastructure) framework by Privacy & Scaling Explorations to understand advanced anti-collusion mechanisms for voting. Experiment with existing QV platforms like Snapshot with the quadratic voting strategy to see how large DAOs operate. The code from this tutorial is a starting point; the next step is to rigorously test, audit, and iterate based on real community feedback.