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

Setting Up Quadratic Voting with Social Tokens

This guide provides a technical walkthrough for implementing quadratic voting in social token communities. It covers the mathematical model, integration with Snapshot or custom smart contracts, and practical steps for community adoption.
Chainscore © 2026
introduction
GOVERNANCE

Setting Up Quadratic Voting with Social Tokens

A practical guide to implementing quadratic voting, a democratic mechanism that reduces the influence of large token holders, using social tokens for community governance.

Quadratic Voting (QV) is a collective decision-making process where participants allocate a budget of voice credits to vote on multiple proposals. The key innovation is that the cost of additional votes for a single proposal increases quadratically. For example, casting 1 vote costs 1 credit, 2 votes cost 4 credits, and 3 votes cost 9 credits. This mathematical relationship, formalized by Glen Weyl and others, makes it economically prohibitive for a single entity to dominate an outcome, thereby better reflecting the intensity of preferences across a diverse group. It's particularly well-suited for DAO governance and funding allocation, like in Gitcoin Grants.

Social tokens, such as those created via Collab.Land or Roll, represent membership, reputation, or contribution within a community. They are ideal for powering a QV system because they are inherently tied to identity and participation, not just capital. To set up QV, you first need to define the voting currency. This could be the community's native social token, a non-transferable "voice credit" token airdropped to members, or a hybrid model. The choice impacts sybil resistance; using a valuable, transferable token is simpler but vulnerable to buying votes, while a non-transferable reputation token better aligns with QV's democratic ideals.

The core implementation involves a smart contract that enforces the quadratic cost function. A basic Solidity structure includes a function where a user submits votes for different proposals. The contract must calculate the sum of the square roots of the votes cast for each proposal, then square the total to determine the credits spent, ensuring it does not exceed the user's balance. For example, voting [1, 4, 0] across three proposals calculates as (sqrt(1) + sqrt(4) + sqrt(0))^2 = (1 + 2 + 0)^2 = 9 credits spent. Always use a library like OpenZeppelin's for safe math operations and access control to secure the voting process.

A critical challenge is sybil resistance—preventing users from creating multiple identities to game the system. Effective strategies include integrating with BrightID or Worldcoin for proof of personhood, requiring a minimum token holding period (e.g., 30 days), or using POAP badges as a prerequisite for receiving voice credits. The voting interface, often built with React and ethers.js, should clearly show users their credit budget, the quadratic cost of their current selections, and real-time tallies. Transparency in the counting mechanism is essential for community trust.

After the voting period ends, the contract tallies the results. The winning proposal is the one with the highest sum of square roots of votes received. For instance, if Proposal A gets 100 votes from one user and Proposal B gets 1 vote each from 25 users, QV yields sqrt(100)=10 for A versus 25 * sqrt(1)=25 for B, making B the winner. This outcome demonstrates QV's power to favor broad, moderate support over concentrated interest. Successful implementations, such as Radicle's grant funding, show that QV fosters more equitable and engaged community governance when paired with thoughtfully designed social tokens.

prerequisites
SETUP GUIDE

Prerequisites

Before building a quadratic voting system with social tokens, you need to establish the foundational technical environment and understand the core concepts.

To follow this guide, you should have a working knowledge of JavaScript/TypeScript and basic Ethereum development concepts. Familiarity with smart contracts, wallets, and decentralized applications (dApps) is assumed. You will need Node.js (v18 or later) and npm or yarn installed on your machine. For blockchain interaction, a tool like MetaMask is required, and you should have access to a testnet (e.g., Sepolia) with test ETH from a faucet. The primary development framework used will be Vite with React and TypeScript.

The core of this system involves two main components: a social token and a voting contract. The social token, often an ERC-20 token, represents membership or reputation within a community. For this guide, we will use a simple mintable ERC-20. The voting contract will implement the quadratic voting logic, where the cost of votes scales quadratically with the number of votes cast, preventing whale dominance. We'll use OpenZeppelin contracts for secure, audited base implementations and Hardhat for local development and testing.

