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 a Quadratic Funding Mechanism for Grants

A technical guide for developers implementing a quadratic funding system to allocate community grants, including contract logic, voter verification, and integration patterns.
Chainscore © 2026
introduction
GRANTS DISTRIBUTION

Introduction to Quadratic Funding Implementation

A technical guide to setting up a quadratic funding mechanism for allocating grants, explaining the core algorithm, implementation steps, and security considerations.

Quadratic Funding (QF) is a democratic mechanism for allocating a matching pool of funds to public goods based on the number of contributors, not just the total amount contributed. The core formula calculates a project's matching amount as the square of the sum of the square roots of each individual contribution: Matching ∝ (Σ √contribution_i)². This amplifies the impact of a large number of small donations, making it a powerful tool for community-driven grant programs like Gitcoin Grants. Implementing QF requires careful handling of on-chain data, vote aggregation, and secure fund distribution.

To implement a basic QF round, you need several core components. First, a registry for approved projects, often stored on-chain or in a verifiable database. Second, a voting mechanism where users can contribute funds (e.g., ETH, USDC) to projects during a specified round period. These contributions are recorded on a blockchain for transparency. Third, an aggregator or round manager smart contract that collects all contribution data after the round closes, calculates the quadratic match for each project using the QF formula, and distributes the matching pool funds accordingly.

A critical implementation step is designing the data structures. A project struct might store an ID, owner, and metadata pointer. A contribution struct records the contributor, project ID, amount, and timestamp. The matching calculation is typically performed off-chain in a trusted execution environment or via a zk-SNARK circuit (like MACI) to preserve privacy and prevent manipulation, with only the final merkle root of results published on-chain. The clr.fund project provides a fully open-source, minimal implementation of this architecture on Ethereum.

Security is paramount. The system must be resistant to Sybil attacks, where one entity creates many fake identities to manipulate the square root calculation. Integration with Sybil resistance mechanisms like BrightID, Gitcoin Passport, or proof-of-personhood protocols is essential. Furthermore, the contract must safely handle the matching pool funds, use a timelock for administrative functions, and have a clear process for finalizing round results. Always audit your contracts and use established libraries like OpenZeppelin for access control and security patterns.

For developers, starting with a test implementation using a framework like Hardhat or Foundry is recommended. Simulate a round with dummy projects and contributions, calculate matches using a script (e.g., in JavaScript or Python), and test the distribution. The QF formula implementation in OpenQ's frontend library provides a practical reference. Remember that gas costs for on-chain vote tallying can be prohibitive; most production systems use layer-2 solutions like Polygon or Optimism, or perform verification off-chain with on-chain settlement.

Beyond the basic setup, consider enhancements like tiered matching caps to prevent a single project from dominating the pool, minimum contribution thresholds to filter noise, and real-time matching estimates to encourage participation. The QF mechanism is a powerful primitive for decentralized governance and funding. By implementing it correctly, you can create a transparent, fair, and community-led grants program that efficiently allocates resources to the most valued public goods.

prerequisites
SETUP GUIDE

Prerequisites and Tech Stack

Before deploying a quadratic funding mechanism, you need the right tools and foundational knowledge. This guide outlines the essential prerequisites and the core technology stack for building a secure and functional grants program.

A quadratic funding (QF) mechanism is a smart contract-based application that requires proficiency in Ethereum development. You should be comfortable with Solidity for writing the core funding logic, JavaScript/TypeScript for building the frontend and backend interactions, and a framework like Hardhat or Foundry for development, testing, and deployment. Familiarity with Git for version control and a code editor like VS Code is assumed. If you're new to smart contracts, we recommend completing the Solidity documentation and a basic Hardhat tutorial first.

Your development environment must include Node.js (v18 or later) and a package manager like npm or yarn. You will interact with an Ethereum Virtual Machine (EVM) chain, which could be a local testnet (e.g., Hardhat Network), a public testnet (like Sepolia or Holesky), or eventually a mainnet like Ethereum or an L2 like Arbitrum or Optimism. Essential libraries include ethers.js or viem for blockchain communication, and a testing suite such as Chai or the built-in tools in Foundry. For the QF math, you may need a library like BigNumber.js to handle the precise calculations required for vote tallying and matching fund distribution.

