Розробка квадратичного голосування для DAO та DeFi

Проєктуємо та розробляємо блокчейн-рішення повного циклу: від архітектури смарт-контрактів до запуску DeFi-протоколів, NFT-маркетплейсів та криптобірж. Аудит безпеки, токеноміка, інтеграція з наявною інфраструктурою.
Показано 1 з 1Усі 1305 послуг
Розробка квадратичного голосування для DAO та DeFi
Складний
~1-2 тижні
Часті запитання

Напрямки блокчейн-розробки

Етапи блокчейн-розробки

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1374
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1256
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    965
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1208
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    667
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    954

Квадратичне голосування (quadratic voting) вирішує фундаментальну проблему токен-зваженого голосування: у кита 1000x токенів → 1000x впливу. Ми проектуємо системи, де сила голосу пропорційна квадратному кореню від витраченого ресурсу. 100 голосувальних кредитів дають 10 одиниць голосової сили. 900 кредитів — 30. Для такої ж сили, що 9 осіб з 1 кредитом, потрібно витратити 81 кредит. Математика: вплив = √credits. Це робить економічно невигідним домінування одного учасника порівняно з широкою коаліцією. Наш досвід — 5+ років у блокчейн-розробці, понад 10 реалізованих систем голосування. Гарантуємо аудит коду та захист від атак.

Як квадратичне голосування вирішує проблему домінування китів?

У стандартному голосуванні власник 10 000 токенів має в 100 разів більше впливу, ніж власник 100 токенів. QV змінює це: при кредитах, пропорційних балансу, сила голосу відрізняється в √100 = 10 разів. Для DAO з нерівномірним розподілом токенів це суттєво підвищує справедливість.

QV був запропонований економістами Еріком Познером і Гленом Вейлом в книзі Radical Markets. Intuition за механізмом: у стандартному голосуванні 1 особа = 1 голос, але інтенсивність уподобань не враховується. Той, кому дуже важливий результат, і той, кому байдуже, мають однакову вагу. QV дозволяє виражати інтенсивність через кількість витрачених кредитів — це ближче до реальних економічних уподобань.

Приклад: 100 осіб трохи віддають перевагу варіанту A. 10 осіб дуже хочуть варіант B. У стандартному голосуванні перемагає A. У QV, якщо кожен з 10 витратить 100 кредитів на B (сила = 10 × √100 = 100), вони можуть переголосувати коаліцію зі 100, кожен з яких витратив 1 кредит (сила = 100 × √1 = 100). При балансі уподобань переможе більш інтенсивно бажаний результат.

Критерій Стандартне (1 токен = 1 голос) Квадратичне (QV)
Вплив кита Лінійний (1000x токенів = 1000x сила) Сублінійний (1000x токенів ≈ 31.6x сила)
Вираження інтенсивності Неможливе Через кількість кредитів
Sybil-стійкість Низька (кожна адреса = 1 голос) Вимагає зовнішньої верифікації
Газові витрати Низькі Вищі (розрахунок sqrt)
Складність для учасників Проста Середня (стратегія розподілу)

Системи голосувальних кредитів

Voice Credits модель

Стандартна схема: кожен учасник отримує фіксований бюджет voice credits на період голосування. Кредити не переносяться і не передаються — кожен період fresh allocation.

contract QuadraticVoting {
    struct VotingRound {
        uint256 startTime;
        uint256 endTime;
        mapping(uint256 => int256) optionVotes;  // optionId => суммарні голоси (sqrt-зважені)
    }

    uint256 public constant CREDITS_PER_ROUND = 100;

    // Витрачені кредити учасника в поточному раунді
    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: голосова сила = 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;
        }
    }
}

Токен-зважені кредити

Альтернативна схема: кредити пропорційні балансу токенів (як у Gitcoin Grants). Власник 1000 токенів має 1000 кредитів. Але голосова сила все одно √ від витрачених кредитів. Це дає багатим учасникам більше кредитів, але не лінійний вплив.

Порівняння: при кредитах пропорційних балансу і балансі 10 000 vs 100 (100x різниця) — голосова сила відрізняється в √100 = 10x, не в 100x. Це значно краще ніж стандартне token-weighted.

Delegated QV

Учасник може делегувати свої кредити іншому учаснику. Делегат голосує пакетом кредитів, але все одно застосовується коренева функція до сумарних кредитів на кожен варіант від кожного початкового власника.

Важливий нюанс: агрегація кредитів від делегатів повинна зберігати інформацію про джерело. Якщо просто підсумувати кредити делегатора в пулі делегата — втрачається QV властивість.

// Правильна агрегація: кожен delegation entry окремо
struct Delegation {
    address delegator;
    uint256 credits;
}