You'll need to set up your project environment. Start by initializing a new project and installing the necessary dependencies. Key packages include hardhat, @openzeppelin/contracts, ethers, viem, and wagmi. We recommend using pnpm for faster installs. A basic hardhat.config.ts file must be configured for the Sepolia testnet, requiring an Alchemy or Infura RPC URL and a private key from your funded test wallet stored securely in a .env file.

Understanding the quadratic formula is crucial. In a quadratic voting system, the cost to cast n votes is proportional to n². For example, 1 vote costs 1 credit, 2 votes cost 4 credits, and 3 votes cost 9 credits. This is typically implemented by having users approve the voting contract to spend their tokens and then pay the quadratic cost when casting votes. The contract must calculate the required token amount based on the difference between the user's new and previous vote totals for a given proposal.

Finally, ensure you have a plan for the frontend integration. We will use wagmi and viem to interact with the deployed contracts. This involves configuring wagmi providers, reading token balances, and writing transactions for voting. The UI will need to display proposals, current vote counts, and allow users to connect their wallet and cast votes. With these prerequisites in place, you are ready to start building the smart contract and application logic.

key-concepts-text
TOKEN ENGINEERING

Key Concepts: The Quadratic Model

Quadratic Voting (QV) is a mechanism designed to more accurately reflect the intensity of individual preferences in collective decision-making, particularly for allocating shared resources like community treasuries.

The quadratic model addresses a core flaw in traditional one-token-one-vote (1T1V) governance: it allows wealthy participants to dominate outcomes. In QV, the cost of casting votes increases quadratically with the number of votes allocated to a single option. For example, to cast 1 vote costs 1 credit, 2 votes cost 4 credits (2²), and 10 votes cost 100 credits (10²). This pricing structure makes it economically irrational for any single entity to concentrate all their voting power on one proposal, promoting more equitable and diverse outcomes that better represent the collective will.

Implementing QV with social tokens or non-transferable governance tokens adds a powerful sybil-resistance layer. Since the cost is quadratic in votes, not tokens, an attacker would need to control a vast number of unique identities (sybils) to sway a vote, rather than just amassing a large token balance. This makes QV particularly effective for retroactive public goods funding (like Gitcoin Grants) and community grant allocation, where the goal is to fund projects based on broad, democratic support rather than the preferences of a few large holders.

The core mechanism is enforced by a smart contract. A voter with a budget of C credits can allocate v_i votes to proposal i. The contract ensures the sum of the squares of their votes does not exceed their budget: Σ(v_i²) ≤ C. To check this, the contract calculates the sum of squares of the voter's new vote allocations and verifies it's within their remaining credit limit, which is often derived from their token balance or a fixed allocation per epoch.

Here is a simplified Solidity function illustrating the credit check logic:

solidity
function _checkQuadraticCost(uint256[] memory votes) internal pure returns (uint256 totalCost) {
    totalCost = 0;
    for (uint256 i = 0; i < votes.length; i++) {
        totalCost += votes[i] * votes[i];
    }
}

A front-end or off-chain client would use this logic to prevent users from submitting invalid vote bundles that exceed their quadratic budget.

While powerful, QV has practical considerations. Collusion remains a challenge, as participants could coordinate to split their budgets among each other's preferred options. Voter fatigue can also be an issue with many proposals. Furthermore, the gas cost for on-chain verification scales with the number of proposals a voter engages with. These limitations are active areas of research, with solutions exploring cryptographic proofs like MACI (Minimal Anti-Collusion Infrastructure) for collusion resistance and layer-2 scaling for cost reduction.

QUADRATIC VOTING IMPLEMENTATION

Governance Model Comparison

Comparison of governance models for social token communities, focusing on quadratic voting suitability.

Governance FeatureOne-Token-One-VoteQuadratic VotingConviction Voting

Sybil Resistance

Whale Dominance Risk

Very High

Low

Medium

Implementation Complexity

Low

Medium

High