The core smart contract stack typically involves several key components. You will need a voting contract to accept project registrations and community contributions (often in a stablecoin like USDC), a matching pool contract to hold the funds to be distributed, and the QF algorithm contract itself, which calculates the final distribution based on the square root of the sum of contributions. These contracts must also integrate with a price oracle (like Chainlink) if matching funds are in a different currency, and consider using a multisig wallet (via Safe{Wallet}) or a DAO framework (like OpenZeppelin Governor) for treasury management.

Beyond the blockchain layer, a complete QF round requires supporting infrastructure. You'll need a way for users to sign messages cryptographically, often using EIP-712 typed structured data, to submit their votes without paying gas fees (via a meta-transaction relayer). A backend service or serverless function is necessary to aggregate these signed votes and submit the final batch to the chain. Furthermore, you must plan for frontend development using a framework like Next.js or React with a Web3 library such as wagmi to create the user interface for project submission and contribution.

Finally, security and audit readiness are non-negotiable prerequisites. Your code must include comprehensive unit and integration tests covering edge cases in the QF formula. You should be prepared for a smart contract audit by a reputable firm before any mainnet deployment. Utilize established libraries like OpenZeppelin Contracts for secure standard implementations (e.g., ERC-20, Ownable). Planning for upgradeability via proxies or considering immutable deployment is a key architectural decision that must be made before writing the first line of code.

core-algorithm
GUIDE

The Quadratic Funding Algorithm

A technical walkthrough for implementing a Quadratic Funding (QF) mechanism to allocate grants or public goods funding based on community preferences.

Quadratic Funding (QF) is a mathematically optimal mechanism for funding public goods, first formalized by Vitalik Buterin, Zoë Hitzig, and Glen Weyl. It democratizes funding allocation by amplifying the preferences of a large number of small contributors. The core principle is that the amount of matching funds a project receives is proportional to the square of the sum of the square roots of contributions. This formula, (sum(√contributions))^2, ensures that projects with broad community support receive a larger share of a matching pool than those funded by a few large donors, effectively measuring the number of unique supporters.

To implement a QF round, you need several key components: a registry of projects, a mechanism for collecting contributions (often in a stablecoin like USDC), a defined matching pool of funds, and a period for the round to be active. Contributions are typically made on-chain for transparency and verifiability. After the round concludes, the algorithm calculates the matching amount for each project. The total required matching funds often exceed the pool, so a pairwise coordination subsidy calculation is used to proportionally distribute the available pool, solving the optimization problem of maximizing the sum of the square roots of contributions.

Here is a simplified Python function that calculates the QF match for a list of projects after a round. This example assumes a fixed matching pool and uses the pairwise coordination method to handle an over-subscribed pool.

python
import numpy as np

def calculate_qf_matches(contributions, matching_pool):
    """
    contributions: List of lists, where each sublist contains contribution amounts to a project.
    matching_pool: Total amount of matching funds available.
    Returns: List of matching amounts for each project.
    """
    # Calculate the square root sum for each project
    sqrt_sums = [np.sqrt(c).sum() for c in contributions]
    ideal_matches = [s**2 for s in sqrt_sums]
    
    # If total ideal matches exceed the pool, calculate pairwise subsidies
    total_ideal = sum(ideal_matches)
    if total_ideal <= matching_pool:
        return ideal_matches
    
    # Use a simple iterative approximation (Clarke tax / pairwise coordination)
    # This finds the Lagrange multiplier `lambda`
    lam = 1.0
    for _ in range(100):  # Simple gradient descent iteration
        matches = [max(0, s**2 - lam) for s in sqrt_sums]
        total_matches = sum(matches)
        if abs(total_matches - matching_pool) < 1e-6:
            break
        # Adjust lambda based on whether we are over or under the pool
        lam += (total_matches - matching_pool) * 0.01
    
    return [max(0, m) for m in matches]

