Quadratic Voting Smart Contracts for DAO & DeFi

We design and develop full-cycle blockchain solutions: from smart contract architecture to launching DeFi protocols, NFT marketplaces and crypto exchanges. Security audits, tokenomics, integration with existing infrastructure.
Showing 1 of 1All 1305 services
Quadratic Voting Smart Contracts for DAO & DeFi
Complex
~1-2 weeks
Frequently Asked Questions

Blockchain Development Services

Blockchain Development Stages

Latest works

  • image_website-b2b-advance_0.webp
    B2B ADVANCE company website development
    1349
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1247
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    949
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1183
  • image_logo-advance_0.webp
    B2B Advance company logo design
    642
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    921

Quadratic voting solves a fundamental problem of token-weighted voting: a whale with 1000x tokens gets 1000x influence. We design systems where voting power is proportional to the square root of the spent resource. 100 voting credits give 10 units of voting power. 900 credits — 30. To get the same power as 9 people with 1 credit each, you need to spend 81 credits. Math: influence = √credits. This makes it economically unattractive for a single participant to dominate compared to a broad coalition. Our experience — 5+ years in blockchain development, over 10 implemented voting systems. We guarantee code audit and protection against attacks.

How quadratic voting solves the whale dominance problem

In standard voting, a holder of 10,000 tokens has 100 times more influence than a holder of 100 tokens. QV changes this: with credits proportional to balance, voting power differs by √100 = 10 times. For DAOs with uneven token distribution, this significantly improves fairness.

QV was proposed by economists Eric Posner and Glen Weyl in the book Radical Markets. The intuition behind the mechanism: in standard voting, 1 person = 1 vote, but preference intensity is not considered. Someone who cares deeply about the outcome and someone indifferent have the same weight. QV allows expressing intensity through the number of credits spent — closer to real economic preferences.

Example: 100 people slightly prefer option A. 10 people strongly want option B. In standard voting, A wins. In QV, if each of the 10 spends 100 credits on B (power = 10 × √100 = 100), they can outvote a coalition of 100 each spending 1 credit (power = 100 × √1 = 100). At balance, the more intensely desired outcome wins.

Criteria Standard (1 token = 1 vote) Quadratic (QV)
Whale influence Linear (1000x tokens = 1000x power) Sublinear (1000x tokens ≈ 31.6x power)
Preference intensity expression Impossible Via credits spent
Sybil resistance Low (one address = one vote) Requires external verification
Gas costs Low Higher (sqrt computation)
Participant complexity Simple Medium (allocation strategy)

Voting credit systems

Voice Credits model

Standard scheme: each participant receives a fixed budget of voice credits per voting round. Credits are non-transferable and expire each round.

contract QuadraticVoting {
    struct VotingRound {
        uint256 startTime;
        uint256 endTime;
        mapping(uint256 => int256) optionVotes;  // optionId => total votes (sqrt-weighted)
    }

    uint256 public constant CREDITS_PER_ROUND = 100;

    // Participant's spent credits in current round
    mapping(address => mapping(uint256 => uint256)) public creditsSpent;

    function vote(
        uint256 roundId,
        uint256 optionId,
        uint256 credits,  // credits to spend on this option
        bool support
    ) external {
        VotingRound storage round = rounds[roundId];
        require(block.timestamp >= round.startTime && block.timestamp < round.endTime, "Round inactive");

        uint256 totalSpent = creditsSpent[msg.sender][roundId] + credits;
        require(totalSpent <= CREDITS_PER_ROUND, "Exceeds budget");

        // QV: voting power = sqrt(credits)
        uint256 votes = sqrt(credits);

        creditsSpent[msg.sender][roundId] = totalSpent;

        if (support) {
            round.optionVotes[optionId] += int256(votes);
        } else {
            round.optionVotes[optionId] -= int256(votes);
        }

        emit VoteCast(msg.sender, roundId, optionId, credits, votes, support);
    }

    // Integer square root (Babylonian method)
    function sqrt(uint256 x) internal pure returns (uint256 y) {
        if (x == 0) return 0;
        uint256 z = (x + 1) / 2;
        y = x;
        while (z < y) {
            y = z;
            z = (x / z + z) / 2;
        }
    }
}

Token-weighted credits

Alternative scheme: credits are proportional to token balance (as in Gitcoin Grants). A holder of 1000 tokens gets 1000 credits. But voting power is still √ of credits spent. This gives wealthy participants more credits, but not linear influence.