// Голосування делегата: застосовує QV до кожного делегування окремо
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;
}

Чому Sybil-атака критична для QV і як ми її запобігаємо?

QV повністю ламається без захисту від Sybil-атак. Один учасник зі 100 кредитами отримує силу 10. Сто учасників з 1 кредитом кожен отримують сумарну силу 100. Розділивши ідентичність на N адрес, атакуючий множить свою силу в √N разів.

Proof of Humanity

Зареєстрована унікальна особистість в Proof of Humanity або Worldcoin отримує 1 алокацію кредитів. Не піддається Sybil — створити тисячу реальних людей неможливо.

Інтеграція через on-chain перевірку:

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;
    }
}

Проблема PoH: охоплення обмежене, реєстрація займає час, оскаржувана. Для DAO з глобальною аудиторією — бар’єр входу.

Worldcoin World ID

Більш масштабоване рішення. Iris scan → ZK proof унікальності. Верифікація on-chain через семафор протокол без розкриття особистих даних.

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 {
        // Верифікує ZK proof унікальності
        worldId.verifyProof(
            root,
            groupId,
            abi.encodePacked(signal).hashToField(),
            nullifierHash,
            externalNullifierHash,
            proof
        );

        require(!nullifierUsed[nullifierHash], "Already registered");
        nullifierUsed[nullifierHash] = true;
        // видати кредити
    }
}

Stake-based anti-sybil

Для DeFi-oriented DAO: вимагати stake токенів для участі. Створення багатьох Sybil акаунтів стає дорогим. Комбінація з QV: stake визначає базовий кредит, але голосова сила все одно √ від витраченого.

Повна архітектура системи

On-chain компоненти

  • QuadraticVoting.sol: core контракт з логікою кредитів та голосування
  • IdentityRegistry.sol: зв'язок адрес з верифікованими ідентичностями (PoH/Worldcoin)
  • VotingRoundFactory.sol: створення раундів з параметрами (duration, options, credit allocation)

Off-chain компоненти

Snapshot integration: більшість DAO використовують Snapshot для off-chain QV голосувань — безкоштовно та без обмежень за кількістю учасників. Snapshot підтримує QV стратегію.

Results calculator: off-chain сервіс для складних QF розрахунків, з подальшою публікацією результатів on-chain.

Frontend: інтерфейс, де учасник бачить свій бюджет кредитів, слайдери для розподілу за варіантами, live preview голосової сили кожного рішення.

Параметр Рекомендація Обґрунтування
Базові кредити 99-100 Зручний для √ розрахунків
Тривалість раунду 7-14 днів Час для усвідомленої участі
Перенесення кредитів Ні Запобігає накопиченню та атакам
Мінімальний stake 0.01-0.1% supply Базовий anti-sybil без високого бар'єру
Sybil protection PoH + stake Багаторівневий захист

Обмеження та чесний погляд

QV не вирішує всі проблеми governance. Слабкі місця:

  • Collusion: група учасників може координувати розподіл кредитів для максимізації сумарного впливу. Це складніше ніж у стандартному голосуванні, але не неможливо. MACI (Minimum Anti-Collusion Infrastructure) вирішує це через ZK cryptography.
  • Rational ignorance: більшість учасників не витрачатимуть час на вивчення 20 пропозицій у раунді. QV знижує вартість ігнорування, але не усуває її.
  • Оптимальна стратегія: математично оптимальна стратегія для учасника — не очевидна. Це може знижувати participation у нетехнічних учасників.

QV краще підходить для обмежених наборів варіантів (вибір пріоритетів, розподіл грантів) ніж для бінарних так/ні рішень за протоколом.

Що входить до роботи

  • Аудит поточної структури управління та постановка завдання
  • Проектування архітектури смарт-контрактів (Solidity/Foundry або Rust/Anchor)
  • Реалізація core-контрактів QV з voice credits та квадратичним підрахунком
  • Інтеграція Sybil-захисту (PoH, Worldcoin, або stake-based)
  • Розробка фронтенду (React/viem/RainbowKit) з візуалізацією впливу
  • Написання unit-тестів та integration-тестів (Foundry/Tenderly)
  • Розгортання та налаштування раунду голосування
  • Документація для користувачів та адміністраторів
  • Пост-релізна підтримка на 1 місяць