Gas Cost per Vote

$2-5

$5-15

$15-50

Ideal Community Size

< 100 members

100-10k members

1k members

Snapshot Integration

Native

Via Module

Via Plugin

Vote Weight Calculation

Linear

Square Root

Time-Based

Best For

Simple Proposals

Funding Allocation

Continuous Signaling

snapshot-integration
GOVERNANCE

Implementing a Quadratic Voting Strategy on Snapshot

A technical guide to configuring a custom quadratic voting strategy on Snapshot, using social token balances to weight votes and mitigate whale dominance in DAO governance.

Quadratic voting is a governance mechanism designed to better reflect the intensity of voter preferences while limiting the influence of large token holders, or 'whales'. Instead of a simple one-token-one-vote model, a voter's voting power is calculated as the square root of their token balance. This means a user with 100 tokens gets 10 voting power (sqrt(100) = 10), while a user with 10,000 tokens only gets 100 voting power (sqrt(10,000) = 100). The result is a more democratic distribution of influence, where many small holders can collectively outweigh a single large holder. Snapshot supports this through customizable voting strategies, which are JavaScript functions that define how voting power is fetched and calculated for each address.

To implement this, you must create a custom strategy in your Snapshot space settings. The strategy is defined by a name, a network (e.g., 1 for Ethereum Mainnet), and a strategy object containing the logic. A basic quadratic voting strategy for a standard ERC-20 token uses the erc20-balance-of strategy with a symbol and decimals, then applies the square root function. The key is the params object, which can include a quadratic boolean flag. However, for full control or integration with social tokens, you will often need to write a custom strategy.

Here is a simplified example of a custom quadratic voting strategy for an ERC-20 token deployed on Ethereum. This strategy fetches the token balance and returns the square root. The function must be hosted publicly, for instance, on GitHub Gist or IPFS, and its URL is provided to Snapshot.

javascript
// Example: Quadratic Voting Strategy for ERC-20
module.exports = {
  name: 'erc20-quadratic',
  author: 'YourDAO',
  version: '0.1.0',
  network: '1', // Ethereum Mainnet
  strategy: {
    name: 'contract-call',
    params: {
      address: '0xYourTokenAddress',
      decimals: 18,
      symbol: 'SOCIAL',
      methodABI: {
        name: 'balanceOf',
        type: 'function',
        inputs: [{ name: 'account', type: 'address' }],
        outputs: [{ name: '', type: 'uint256' }]
      }
    }
  },
  async getVotingPower(space, voterAddress, block) {
    // Fetch raw token balance using the defined contract call
    const balance = await this.strategy.getVotingPower(space, voterAddress, block);
    // Apply quadratic formula: voting power = sqrt(balance)
    const quadraticPower = Math.sqrt(balance);
    return quadraticPower;
  }
};

For social tokens or more complex reputation systems, the strategy can pull data from platforms like Collab.Land, SourceCred, or a custom on-chain registry. Instead of a simple token balance, you might query an API endpoint that returns a user's 'contribution score' or 'reputation balance', then apply the quadratic function to that value. This aligns voting power with proven community contribution rather than pure capital. Ensure your data source is reliable and publicly verifiable to maintain the trustlessness of the Snapshot vote.

After deploying your strategy, test it thoroughly using Snapshot's Test Strategy feature. Input a few addresses with known token balances and verify the calculated voting power matches your expected quadratic values. Common pitfalls include incorrect decimal handling, unreachable API endpoints for custom data, and not accounting for the block number snapshot. Once validated, assign the strategy to a proposal in your space. Voters will see their voting power adjusted automatically, fostering a more equitable and sybil-resistant governance process.

custom-contract-walkthrough
TUTORIAL

Building a Custom Quadratic Voting Smart Contract

Implement a Sybil-resistant governance mechanism using social tokens to weight votes quadratically.