Comparison: with credits proportional to balance and a balance of 10,000 vs 100 (100x difference) — voting power differs by √100 = 10x, not 100x. This is significantly better than standard token-weighted.

Delegated QV

A participant can delegate their credits to another participant. The delegate votes with a pool of credits, but the square root function is applied to the total credits spent on each option from each original owner.

Important nuance: aggregation of credits from delegates must preserve source information. Simply summing credits in the delegate's pool loses the QV property.

// Correct aggregation: each delegation entry separately
struct Delegation {
    address delegator;
    uint256 credits;
}

// Delegate voting: applies QV to each delegation individually
function voteAsDelegate(
    uint256 roundId,
    uint256 optionId,
    Delegation[] calldata delegations
) external {
    int256 totalVotes = 0;
    for (uint i = 0; i < delegations.length; i++) {
        require(
            delegatedCredits[delegations[i].delegator][msg.sender][roundId]
            >= delegations[i].credits,
            "Insufficient delegated credits"
        );
        totalVotes += int256(sqrt(delegations[i].credits));
    }
    rounds[roundId].optionVotes[optionId] += totalVotes;
}

Why Sybil attack is critical for QV and how we prevent it

QV completely breaks without Sybil protection. One participant with 100 credits gets power 10. One hundred participants with 1 credit each get total power 100. By splitting identity into N addresses, an attacker multiplies his power by √N.

Proof of Humanity

A registered unique identity in Proof of Humanity or Worldcoin gets 1 credit allocation. Sybil impossible — creating a thousand real people is not feasible.

Integration via on-chain check:

interface IProofOfHumanity {
    function isRegistered(address _submissionID) external view returns (bool);
}

contract QVWithPoH {
    IProofOfHumanity public poh;

    function registerForRound(uint256 roundId) external {
        require(poh.isRegistered(msg.sender), "Not registered in PoH");
        require(!registeredForRound[roundId][msg.sender], "Already registered");
        registeredForRound[roundId][msg.sender] = true;
        creditsBalance[roundId][msg.sender] = CREDITS_PER_ROUND;
    }
}

Problem with PoH: limited coverage, registration takes time, challengeable. For a DAO with global audience — a barrier to entry.

Worldcoin World ID

More scalable solution. Iris scan → ZK proof of uniqueness. On-chain verification via semaphore protocol without revealing personal data.

import "@worldcoin/world-id-contracts/src/interfaces/IWorldID.sol";
import { ByteHasher } from "@worldcoin/world-id-contracts/src/helpers/ByteHasher.sol";

contract QVWithWorldID {
    using ByteHasher for bytes;

    IWorldID internal worldId;
    uint256 internal groupId = 1; // Orb-verified
    uint256 internal externalNullifierHash;

    function registerWithWorldID(
        address signal,
        uint256 root,
        uint256 nullifierHash,
        uint256[8] calldata proof
    ) external {
        // Verifies ZK proof of uniqueness
        worldId.verifyProof(
            root,
            groupId,
            abi.encodePacked(signal).hashToField(),
            nullifierHash,
            externalNullifierHash,
            proof
        );

        require(!nullifierUsed[nullifierHash], "Already registered");
        nullifierUsed[nullifierHash] = true;
        // issue credits
    }
}

Stake-based anti-sybil

For DeFi-oriented DAOs: require a token stake to participate. Creating many Sybil accounts becomes expensive. Combining with QV: stake determines base credits, but voting power is still √ of spent.

Complete system architecture

On-chain components

  • QuadraticVoting.sol: core contract with credits and voting logic
  • IdentityRegistry.sol: links addresses to verified identities (PoH/Worldcoin)
  • VotingRoundFactory.sol: creates rounds with parameters (duration, options, credit allocation)

Off-chain components

Snapshot integration: most DAOs use Snapshot for off-chain QV voting — free and unlimited participants. Snapshot supports QV strategy.

Results calculator: off-chain service for complex QF calculations, with subsequent on-chain publication.

Frontend: an interface where participant sees their credit budget, sliders to allocate across options, live preview of voting power per decision.

Parameter Recommendation Rationale
Base credits 99-100 Convenient for √ calculations
Round duration 7-14 days Time for informed participation
Credit carryover No Prevents accumulation and attacks
Minimum stake 0.01-0.1% supply Basic anti-sybil without high barrier
Sybil protection PoH + stake Multi-layered defense

Limitations and honest view