Як ми розробляємо систему квадратичного голосування: покроково

  1. Аналітика (2-3 дні): розбираємо поточні процеси, виявляємо біль та вимоги до голосування.
  2. Проектування (3-5 днів): створюємо архітектуру смарт-контрактів, обираємо методи Sybil-захисту та платформу.
  3. Розробка (14-30 днів): пишемо контракти на Solidity, інтегруємо PoH/Worldcoin, розробляємо фронтенд.
  4. Тестування (5-7 днів): проводимо unit- та integration-тести, використовуємо Slither та Mythril для статичного аналізу.
  5. Деплой (1-2 дні): розгортаємо контракти в mainnet, налаштовуємо раунд голосування.
  6. Пост-релізна підтримка: 1 місяць моніторингу та виправлень.

Терміни: від 3 тижнів (базовий QV без anti-sybil) до 12 тижнів (повний продукт з PoH/Worldcoin та делегуванням). Вартість розраховується індивідуально — інвестиції в справедливе голосування окупаються завдяки зниженню конфліктів та підвищенню активності спільноти.

Приклад розрахунку голосів Учасник з 9 кредитами отримує 3 голоси (√9). Якщо він хоче підтримати два варіанти, розподіл 4 і 5 кредитів дає 2 + 2.236 = 4.236 голоси, що більше, ніж 3 при концентрації на одному варіанті. Це стимулює розподіляти кредити, а не концентрувати.

Отримайте консультацію щодо впровадження квадратичного голосування у вашу DAO. Наші інженери запропонують оптимальне рішення під ваші завдання. Зв'яжіться з нами, щоб обговорити деталі.

Розробка DAO: управління, яке працює

Ми займаємося розробкою DAO понад 5 років — провели більше 30 інтеграцій Governor, Safe та Snapshot для протоколів зі значним TVL. Проблема типова: протокол піднято, ліквідність є, токен розподілено. Наступний крок — передача управління спільноті. На практиці це означає: хтось повинен написати контракти, які не дозволять 5% холдерів злити казну через одне голосування, і при цьому не заблокують легітимні апгрейди на 18 місяців. Баланс нетривіальний.

Чому більшість DAO стають олігархією?

Типовий сценарій: форкають OpenZeppelin Governor, деплоять, запускають Snapshot — і отримують DAO, яким на практиці управляють 3 адреси. Проблема не в коді, а в токеноміці та параметрах.

Quorum занадто високий або занадто низький. Compound встановив quorum у 400 000 COMP. При низькій явці пропозали не проходять місяцями. При низькому quorum — один великий холдер закриває будь-яке питання. Правильний quorum залежить від реального розподілу токенів і середнього turnout, а не від красивої цифри. Ми аналізуємо історію голосувань, частку locked vs circulating і підбираємо динамічний quorum через GovernorVotesQuorumFraction.

Flash loan governance attack. Класика: атакуючий бере flash loan, отримує voting power на один блок, створює і проводить пропозал. Захист — votingDelay мінімум 1-2 блоки плюс snapshot на блоці створення пропозалу, а не на блоці голосування. OpenZeppelin's GovernorVotes робить snapshot коректно, але якщо пишеш кастомний контракт — легко помилитися. Beanstalk втратив значну суму через відсутність whitelist target'ів у timelock — саме цей кейс став індустріальним стандартом помилки.

Timelock без executor whitelist. Якщо TimelockController не обмежує список дозволених target-контрактів, через прийнятий пропозал можна викликати довільну функцію. Ми завжди налаштовуємо TimelockController з білим списком адрес і мінімальною затримкою 48 годин для протоколів з TVL понад певний поріг. Для великих — 7 днів, що дає час на оскарження через hard fork або мультисиг emergency.

Архітектура on-chain управління

Стандартний стек: OpenZeppelin Governor + TimelockController + ERC-20Votes (або ERC-721Votes для NFT-based governance). Ми використовуємо Foundry для розробки та тестування — це дозволяє fork mainnet і симулювати атаки проти реального стану контрактів.

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

Governor відповідає за логіку голосування: propose, castVote, queue, execute. Timelock додає затримку між прийняттям пропозалу і його виконанням — це вікно для виходу незгодних. Delegated voting через ERC-20Votes критично для протоколів з великою кількістю пасивних власників: без нього quorum фізично недосяжний.

Snapshot + on-chain: гібридна модель

Повністю on-chain голосування коштують газу. Для протоколів з активним ком'юніті це означає або високий бар'єр участі, або L2. Гібридна модель: Snapshot для сигнального голосування (off-chain, gasless через EIP-712 підписи), on-chain тільки для виконання. Ми віддаємо перевагу SafeSnap (Zodiac module від Gnosis) — результат верифікується через Reality.eth (optimistic oracle) і автоматично виконується через Safe без довіреної сторони.

Multi-sig: Gnosis Safe як операційний шар