Quadratic voting is a governance mechanism designed to better reflect the intensity of voter preferences while limiting the influence of large token holders. Instead of one token equaling one vote, the cost of a vote increases quadratically with the number of votes cast. This means casting 2 votes costs 4 credits, 3 votes costs 9 credits, and so on. When combined with social tokens—which represent reputation or contribution rather than pure capital—it creates a more nuanced and resistant-to-manipulation system for community decisions. This guide walks through building a custom smart contract for this purpose on Ethereum.

The core logic revolves around tracking a voter's credits based on their social token balance. First, define the relationship: 1 social token could equal 1 voting credit. The key formula is cost = votes². A user with 100 credits can cast a maximum of 10 votes on a single proposal (10² = 100). The contract must prevent overallocation by checking usedCredits[user][proposalId] + cost <= getCredits(user). State variables include proposals, voteCount, and a mapping for usedCredits. This structure ensures the quadratic cost is enforced on-chain.

Here is a simplified Solidity snippet for the voting function:

solidity
function castVote(uint256 proposalId, uint8 voteCount) external {
    uint256 cost = voteCount * voteCount;
    uint256 userCredits = socialToken.balanceOf(msg.sender);
    require(usedCredits[msg.sender][proposalId] + cost <= userCredits, "Insufficient credits");
    
    usedCredits[msg.sender][proposalId] += cost;
    proposals[proposalId].totalVotes += voteCount;
    // Additional logic for tracking voter's choice
}

This function calculates the quadratic cost, validates the user has enough social token-derived credits, and updates the proposal's tally. The socialToken would be an ERC-20 interface pointing to your social token contract.

Integrating a social token like ERC-20 or ERC-1155 is critical. The contract should call balanceOf to determine voting power. For enhanced Sybil resistance, consider using proof-of-personhood systems like Worldcoin or BrightID to mint or weight social tokens. Alternatively, tie token distribution to verifiable on-chain actions (e.g., contribution NFTs). The vote tallying should be isolated per proposal, and you must include functions to create proposals and query results. Always add a timelock or voting period to finalize outcomes.

Security considerations are paramount. Use checks-effects-interactions patterns and guard against integer overflow (though Solidity 0.8.x defaults to checked math). Consider implementing a vote delegation feature and snapshotting token balances at proposal creation time to prevent manipulation. Thoroughly test with tools like Foundry or Hardhat, simulating attacks where a user tries to vote twice or exceed their credit limit. The final contract provides a transparent, auditable foundation for community governance that values diverse participation over sheer capital weight.

community-education
COMMUNITY GOVERNANCE

Setting Up Quadratic Voting with Social Tokens

Quadratic voting is a democratic mechanism that allocates voting power based on the square root of token holdings, preventing whale dominance. This guide explains how to implement it for community governance using social tokens.

Quadratic voting (QV) is a governance model designed to reflect the intensity of voter preferences while mitigating the influence of large token holders. Instead of granting one vote per token (one-token-one-vote), QV calculates voting power as the square root of the number of tokens a user commits to a proposal. For example, a user with 100 tokens gets 10 voting credits (√100), while a user with 10,000 tokens gets only 100 credits (√10,000). This system makes it exponentially more expensive for a single entity to dominate decisions, promoting more equitable and diverse community outcomes. It's particularly well-suited for social token communities where engagement and reputation are valued alongside financial stake.

To implement quadratic voting, you need a smart contract that handles vote credits and a frontend for user interaction. The core logic involves calculating a user's voting power and deducting the corresponding cost from their token balance. A basic Solidity function might look like this:

solidity
function castVote(uint256 proposalId, uint256 votePower) public {
    uint256 cost = votePower * votePower;
    require(balanceOf(msg.sender) >= cost, "Insufficient tokens");
    _burn(msg.sender, cost);
    votes[proposalId][msg.sender] += votePower;
}

This function ensures a user pays tokens equal to the square of their desired voting power (votePower²). Key considerations include using a commit-reveal scheme to prevent strategic voting, implementing a vote delegation system, and setting up snapshotting to determine eligible token holders at a specific block.

