Previous Module
Snapshot Voting Visual

🛠️ Implementation: Sybil Resistance

Learn how DAOs prevent fake accounts from exploiting QV

Experience a fairer voting mechanism

🛠️ Implementation Strategies

Implementing quadratic voting requires choosing your trade-offs. Pure quadratic (votes = √tokens) is simple but vulnerable to sybil attacks. Adding identity verification blocks sybils but sacrifices privacy. Adding time-weighting rewards long-term holders but punishes new members. Most production systems use hybrid approaches combining multiple mechanisms. Let's explore the strategy landscape.

🎮 Interactive: Strategy Comparison Tool

Select an implementation strategy to see its advantages, disadvantages, best use cases, and real-world examples. Compare trade-offs to choose the right approach for your DAO.

√ Pure Quadratic (No Identity)

votes = √tokens with no additional requirements. Simplest implementation but vulnerable to sybil attacks and vote buying.

✓ Advantages
  • Simplest to implement (just sqrt function)
  • No identity verification overhead
  • Maximum privacy (no KYC)
  • Lowest gas costs
  • Immediate participation (no verification delay)
⚠️ Disadvantages
  • Vulnerable to sybil attacks (wallet splitting)
  • Vote buying is economically rational
  • No defense against collusion
  • Whales can game system via multiple wallets
  • Trust in honest participation required
🎯 Best For

Low-stakes decisions, trusted communities, experimental DAOs, or when identity verification is philosophically unacceptable.

💼 Real Examples

Early quadratic funding experiments, internal team voting, community polls (non-binding)

📋 Implementation Checklist

1️⃣
Choose Your Formula

Decide on voting power calculation: pure quadratic (√tokens), time-weighted (√(tokens × days)), capped quadratic (√tokens with maximum), or hybrid. Consider your DAO's risk tolerance for whale dominance vs sybil attacks.

2️⃣
Identity Verification (If Needed)

If blocking sybil attacks is critical, integrate identity system: Gitcoin Passport (most common), BrightID (decentralized social graph), Proof of Humanity (video verification), or ENS + on-chain activity (lightweight). Each has privacy/friction trade-offs.

3️⃣
Snapshot Integration

Use snapshot.org with custom voting strategy. Create JavaScript function that calculates √tokens (or variant) from wallet balances. Snapshot handles off-chain signatures, zero gas costs, and historical state. Custom strategies are public and auditable.

4️⃣
On-Chain Execution (Optional)

For binding votes, integrate SafeSnap (Gnosis Safe module) or custom execution contract. Snapshot results trigger on-chain transactions if threshold is met. Only successful votes pay gas. Requires oracle to bridge off-chain → on-chain.

5️⃣
Test in Staging

Deploy to testnet, simulate attacks: wallet splitting (sybil), large token purchases (whale accumulation), collusion (coordinated voting). Verify formula works as expected. Check gas costs for on-chain components. Run multiple test votes with different participation levels.

6️⃣
Document & Educate

Create guides explaining quadratic voting to your community. Most users won't understand √tokens intuitively. Provide calculator tools showing "X tokens = Y votes." Document trade-offs, especially vote buying economics. Transparency builds trust.

7️⃣
Start Small, Iterate

Use quadratic voting for low-stakes decisions first (community polls, grant allocations, feature prioritization). Observe gaming attempts. Collect feedback. Adjust parameters (identity requirements, time weights, quorum thresholds) based on behavior. Graduate to high-stakes votes only after validation.

💻 Code Example: Snapshot Custom Strategy

Here's a simplified quadratic voting strategy for Snapshot. This calculates √(token balance) for each voter:

// snapshot-strategies/quadratic-voting/index.js
export async function strategy(
  space,
  network,
  provider,
  addresses,
  options,
  snapshot
) {
  const blockTag = typeof snapshot === 'number' ? snapshot : 'latest';
  
  // Get token balances for all addresses
  const balances = await getBalances(
    provider,
    options.address, // token contract
    addresses,
    blockTag
  );

  // Apply quadratic formula: votes = sqrt(balance)
  return Object.fromEntries(
    Object.entries(balances).map(([address, balance]) => [
      address,
      Math.sqrt(balance / 10**options.decimals) // normalize by decimals
    ])
  );
}

Note: Production strategies should handle decimal precision, prevent overflow, and validate inputs. This is conceptual pseudocode. See snapshot-labs/snapshot-strategies on GitHub for real implementations.

💡 Key Insight

There's no perfect quadratic voting implementation. Every approach trades off between simplicity, security, privacy, and inclusivity. Pure quadratic is vulnerable to sybils. Identity-verified quadratic sacrifices privacy. Time-weighted quadratic punishes new members. Hybrid approaches are complex and expensive. Choose based on your threat model: If whales are your biggest risk, use pure quadratic. If sybils are the threat, add identity verification. If both, go hybrid and accept the complexity cost. Most successful implementations start simple and add complexity only when needed. Gitcoin began with pure quadratic, added Passport when sybil attacks emerged, and continues iterating. Your DAO should do the same.

← Vote Buying Economics