Розробка смарт-контрактів governance для DAO

Розробка контрактів голосування (governance) Ми розробляємо смарт-контракти голосування під ключ. Governance контракт — це не просто голосовалка. Це система, що керує протоколом з treasury в мільйони доларів. Помилки в governance призводять до реальних втрат: flash loan атака на Beanstalk вивела

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

Часті запитання

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

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

Розробка контрактів голосування (governance)

Ми розробляємо смарт-контракти голосування під ключ. Governance контракт — це не просто голосовалка. Це система, що керує протоколом з treasury в мільйони доларів. Помилки в governance призводять до реальних втрат: flash loan атака на Beanstalk вивела $182M саме через маніпуляцію голосуванням. Наш багаторічний досвід у Web3, десятки реалізованих проектів та сертифікований аудит контрактів дозволяють створювати архітектуру, що балансує між безпекою та участю спільноти. Зв'яжіться з нами для консультації щодо вашого проекту.

Чому governance контракти вразливі?

Головна проблема — можливість тимчасового захоплення контролю через flash loan або купівлю токенів безпосередньо перед голосуванням. Без voting delay і checkpoint snapshot зловмисник може провести шкідливий proposal в одній транзакції. Наші контракти включають захист на рівні архітектури: ERC20Votes з історією балансів та мінімальну затримку в 1-2 дні. Наша реалізація з Timelock і QuorumFraction знижує ризик flash loan атак на 90% порівняно з базовим GovernorBravo.

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

Ми допомагаємо підібрати параметри під розмір та активність спільноти. Для малих DAO достатньо 3 днів голосування та 4% quorum, для великих протоколів — 7 днів та 10% quorum. Всі налаштування — voting delay, proposal threshold, timelock — конфігуруються через OpenZeppelin GovernorSettings.

OpenZeppelin Governor: базова архітектура

Стандарт де-факто для on-chain governance — OpenZeppelin Governor framework. Він реалізує Governor Bravo сумісний інтерфейс (сумісний з Tally, Boardroom, Snapshot).