Practical deployment requires integrating with existing social token standards like ERC-20 or ERC-1155 and a governance framework such as OpenZeppelin's Governor. You'll also need to decide on critical parameters: the voting period duration, quorum requirements, and a proposal threshold. For gas efficiency on Ethereum, consider using a Layer 2 solution like Arbitrum or Optimism, or an app-specific chain via Cosmos SDK or Polygon Edge. Tools like Tally or Boardroom can provide a frontend interface, while Snapshot offers an off-chain, gas-free voting layer that can be adapted for quadratic calculations using its strategies plugin system.

Successful QV implementations balance fairness with usability. The Gitcoin Grants program is a canonical example, using quadratic funding to match community donations and prevent sybil attacks with a unique passport system. For your community, start with a pilot on a testnet for a low-stakes proposal. Educate members on how vote cost works—spending 9 tokens grants 3 votes, not 9. Monitor metrics like voter participation rate and the Gini coefficient of voting power distribution to assess the system's health. Remember, the goal is not just technical implementation but fostering a culture where every member's voice has meaningful weight.

TOKEN DISTRIBUTION SCENARIOS

Quadratic Voting Cost Examples

A comparison of the total cost for a voter to allocate different vote weights across three proposals, demonstrating the quadratic cost scaling.

Vote Allocation (Proposal A, B, C)Total Votes CastLinear Cost (if applied)Quadratic Cost

(1, 1, 1)

3 votes

$3.00

$3.00

(5, 0, 0)

5 votes

$5.00

$25.00

(2, 2, 2)

6 votes

$6.00

$12.00

(10, 0, 0)

10 votes

$10.00

$100.00

(3, 3, 3)

9 votes

$9.00

$27.00

(8, 1, 1)

10 votes

$10.00

$66.00

(0, 0, 0)

0 votes

$0.00

$0.00

QUADRATIC VOTING & SOCIAL TOKENS

Frequently Asked Questions

Common technical questions and troubleshooting steps for developers implementing quadratic voting systems with social tokens.

Quadratic voting (QV) is a governance mechanism where the cost of casting votes increases quadratically with the number of votes allocated to a single proposal. Unlike simple token-weighted voting, where one token equals one vote, QV uses a formula like cost = votes². This means buying 2 votes costs 4 credits, and 10 votes costs 100 credits. The core difference is that QV strongly penalizes vote concentration, making it economically prohibitive for a single large holder to dominate a decision. This aligns incentives for broad consensus and reduces the "whale problem" prevalent in many DAOs. It's mathematically designed to reflect the intensity of preference across a diverse group more accurately than linear systems.

conclusion
IMPLEMENTATION SUMMARY

Conclusion and Next Steps

You have successfully set up a basic quadratic voting system for social token governance. This guide covered the core components: the token contract, the voting contract, and a simple frontend interface.

Your implementation now allows token holders to propose ideas and vote using a quadratic formula, where voting power is the square root of the tokens committed. This system reduces the influence of large token holders and encourages broader community participation. The key contracts you deployed include a standard ERC-20 token for representation and a custom QuadraticVoting contract to manage proposals, deposits, and vote tallying. The frontend connects via MetaMask to interact with these contracts on a testnet like Sepolia or Goerli.

To build on this foundation, consider enhancing the system's security and functionality. Implement a timelock on executed proposals to prevent malicious governance actions. Add a delegation feature so users can delegate their voting power to others. For production, you must conduct thorough audits and consider using established frameworks like OpenZeppelin's Governor for battle-tested governance logic. Always test upgrades on a forked mainnet before deployment.

For further learning, explore integrating with Sybil-resistant identity systems like BrightID or Gitcoin Passport to prevent vote manipulation through multiple accounts. Study real-world implementations such as Gitcoin Grants, which uses quadratic funding for public goods. The next step is to move your application to a mainnet, starting with a low-stakes token and a multisig guardian for the initial governance period to ensure stability as the community learns the system.

How to Set Up Quadratic Voting with Social Tokens | ChainScore Guides