In a production environment, you would use a battle-tested library or smart contract. The Gitcoin Grants program is the most prominent real-world implementation, having distributed over $50 million in matching funds via the Ethereum mainnet and its own scaling solution, Grant Stack. For developers, the Grant Stack provides open-source smart contracts (written in Solidity) and a front-end template to launch a custom QF round. Key contract functions include vote, finalizeRound, and distributeFunds, which handle contribution recording, match calculation, and token distribution securely on-chain.

When setting up your mechanism, critical design decisions include: choosing the blockchain and token for contributions (considering gas fees and accessibility), defining round parameters like duration and minimum/maximum contribution, establishing sybil resistance (e.g., integrating with BrightID or using passport scores), and ensuring a clear review process for project applications. Security is paramount; audits of the QF smart contracts are essential to prevent exploits that could drain the matching pool. Furthermore, the mechanism's success hinges on community outreach and clear communication to attract a diverse set of contributors and projects.

Quadratic Funding transforms grant-making from a centralized decision into a pluralistic, community-driven process. It's particularly effective for funding open-source software, community initiatives, and research. By implementing it, you create a transparent system where the "wisdom of the crowd" is mathematically amplified to determine the most impactful allocation of shared resources. For further reading, consult the original paper Liberal Radicalism and the technical documentation for Gitcoin's Grant Stack.

key-components
QUADRATIC FUNDING IMPLEMENTATION

Key System Components

A functional Quadratic Funding (QF) system requires several core technical components to handle donations, matching pools, and result calculations.

01

Smart Contract Registry

A central smart contract that acts as the canonical registry for all rounds, projects, and funding pools. It stores:

  • Project metadata and recipient addresses
  • Round parameters (start/end times, matching cap)
  • The final list of approved projects eligible for matching This contract is the single source of truth that other components query.
02

Donation & Voting Mechanism

The interface and logic for contributors to fund projects. This can be a simple transfer function or a more complex system using vote-escrowed tokens or signature-based contributions. Key considerations:

  • Support for multiple tokens (e.g., ETH, USDC, GTC)
  • Prevention of Sybil attacks via identity verification layers
  • A clear record of each donor's contribution per project for the QF calculation.
04

QF Round Coordinator

An off-chain service or keeper bot that manages the round lifecycle. It:

  1. Initiates the round by updating the registry contract.
  2. Monitors the round for contributions and events.
  3. Triggers the calculation at the round's end to compute the match.
  4. Submits the final distribution for treasury execution. This automates the process and ensures timely execution.
MECHANISM OVERVIEW

Sybil Resistance Methods Comparison

A comparison of common techniques to prevent Sybil attacks in quadratic funding rounds.

MethodProof of PersonhoodStaking / BondingSocial Graph Analysis

Core Principle

Verify unique human identity

Require economic stake to participate

Analyze social connections for uniqueness

Implementation Complexity

High

Medium

Very High

User Friction

High (biometric/KYC)

Medium (capital required)

Low (passive)

Decentralization

Varies (centralized issuers common)

High

High

Cost to Attacker

Cost of fake identities

Capital at risk (slashing)

Cost to build credible graph

Collusion Resistance

Low

Medium (via slashing)

High

Example Protocol / Tool

Worldcoin, BrightID

Gitcoin Grants (early rounds)

Gitcoin Passport, Sismo

Typical Verification Time

Minutes to hours

Seconds (if capital ready)

Real-time to days

QUADRATIC FUNDING SETUP

Step-by-Step Implementation

Understanding the Components

A Quadratic Funding (QF) mechanism requires three core elements: a funding pool, a project registry, and a matching algorithm. The pool holds the matching funds, often from a DAO treasury or grant program. The registry is a smart contract where projects submit their public goods proposals, including a receiving wallet address. The algorithm, typically the CLR (Capital-constrained Liberal Radicalism) formula, calculates the final distribution of matching funds based on the square root of each project's total contributions.

