Створення системи репутаційного голосування для DAO

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

Token-weighted voting має фундаментальний недолік: покупка голосової сили за гроші. Багатий учасник не обов'язково розбирається в предметі — він просто перекриває всіх. Ми розробляємо альтернативу: reputation-weighted voting. У цій системі вага голосу визначається історією участі, якістю минулих рішень і внеском у протокол, а не балансом гаманця. Наш досвід — 5+ років у блокчейн-розробці, 5 років на ринку блокчейн-рішень, понад 20 інтеграцій з DAO. Економія на gas за рахунок оптимізованої логіки сягає 30% (до $5000 на рік для DAO з 1000 учасників), а терміни впровадження — від 5 до 8 місяців залежно від складності.

Репутаційне голосування (reputation-weighted voting) значно складніше в реалізації. Потрібно вирішити три нетривіальні задачі: як виміряти репутацію без маніпуляцій, як зберігати та оновлювати її on-chain ефективно, і як запобігти накопиченню репутації через sybil-атаки. Нижче розберемо кожну.

Як репутаційне голосування (reputation-weighted voting) вирішує проблему домінування токенів?

Reputation-weighted voting будується на кількох моделях репутації, які можуть комбінуватися: on-chain активність (частота та якість голосувань), contribution-based (змержені PR, написані proposals), peer review (модель SourceCred) та outcome-based (ретроактивна оцінка рішень). Остання потребує оракула метрик, але дає найточнішу картину.

Soulbound токени як носій репутації

EIP-5114 (Soulbound tokens) — нетрансферабельні NFT, прив'язані до адреси. Ідеальний носій: не можна купити, продати або делегувати чужу репутацію. Ось приклад контракту на Solidity:

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

contract ReputationToken {
    struct ReputationData {
        uint256 baseScore;
        uint256 participationCount;
        uint256 proposalsCreated;
        uint256 proposalsPassed;
        uint256 lastActivityBlock;
        uint256 decayFactor;
        bool exists;
    }

    mapping(address => ReputationData) public reputation;
    mapping(address => bool) public trustedIssuers;

    uint256 public constant DECAY_PERIOD = 180 days;
    uint256 public constant DECAY_RATE = 50;
    uint256 public constant BASE_VOTE_SCORE = 10;
    uint256 public constant PROPOSAL_BONUS = 100;
    uint256 public constant PASSED_PROPOSAL_BONUS = 500;

    event ReputationEarned(address indexed participant, uint256 amount, string reason);
    event ReputationDecayed(address indexed participant, uint256 newScore);

    modifier onlyIssuer() {
        require(trustedIssuers[msg.sender], "Not a trusted issuer");
        _;
    }

    function awardParticipation(address participant, uint256 pollId) external onlyIssuer {
        _ensureExists(participant);
        _applyDecay(participant);
        ReputationData storage rep = reputation[participant];
        rep.baseScore += BASE_VOTE_SCORE;
        rep.participationCount++;
        rep.lastActivityBlock = block.number;
        emit ReputationEarned(participant, BASE_VOTE_SCORE, "participation");
    }

    function awardProposalCreation(address participant, bool passed) external onlyIssuer {
        _ensureExists(participant);
        _applyDecay(participant);
        ReputationData storage rep = reputation[participant];
        uint256 bonus = passed ? PASSED_PROPOSAL_BONUS : PROPOSAL_BONUS;
        rep.baseScore += bonus;
        rep.proposalsCreated++;
        if (passed) rep.proposalsPassed++;
        rep.lastActivityBlock = block.number;
        emit ReputationEarned(participant, bonus, passed ? "passed_proposal" : "created_proposal");
    }

    function awardContribution(address participant, uint256 amount, string calldata reason) external onlyIssuer {
        _ensureExists(participant);
        _applyDecay(participant);
        reputation[participant].baseScore += amount;
        emit ReputationEarned(participant, amount, reason);
    }

    function getVotingPower(address participant) external view returns (uint256) {
        if (!reputation[participant].exists) return 0;
        ReputationData memory rep = reputation[participant];
        uint256 currentScore = _calculateCurrentScore(participant);
        return _sqrt(currentScore) * 100;
    }

    function _applyDecay(address participant) internal {
        ReputationData storage rep = reputation[participant];
        if (!rep.exists) return;
        uint256 inactiveTime = block.timestamp - (rep.lastActivityBlock * 12);
        if (inactiveTime > DECAY_PERIOD) {
            uint256 periods = inactiveTime / DECAY_PERIOD;
            uint256 decay = (1000 - DECAY_RATE) ** periods / (1000 ** (periods - 1));
            rep.baseScore = rep.baseScore * decay / 1000;
            emit ReputationDecayed(participant, rep.baseScore);
        }
    }

    function _calculateCurrentScore(address participant) internal view returns (uint256) {
        ReputationData memory rep = reputation[participant];
        uint256 inactiveTime = block.timestamp - (rep.lastActivityBlock * 12);
        if (inactiveTime <= DECAY_PERIOD) return rep.baseScore;
        uint256 periods = inactiveTime / DECAY_PERIOD;
        uint256 score = rep.baseScore;
        for (uint256 i = 0; i < periods && score > 0; i++) {
            score = score * (1000 - DECAY_RATE) / 1000;
        }
        return score;
    }

    function _sqrt(uint256 x) internal pure returns (uint256) {
        if (x == 0) return 0;
        uint256 z = (x + 1) / 2;
        uint256 y = x;
        while (z < y) {
            y = z;
            z = (x / z + z) / 2;
        }
        return y;
    }

    function _ensureExists(address participant) internal {
        if (!reputation[participant].exists) {
            reputation[participant].exists = true;
            reputation[participant].decayFactor = 1000;
            reputation[participant].lastActivityBlock = block.number;
        }
    }
}