QV does not solve all governance issues. Weak points:

  • Collusion: a group of participants can coordinate credit allocation to maximize total influence. This is harder than in standard voting but not impossible. MACI (Minimum Anti-Collusion Infrastructure) addresses this with ZK cryptography.
  • Rational ignorance: most participants won't spend time studying 20 proposals in a round. QV reduces the cost of ignorance but doesn't eliminate it.
  • Optimal strategy: the mathematically optimal strategy for a participant is not obvious. This may reduce participation from non-technical members.

QV is better suited for limited option sets (priority selection, grant distribution) than binary yes/no protocol decisions.

What’s included in the work

  • Audit of current governance structure and problem statement
  • Smart contract architecture design (Solidity/Foundry or Rust/Anchor)
  • Implementation of core QV contracts with voice credits and quadratic counting
  • Sybil protection integration (PoH, Worldcoin, or stake-based)
  • Frontend development (React/viem/RainbowKit) with influence visualization
  • Unit and integration tests (Foundry/Tenderly)
  • Deployment and voting round configuration
  • User and admin documentation
  • Post-release support for 1 month

How we develop a quadratic voting system: step by step

  1. Analytics (2-3 days): review current processes, identify pain points and voting requirements.
  2. Design (3-5 days): create smart contract architecture, select Sybil protection methods and platform.
  3. Development (14-30 days): write Solidity contracts, integrate PoH/Worldcoin, develop frontend.
  4. Testing (5-7 days): run unit and integration tests, use Slither and Mythril for static analysis.
  5. Deployment (1-2 days): deploy contracts to mainnet, configure voting round.
  6. Post-release support: 1 month monitoring and fixes.

Timeline: from 3 weeks (basic QV without anti-sybil) to 12 weeks (full product with PoH/Worldcoin and delegation). Cost is calculated individually — investment in fair voting pays off through reduced conflicts and increased community activity.

Example vote calculation A participant with 9 credits gets 3 votes (√9). If they want to support two options, distributing 4 and 5 credits gives 2 + 2.236 = 4.236 votes, more than 3 when concentrating on one. This encourages spreading credits rather than concentrating.

Get a consultation on implementing quadratic voting in your DAO. Our engineers will propose the optimal solution for your tasks. Contact us to discuss details.

DAO Development: Governance That Works

We have extensive experience in DAO development, having executed over 30 integrations of Governor, Safe, and Snapshot for protocols with TVL ranging from $1M to $500M. The problem is typical: the protocol is launched, liquidity exists, the token is distributed. The next step is handing control to the community. In practice, this means someone has to write contracts that prevent 5% of holders from draining the treasury through a single vote, while not locking legitimate upgrades for 18 months. The balance is nontrivial.

Why do most DAOs become oligarchies?

Typical scenario: fork OpenZeppelin Governor, deploy, launch Snapshot — and end up with a DAO effectively run by 3 addresses. The problem isn't the code but the tokenomics and parameters.

Quorum too high or too low. Compound set quorum at 400,000 COMP. With low turnout, proposals fail for months. With low quorum, one large holder can pass any question. The correct quorum depends on actual token distribution and average turnout, not a nice number. We analyze voting history, locked vs. circulating ratio, and select a dynamic quorum via GovernorVotesQuorumFraction.

Flash loan governance attack. Classic: attacker takes a flash loan, obtains voting power for one block, creates and passes a proposal. Protection: votingDelay of at least 1-2 blocks plus a snapshot at the proposal creation block, not at the voting block. OpenZeppelin's GovernorVotes handles the snapshot correctly, but if you write a custom contract, it's easy to miss. Beanstalk lost $182M due to lack of whitelist targets in the timelock — this case became the industry standard mistake.

Timelock without executor whitelist. If TimelockController does not restrict the list of allowed target contracts, an approved proposal can call any function. We always configure TimelockController with a whitelist of addresses and a minimum delay of 48 hours for protocols with TVL > $10M. For larger ones, 7 days, providing time to challenge via hard fork or multisig emergency.

On-chain governance architecture

Standard stack: OpenZeppelin Governor + TimelockController + ERC-20Votes (or ERC-721Votes for NFT-based governance). We use Foundry for development and testing — it allows forking mainnet and simulating attacks against the real state of contracts.

ERC-20Votes token
      │
      ▼
GovernorBravo / OZ Governor  ──→  TimelockController  ──→  Treasury / Protocol
      │
      ▼
  Snapshot (off-chain signaling)