Key Design Decisions

Before deployment, you must decide on critical parameters:

  • Matching Cap: The maximum amount of matching funds any single project can receive.
  • Contribution Token: The ERC-20 token used for donations (e.g., USDC, DAI, ETH).
  • Round Duration: The fixed period (e.g., 2 weeks) during which contributions are accepted.
  • Sybil Resistance: Methods to prevent manipulation, such as requiring a minimal donation or integrating with Gitcoin Passport for proof-of-personhood.
contract-architecture
SMART CONTRACT ARCHITECTURE

Setting Up a Quadratic Funding Mechanism for Grants

This guide explains how to implement a Quadratic Funding (QF) mechanism on-chain, covering the core smart contract architecture, funding rounds, and vote aggregation.

Quadratic Funding (QF) is a democratic mechanism for allocating capital to public goods, where the amount of matching funds a project receives is proportional to the square of the sum of the square roots of its contributions. In a smart contract context, this requires a system to manage grant rounds, collect contributions, and calculate matching payouts. The core architecture typically involves three main components: a Round Manager contract to create and configure funding periods, a Voting/Vault contract to securely hold and track contributions, and a QF Calculator contract to perform the final matching distribution after a round closes.

The first step is deploying a factory or manager contract to create new funding rounds. Each round is its own contract with parameters like startTime, endTime, a matchingPoolSize (the total amount of matching funds available), and a grantRegistry (a list of approved project addresses). Projects are usually added via a registry or an on-chain application process. A common practice is to use a minimal proxy (ERC-1167) pattern for round contracts to save on gas costs during deployment. The Open Source Software Funding platform Gitcoin Grants popularized this model on Ethereum and its Layer 2 solutions.

During the active round, contributors send funds to the round's voting contract. It's critical that this contract does not simply tally raw contribution amounts. Instead, it must track each unique contributor's amount per project to later calculate the quadratic sum. A secure implementation will use a commit-reveal scheme or MACI (Minimal Anti-Collusion Infrastructure) to prevent sybil attacks and collusion, where one user splits their funds across many wallets to unfairly increase matching. For simpler implementations, a merkle tree of contributions can be built off-chain, with the root stored on-chain for later verification.

When the round ends, the matching distribution is calculated. This is computationally intensive, so it's often done off-chain in a trusted or cryptographically verifiable way. The QF formula is applied: for each project, sum the square roots of each contribution, square that total, and sum across all projects to get a denominator. The project's share of the matching pool is its numerator divided by this denominator. Projects like clr.fund implement this using zk-SNARKs (via the zksync circuit) to generate a verifiable proof of the correct match, which is then submitted on-chain to trigger payouts from the matching pool.

Key security considerations include ensuring the matching pool funds are held in escrow and only releasable after verified calculation, protecting against rounding errors in the square root calculations, and implementing emergency pause/withdraw functions for round operators. Testing is paramount; use forked mainnet environments and property-based testing frameworks like Foundry's fuzzing to simulate thousands of contribution patterns. The final architecture creates a transparent, auditable, and mathematically fair system for allocating community-driven funding.

IMPLEMENTATION PATHS

Code Examples and Snippets

Core Contract Logic

Below is a simplified version of the key quadratic funding calculation, often implemented in a Round or Distributor contract.

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

import "@openzeppelin/contracts/utils/math/Math.sol";

contract SimpleQF {
    using Math for uint256;

    struct Project {
        address recipient;
        uint256 totalReceived;
        uint256 sumOfSqrtContributions;
    }

    Project[] public projects;
    uint256 public matchingPool;
    uint256 public totalSumOfSqrt;

    function contribute(uint256 _projectId) external payable {
        require(_projectId < projects.length, "Invalid project");
        Project storage project = projects[_projectId];
        
        project.totalReceived += msg.value;
        // Calculate the square root of this contribution and add it to the running sum
        project.sumOfSqrtContributions += Math.sqrt(msg.value);
        // Update the global sum of square roots for all projects
        totalSumOfSqrt += Math.sqrt(msg.value);
    }

    function calculateMatch(uint256 _projectId) public view returns (uint256 matchAmount) {
        Project memory project = projects[_projectId];
        if (totalSumOfSqrt == 0) return 0;
        // QF Formula: (project_sum_of_sqrt / total_sum_of_sqrt)^2 * matchingPool
        uint256 ratio = (project.sumOfSqrtContributions * 1e18) / totalSumOfSqrt;
        matchAmount = (matchingPool * ratio * ratio) / (1e18 * 1e18);
    }
}