Більшість DAO використовують Gnosis Safe для скарбниці. Стандартна конфігурація: M-of-N, де N — 7-9 підписантів з різних часових зон, M — 4-5. Менше — небезпечно. Більше — операційне пекло при термінових транзакціях. Safe підтримує модулі: Zodiac, Delay, Roles. Через Roles модуль можна дати конкретній адресі право викликати тільки певні функції скарбниці — наприклад, тільки transfer до певної суми, без права на delegatecall.

Важливо: Safe мультисиг і Governor — різні рівні. Governor управляє протоколом (апгрейди, параметри). Safe управляє скарбницею (виплати, гранти). Змішувати їх в один контракт — помилка архітектури, яка може коштувати мільйонів.

Як захистити DAO від flash loan атаки?

Ми використовуємо кілька рівнів захисту. По-перше, votingDelay не менше 2 блоків (рекомендація OZ говорить про 1, але ми ставимо 2 для додаткової безпеки). По-друге, snapshot робиться на блоці створення пропозалу, а не на блоці голосування — це блокує flash loan attacks, оскільки позика береться в тому ж блоці, що й голосування. По-третє, GovernorPreventLateQuorum продовжує voting period, якщо quorum досягнуто в останні блоки — без цього розширення великий холдер може дочекатися закінчення періоду і одним голосом змінити результат.

Governor Extensions: що потрібно майже завжди

Розширення Для чого Примітка
GovernorTimelockControl Затримка виконання Обов'язково при TVL понад $1M
GovernorVotesQuorumFraction Динамічний quorum Краще фіксованого числа
GovernorPreventLateQuorum Захист від last-minute votes EIP-4824 рекомендує
GovernorSettings On-chain зміна параметрів Без нього — тільки апгрейд

On-chain vs Off-chain голосування: коли що вибирати

Параметр On-chain (OZ Governor) Off-chain (Snapshot)
Gas cost per vote Певна сума на Ethereum Безкоштовно (підпис)
Decentralization Повна (мінус газова) Вимагає довіреного executor
Finality Атомарна Вимагає моста (Reality.eth)
Складність атаки Flash loan Sybil attack (вирішувано)

Вибір залежить від бюджету ком'юніті та вимог до безпеки. Для протоколів з великим TVL ми рекомендуємо on-chain з L2 (Arbitrum, Optimism) — вартість голосування суттєво знижується.

Процес розробки та аудит параметрів

Робота починається не з коду, а з токеноміки: поточний розподіл токенів, реальний turnout аналогічних протоколів, список операцій, які повинні вимагати governance, і які — ні. Ми аналізуємо дані через Dune та Nansen, щоб визначити realistic quorum та thresholds.

Після параметризації: реалізація Governor на основі OZ з кастомними розширеннями, інтеграція з існуючим токеном (або деплой нового з ERC-20Votes), конфігурація Safe мультисига, налаштування Snapshot space з правильною стратегією (часто erc20-balance-of недостатньо — потрібна delegation стратегія).

Тестування включає симуляцію governance attacks: flash loan quorum, proposal spam, malicious executor. Foundry дозволяє fork mainnet і прогнати атаки проти реального стану контрактів. Деплой Governor без аудиту параметрів — стандартна помилка. Аудитори дивляться код. Але ніхто не перевірить, що quorum у 10% від totalSupply недосяжний при поточному locked/circulating ratio.

Ми гарантуємо, що параметри налаштовані під вашу спільноту, і надаємо детальний звіт з обґрунтуванням кожного порогу. Досвід показує: правильна параметризація знижує ризик governance attack на 80% (за нашими даними за весь час роботи).

Що входить в роботу

  • Смарт-контракти Governor, Timelock, Token (ERC-20Votes/ERC-721Votes) з тестами та документацією
  • Налаштований Safe мультисиг з модулями (Zodiac, Delay, Roles при необхідності)
  • Snapshot space з кастомною стратегією голосування
  • Аудит параметрів governance: quorum, voting period, delay, delegation mechanics
  • Інтеграція з існуючим протоколом (скарбниця, стейкінг, бриджі)
  • Підтримка та навчання команди (4 години консультацій)
  • Документація з управління та emergency процедурам

Терміни

Базова DAO-система (Governor + Timelock + Safe + Snapshot) — від 3 до 6 тижнів. З кастомними модулями Zodiac, нестандартною стратегією голосування, інтеграцією з існуючим протоколом — від 6 до 12 тижнів. Аудит займає окремо 2-4 тижні.

Замовте розробку DAO під ключ з гарантією безпеки — ми провели більше 50 подібних проєктів і знаємо, де приховуються ризики. Отримайте консультацію щодо вашої поточної конфігурації або параметрів для нового протоколу.