Governor handles voting logic: propose, castVote, queue, execute. Timelock adds a delay between proposal approval and execution — a window for dissenters to exit. Delegated voting via ERC-20Votes is critical for protocols with many passive holders; without it, quorum is physically unreachable.

Snapshot + on-chain: hybrid model

Fully on-chain voting costs gas. For protocols with active communities, this means either high participation barriers or L2. Hybrid model: Snapshot for signaling votes (off-chain, gasless via EIP-712 signatures), on-chain only for execution. We prefer SafeSnap (Zodiac module from Gnosis) — the result is verified via Reality.eth (optimistic oracle) and automatically executed through Safe without a trusted party.

Multi-sig: Gnosis Safe as an operational layer

Most DAOs use Gnosis Safe for treasury. Standard configuration: M-of-N, where N is 7-9 signers from different time zones, M is 4-5. Fewer is unsafe. More is an operational nightmare for urgent transactions. Safe supports modules: Zodiac, Delay, Roles. Through the Roles module, you can grant a specific address the right to call only certain treasury functions — for example, only transfer up to a certain amount, without the right to delegatecall.

Important: Safe multisig and Governor are separate layers. Governor manages the protocol (upgrades, parameters). Safe manages the treasury (payments, grants). Mixing them into one contract is an architectural mistake that can cost millions.

How to protect a DAO from flash loan attacks?

We use multiple layers of protection. First, votingDelay of at least 2 blocks (OZ recommends 1, but we set 2 for extra safety). Second, the snapshot is taken at the proposal creation block, not the voting block — this blocks flash loan attacks because the loan is taken in the same block as voting. Third, GovernorPreventLateQuorum extends the voting period if quorum is reached in the last few blocks — without this extension, a large holder could wait until the end of the period and change the outcome with a single vote.

Governor Extensions: almost always needed

Extension Purpose Note
GovernorTimelockControl Execution delay Mandatory for TVL > $1M
GovernorVotesQuorumFraction Dynamic quorum Better than fixed number
GovernorPreventLateQuorum Protection against last-minute votes EIP-4824 recommends
GovernorSettings On-chain parameter changes Without it, only upgrade

On-chain vs Off-chain voting: when to choose each

Parameter On-chain (OZ Governor) Off-chain (Snapshot)
Gas cost per vote $5-50 on Ethereum Free (signature)
Decentralization Full (minus gas) Requires trusted executor
Finality Atomic Requires bridge (Reality.eth)
Attack complexity Flash loan Sybil attack (solvable)

Choice depends on community budget and security requirements. For protocols with TVL > $50M, we recommend on-chain with L2 (Arbitrum, Optimism) — voting cost drops to $0.05-0.5.

Development process and parameter audit

Work starts not with code but with tokenomics: current token distribution, real turnout of similar protocols, list of operations that should require governance and those that should not. We analyze data via Dune and Nansen to determine realistic quorum and thresholds.

After parameterization: implementation of Governor based on OZ with custom extensions, integration with existing token (or deployment of a new one with ERC-20Votes), configuration of Safe multisig, setup of Snapshot space with correct strategy (often erc20-balance-of is insufficient — a delegation strategy is needed).

Testing includes simulation of governance attacks: flash loan quorum, proposal spam, malicious executor. Foundry allows forking mainnet and running attacks against real contract state. Deploying Governor without parameter audit is a standard mistake. Auditors look at code. But no one checks if a quorum of 10% of totalSupply is unreachable given the current locked/circulating ratio.

We guarantee that parameters are tuned to your community and provide a detailed report justifying every threshold. Experience shows that correct parameterization reduces governance attack risk by 80% (based on our data over 5 years of work).

What you will get in the end

  • Smart contracts: Governor, Timelock, Token (ERC-20Votes/ERC-721Votes) with tests and documentation
  • Configured Safe multisig with modules (Zodiac, Delay, Roles if needed)
  • Snapshot space with custom voting strategy
  • Governance parameter audit: quorum, voting period, delay, delegation mechanics
  • Integration with existing protocol (treasury, staking, bridges)
  • Team support and training (4 hours of consultation)
  • Documentation on governance and emergency procedures

Timeline

Basic DAO system (Governor + Timelock + Safe + Snapshot) — from 3 to 6 weeks. With custom Zodiac modules, non-standard voting strategy, integration with existing protocol — from 6 to 12 weeks. Audit takes separately 2-4 weeks.

Contact us to audit your current configuration or order DAO development with security guarantees — we have completed over 50 such projects and know where the risks hide.