Key Points:

  • The sqrt function from OpenZeppelin's Math library is used for calculations.
  • The matching amount is proportional to the square of the sum of square roots of contributions.
  • This is a naive example; production contracts require safeguards against sybil attacks, often using a clr.fund or Allo protocol design.
QUADRATIC FUNDING

Frequently Asked Questions

Common technical questions and solutions for developers implementing a quadratic funding mechanism for grants.

Quadratic funding (QF) is a democratic mechanism for allocating a matching pool of funds to public goods projects based on the number of contributors, not just the total amount contributed. The core formula calculates a project's matching amount as the square of the sum of the square roots of each individual contribution.

Mathematically: Matching ∝ (Σ √contribution_i)²

This structure amplifies the power of many small donations. For example, a project receiving 100 donations of $1 each (Σ √1 = 100) would receive a much larger match than a project receiving one donation of $10,000 (Σ √10000 = 100), even though the total contributed is the same. The matching pool is distributed proportionally to these calculated amounts. Smart contracts, like those used by Gitcoin Grants, automate this calculation and distribution on-chain.

conclusion
IMPLEMENTATION SUMMARY

Conclusion and Next Steps

You have successfully configured a foundational quadratic funding (QF) mechanism. This guide covered the core components: a smart contract for matching fund distribution, a frontend for project submission, and a voting interface. The next steps involve hardening the system for production and exploring advanced features.

Your basic QF implementation is now functional. The core contract uses a commit-reveal scheme to prevent tactical voting, calculates matches using the quadratic formula (sum of square roots of contributions)^2, and distributes a matching pool. You have a frontend for projects to create profiles with descriptions, funding goals, and recipient addresses, and a separate interface for donors to contribute and vote. This setup is suitable for a testnet or small-scale grant round.

Before launching a mainnet round, conduct a thorough security audit. Key areas to review include: the accuracy of the matching calculation to prevent rounding errors, gas optimization for the vote tallying function, and access controls on administrative functions like finalizing the round. Consider using established libraries like OpenZeppelin for secure contract patterns. Test edge cases, such as a project receiving zero votes or a single donor contributing the entire matching pool.

To enhance the mechanism, integrate Sybil resistance. The simplest method is to require a small, non-refundable donation or stake to vote, making fake identities costly. For stronger guarantees, leverage BrightID or Gitcoin Passport for proof-of-personhood. You could also implement pairwise coordination subsidies to encourage discovering and funding projects with overlapping communities, moving beyond simple QF.

The administrative dashboard is critical for round operators. Build features to: monitor the total matching pool in real-time, track project submission statistics, and generate reports for transparency. After a round concludes, the contract should allow the operator to trigger the final distribution, sending matched funds directly to each project's designated wallet. All transaction data should be exportable for public verification.

Explore integrating with broader ecosystems. Your QF round can be listed on platforms like Gitcoin Grants to tap into an existing donor base. Consider using Superfluid for streaming contributions over time instead of one-time donations. For decentralized curation, allow token holders of your DAO or protocol to signal which project categories should receive higher matching caps in future rounds.

The final step is documentation and community onboarding. Create clear guides for project applicants and donors. Publish the verified contract address, the round's rules, and the matching formula. A well-run QF round not only distributes funds effectively but also builds a strong, engaged community around public goods funding. Start with a small pilot round, gather feedback, and iterate on the design for subsequent, larger rounds.

How to Implement Quadratic Funding for Grants | ChainScore Guides