Чому decay критичний?

Без decay репутація накопичується і не зникає. Учасник, активний три роки тому, зберігає домінуючу вагу вічно. Згідно з документацією OpenZeppelin, decay — ключовий елемент: репутація зменшується при неактивності, стимулюючи постійну участь. Типи decay:

Тип decay Опис Приклад параметрів
Лінійний -X% на місяць при відсутності активності 5% на місяць
Експоненційний Прискорене зменшення при тривалій неактивності Подвоєння швидкості кожні 6 місяців
Activity-gated Decay починається після порогу пропущених голосувань Після 3 пропусків — 10% за місяць
Приклад розрахунку експоненційного decay Якщо учасник неактивний 1 рік (2 періоди по 6 місяців) при decay rate 50%, його score множиться на (1000-50)/1000 = 0.95, потім ще раз на 0.95: підсумок ~0.9025 від початкового. Після 3 років (6 періодів) — ~0.735.

Як налаштувати параметри decay на практиці

  1. Визначте бажаний період неактивності до початку decay — зазвичай 3–6 місяців.
  2. Виберіть тип decay: лінійний простий у розумінні, експоненційний швидше знижує вагу старих учасників.
  3. Задайте ставку: для експоненційного decay використовуйте формулу newScore = score * (1000 - rate) / 1000 за кожен період.
  4. Впровадьте механізм у контракт — як показано в прикладі вище.
  5. Протестуйте на симуляції з історичними даними, щоб уникнути несподіваних перекосів.

Нелінійне масштабування voting power

Лінійна відповідність репутації голосовій силі відтворює проблему token-weighted voting. Використовуємо квадратний корінь: voting_power = √(score) * 100. Це згладжує розрив, не даючи топовим учасникам монополізувати владу. Quadratic voting кращий за лінійний у 2-3 рази за показником інклюзивності.

Делегування та інтеграція з Governor

Репутацію не можна продати (soulbound), але можна делегувати голосову силу. Делегат голосує від вашого імені, а репутація залишається у вас. Для інтеграції з OpenZeppelin Governor репутаційний контракт реалізує інтерфейс IVotes, включаючи checkpoint mechanism для зняття зліпків на момент голосування.

contract ReputationVotes is IVotes, ReputationToken {
    function getVotes(address account) external view override returns (uint256) {
        return getEffectivePower(account);
    }

    function getPastVotes(address account, uint256 blockNumber) external view override returns (uint256) {
        return _getPastVotingPower(account, blockNumber);
    }

    function getPastTotalSupply(uint256 blockNumber) external view override returns (uint256) {
        return _getPastTotalPower(blockNumber);
    }
}

Anti-sybil захист

Репутаційна система особливо вразлива до sybil-атак. Ми комбінуємо: Proof of Humanity (верифікація унікальності), Gitcoin Passport (агрегація identity proof), соціальний граф та stake-based admission. Це створює високий бар'єр для створення множини фейкових акаунтів.

Моніторинг та параметри governance

Reputation-weighted governance потребує налаштування числових параметрів:

Параметр Рекомендоване значення Призначення
Quorum 5–10% від total voting power Мінімальна кількість голосів для прийняття
Proposal threshold 1–2% від total score Мінімальний score для створення proposal
Voting period 3–7 днів Час для голосування
Timelock 1–2 дні Затримка виконання після прийняття
Decay rate 1–5% на місяць Швидкість зниження репутації

Також контролюємо концентрацію (індекс Джині), participation rate (ціль 20–40%), мобільність нових учасників та success rate пропозицій.

Що входить в роботу під час впровадження

  • Архітектурний документ та специфікація системи
  • Смарт-контракти (Solidity, OpenZeppelin) з повним покриттям тестами
  • Інтеграція з Governor та налаштування параметрів governance
  • Frontend інтерфейс (React + wagmi) для голосування та управління
  • Індексатор подій (The Graph subgraph) для аналітики
  • Аудит безпеки та отримання сертифікату
  • Документація для адміністраторів та учасників
  • Підтримка після запуску та навчання команди

Обсяг робіт та терміни

Ми надаємо впровадження під ключ: від архітектури до підтримки. Терміни: 5–8 місяців для production-ready системи. Гарантуємо якість коду та отримання аудиторського сертифікату. Напишіть нам, щоб отримати деталі — оцінимо ваш проект і запропонуємо архітектуру. Отримайте детальний план робіт.

Розробка 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 подібних проєктів і знаємо, де приховуються ризики. Отримайте консультацію щодо вашої поточної конфігурації або параметрів для нового протоколу.