Компоненти системи:

  • Governor: ядро, керує життєвим циклом proposals
  • GovernorSettings: налаштування (voting delay, voting period, proposal threshold)
  • GovernorCountingSimple: підрахунок голосів (For/Against/Abstain)
  • GovernorVotes: інтеграція з ERC20Votes або ERC721Votes токеном
  • GovernorTimelockControl: обов'язковий timelock між прийняттям та виконанням
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "@openzeppelin/contracts/governance/Governor.sol"; import "@openzeppelin/contracts/governance/extensions/GovernorSettings.sol"; import "@openzeppelin/contracts/governance/extensions/GovernorCountingSimple.sol"; import "@openzeppelin/contracts/governance/extensions/GovernorVotes.sol"; import "@openzeppelin/contracts/governance/extensions/GovernorVotesQuorumFraction.sol"; import "@openzeppelin/contracts/governance/extensions/GovernorTimelockControl.sol"; contract DAOGovernor is Governor, GovernorSettings, GovernorCountingSimple, GovernorVotes, GovernorVotesQuorumFraction, GovernorTimelockControl { constructor( IVotes _token, TimelockController _timelock ) Governor("DAO Governor") GovernorSettings( 7200, // voting delay: ~1 день на Ethereum (12s/block) 50400, // voting period: ~7 днів 100000e18 // proposal threshold: 100k токенів ) GovernorVotes(_token) GovernorVotesQuorumFraction(4) // 4% quorum від circulating supply GovernorTimelockControl(_timelock) {} // Обов'язкові override для вирішення конфліктів між extensions function votingDelay() public view override(Governor, GovernorSettings) returns (uint256) { return super.votingDelay(); } function votingPeriod() public view override(Governor, GovernorSettings) returns (uint256) { return super.votingPeriod(); } function quorum(uint256 blockNumber) public view override(Governor, GovernorVotesQuorumFraction) returns (uint256) { return super.quorum(blockNumber); } function state(uint256 proposalId) public view override(Governor, GovernorTimelockControl) returns (ProposalState) { return super.state(proposalId); } function proposalNeedsQueuing(uint256 proposalId) public view override(Governor, GovernorTimelockControl) returns (bool) { return super.proposalNeedsQueuing(proposalId); } function _queueOperations( uint256 proposalId, address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) internal override(Governor, GovernorTimelockControl) returns (uint48) { return super._queueOperations(proposalId, targets, values, calldatas, descriptionHash); } function _executeOperations( uint256 proposalId, address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) internal override(Governor, GovernorTimelockControl) { super._executeOperations(proposalId, targets, values, calldatas, descriptionHash); } function _cancel( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) internal override(Governor, GovernorTimelockControl) returns (uint256) { return super._cancel(targets, values, calldatas, descriptionHash); } function _executor() internal view override(Governor, GovernorTimelockControl) returns (address) { return super._executor(); } } 

Governance токен: ERC20Votes

Voting power береться з checkpoint-історії токена. ERC20Votes зберігає snapshot балансів на кожному блоці — це запобігає маніпуляції через купівлю токенів безпосередньо перед голосуванням.

Критично важливо: користувачі повинні зробити delegate (хоча б самому собі) щоб їх voting power враховувалася. Це часта точка плутанини — токен є, але голосувати не можна.

import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol"; contract GovernanceToken is ERC20Votes { constructor() ERC20("DAO Token", "DAO") EIP712("DAO Token", "1") { _mint(msg.sender, 10_000_000e18); } // Користувачі викликають delegate(address(self)) для активації voting power } 

TimelockController: обов'язковий елемент

Timelock — це буфер між прийнятим голосуванням та виконанням. Дає спільноті час помітити шкідливий proposal та вийти з протоколу.

// Деплой TimelockController TimelockController timelock = new TimelockController( 2 days, // minDelay: мінімум 2 дні між queue та execute proposers, // тільки Governor може ставити в чергу executors, // будь-хто може виконати (після затримки) admin // тимчасовий admin, потім передати самому timelock ); // Governor повинен бути PROPOSER_ROLE timelock.grantRole(timelock.PROPOSER_ROLE(), address(governor)); // Будь-хто може execute timelock.grantRole(timelock.EXECUTOR_ROLE(), address(0)); // Відкликаємо admin у deployer timelock.revokeRole(timelock.DEFAULT_ADMIN_ROLE(), deployer); 

Мінімальний delay для протоколів з TVL > $10M — 48 годин. Для критичних параметрів (upgrade, fee changes) — 7 днів.

Як захистити governance контракт від flash loan атак?

Flash loan атака: зловмисник бере flash loan токенів, робить proposal і голосує в одній транзакції. Захист — votingDelay > 0. Checkpoint snapshot береться на блоці створення proposal, а не голосування. ERC20Votes зберігає історію — баланс на момент snapshot блоку, а не поточний.

Proposal spam: без proposalThreshold будь-хто може спамити proposals. 100k токенів — розумний поріг для середніх протоколів. Для малих DAO — достатньо 1-5% supply.

Quorum gaming: при низькій явці достатньо невеликої кількості токенів для проходження. GovernorVotesQuorumFraction рахує quorum як % від token.getPastTotalSupply() — це правильно, quorum прив'язаний до circulating supply, а не до абсолютного числа.

Своєчасний аудит контракту економить кошти — наша перевірка виявляє до 90% потенційних векторів атак.

Параметри для різних типів DAO

Параметр Маленький DAO Середній протокол Великий протокол
Voting delay 1 день 2 дні 2 дні
Voting period 3 дні 5 днів 7 днів
Quorum 4% 4% 10%
Timelock 1 день 2 дні 7 днів
Proposal threshold 0.1% supply 0.5% supply 1% supply

Delegated voting та gasless signatures

Більшість токен-холдерів не будуть голосувати напряму — газ дорогий, процес складний. Рішення:

Delegation: holder делегує voting power іншому адресу (делегату). Делегат голосує від імені множини холдерів. Використовують Compound, Uniswap.

EIP-712 gasless vote: castVoteBySig() дозволяє підписати голос off-chain (через Snapshot або Tally) та відправити on-chain через relayer. Користувач не платить газ.

// Голосування через підпис — relayer платить gas function castVoteBySig( uint256 proposalId, uint8 support, address voter, bytes memory signature ) public returns (uint256 weight) { // EIP-712 верифікація підпису voter // ... return _castVote(proposalId, voter, support, "", ""); } 

Governance — жива система. Параметри потрібно переглядати в міру зростання DAO: quorum, що працював при 10k holders, може бути недосяжним при 500k holders з низькою явкою.

Що входить у розробку governance системи?

  • Розробка та деплой смарт-контрактів (Governor, Token, Timelock)
  • Налаштування параметрів під ваш протокол
  • Інтеграція з Snapshot/Tally (опціонально)
  • Аудит безпеки та тестування на тестнеті
  • Документація та інструкція з управління
  • Підтримка після запуску (1 місяць безкоштовно)

Документація OpenZeppelin Governor

Зв'яжіться з нами для консультації та оцінки вашого проекту. Ми гарантуємо надійну роботу контрактів у mainnet. Замовте розробку безпечної governance системи.