Разработка DAO
DAO — это смарт-контракты + социальный слой. Контракты обеспечивают исполнение решений без доверия к конкретным людям, социальный слой формирует консенсус до того, как что-то идёт on-chain. Технически построить DAO можно за неделю используя Governor Bravo или OpenZeppelin Governor. Но большинство DAO с хорошей кодовой базой умирает именно из-за governance design, а не из-за кода.
Здесь разберём оба слоя: что именно реализуется on-chain, какие паттерны работают в production, и где governance design критичнее кода.
On-chain архитектура Governor
OpenZeppelin Governor как базис
OpenZeppelin Governor (OZ 4.x+) — модульный фреймворк: core логика + interchangeable модули для voting, counting, quorum, timelock. Большинство production DAO сегодня используют его или Governor Bravo (Compound).
Минимальная конфигурация:
contract MyDAO is
Governor,
GovernorSettings, // votingDelay, votingPeriod, proposalThreshold
GovernorCountingSimple, // FOR / AGAINST / ABSTAIN
GovernorVotes, // ERC20Votes или ERC721Votes
GovernorVotesQuorumFraction, // quorum как % от total supply
GovernorTimelockControl // TimelockController интеграция
{
constructor(IVotes _token, TimelockController _timelock)
Governor("MyDAO")
GovernorSettings(7200, 50400, 1000e18) // 1 день delay, 1 неделя voting, 1000 токенов threshold
GovernorVotes(_token)
GovernorVotesQuorumFraction(4) // 4% quorum
GovernorTimelockControl(_timelock)
{}
}
ERC20Votes: snapshots голосования
ERC20Votes расширяет стандартный ERC-20, добавляя _delegate механизм и checkpoint историю. Каждый трансфер или делегирование создаёт checkpoint. При голосовании используется voting power на блоке proposalSnapshot, а не текущий баланс — это защита от покупки токенов специально для голосования.
// Пользователь должен делегировать себе (или другому) для активации voting power
token.delegate(msg.sender);
// Voting power на момент снапшота
uint256 power = token.getPastVotes(account, proposalSnapshot);
Важно: токены без делегирования не участвуют в голосовании. Это часто удивляет новых пользователей. UX должен напоминать о делегировании при первом использовании кошелька.
TimelockController: задержка исполнения
Timelock — обязательный элемент production DAO. Одобренное предложение не исполняется немедленно: оно помещается в очередь и исполняется после задержки (обычно 2-7 дней). Это окно для сообщества заметить потенциально опасное предложение и выйти из протокола до его исполнения.
TimelockController роли:
- PROPOSER — кто может ставить в очередь (обычно только Governor контракт)
-
EXECUTOR — кто может исполнять (часто
address(0)— anyone) - CANCELLER — кто может отменить (мультисиг команды как safety valve)
Минимальная задержка — параметр безопасности. 48 часов — абсолютный минимум для протокола с реальными средствами. Compound и Aave используют 2-7 дней.
Proposal lifecycle
Create proposal → votingDelay (чтобы снапшот зафиксировался) →
votingPeriod (FOR/AGAINST/ABSTAIN) →
(если прошло) queue в timelock →
timelockDelay →
execute
Proposal содержит массив вызовов: targets[], values[], calldatas[]. Один proposal может выполнить произвольное количество on-chain действий атомарно — изменить параметр протокола, перевести средства из treasury, обновить контракт.
// Proposal: изменить комиссию протокола с 0.3% до 0.5%
address[] memory targets = new address[](1);
targets[0] = address(protocolFeeManager);
uint256[] memory values = new uint256[](1);
values[0] = 0;
bytes[] memory calldatas = new bytes[](1);
calldatas[0] = abi.encodeWithSignature("setFee(uint256)", 50); // 0.5% = 50 bps
governor.propose(targets, values, calldatas, "Increase protocol fee to 0.5%");
Treasury management
DAO обычно управляет treasury — протокольными резервами. Стандартный паттерн: treasury — это сам TimelockController (он держит ETH и токены), или отдельный контракт типа Gnosis Safe с Governor как единственным owner.
Gnosis Safe + Governor интеграция
Для маленьких DAO или на раннем этапе: Gnosis Safe с мультисигом + zodiac SafeSnap модуль, который исполняет Snapshot.org голосования on-chain. Это дешевле (gasless off-chain voting) и достаточно до накопления достаточного числа активных держателей для on-chain governance.
Переход от мультисига к полному on-chain governance — отдельный milestone. Типичный путь: мультисиг (launch) → мультисиг + Snapshot (рост сообщества) → полный on-chain Governor (зрелый протокол).
Diversification и стабильность
Treasury, состоящий на 100% из native токена — высокорисковый. Медвежий рынок обрушивает runway. Production DAO диверсифицируют: 20-30% USDC/DAI для операционных нужд, остаток — нативный токен. Диверсификация производится через governance-approved proposal на DEX swap или OTC сделку.
Delegation и off-chain coordination
Delegate system
Большинство держателей не голосуют напрямую. Compound ввёл концепцию delegate: токен-холдеры делегируют voting power известным участникам (researchers, core contributors, DAO-специалисты), которые активно участвуют в governance.
Delegate profile — это Discourse/Mirror пост с позицией по ключевым вопросам. Реализуется через ERC20Votes.delegate(). Делегирование не трансферирует токены — только voting power.
Off-chain governance (Snapshot)
Snapshot.org — gasless голосование через подпись сообщения. Используется для сигнальных голосований (temperature check), не связанных с on-chain действиями. Стратегии: erc20-balance-of, erc20-votes-with-overrides, delegation и десятки кастомных.
Типичный двухступенчатый процесс:
- Temperature check на Snapshot — оценка настроений, gasless
- On-chain proposal — если температурный чек прошёл с 60%+ поддержкой
Безопасность governance
Flash loan attack на governance
Атака: flash loan → получить временный контроль над большим количеством токенов → делегировать себе → создать или протолкнуть proposal → вернуть loan. Для создания proposal: proposalThreshold должен быть достаточно высок. Для голосования: proposalSnapshot фиксируется в прошлом, flash loan не помогает (в текущем блоке нет истории делегирования).
ERC20Votes защищён от flash loan атак на голосование именно благодаря checkpoint механизму. Уязвимость — только на proposalThreshold при его низком значении.
Proposal Spam и DOS
Без порога создания предложений — протокол засыпается мусорными proposals. proposalThreshold (минимум токенов для создания proposal) — обязательный параметр. Типичные значения: 0.1% - 1% от total supply.
Governance takeover
Если злоумышленник накопил > 50% voting power (или > quorum при низкой явке) — он может провести любое proposal. Защиты:
- Высокий quorum (4-10% от supply)
- Timelock с достаточной задержкой (7 дней)
- Guardian multisig с правом CANCELLER в TimelockController
-
GovernorPreventLateQuorum— продлевает voting period если quorum набран в последний момент (предотвращает last-minute whale swing)
Upgrades через DAO
Смарт-контракты апгрейдятся через DAO proposal + timelock. Паттерны апгрейдаемости:
UUPS/Transparent Proxy + DAO owner. Governor является owner прокси. Proposal вызывает upgradeTo(newImplementation). Timelock даёт сообществу время проверить новый код до его активации.
Modular architecture без proxy. Каждый модуль заменяется через governance: proposal меняет адрес модуля в registry контракте. Менее рискованно, чем полный upgrade.
Стек и типичные сроки
Базовая on-chain DAO: OpenZeppelin Governor + TimelockController + ERC20Votes. Разработка 2-3 недели, аудит 2-3 недели.
DAO с treasury management, delegation UI, Snapshot интеграцией, Guardian мультисигом: 6-10 недель разработки.
Полная DAO платформа с кастомными модулями, veToken governance, gauge system, bribe market: 3-6 месяцев.
| Компонент | Технология | Обязательность |
|---|---|---|
| Governor | OZ Governor / Governor Bravo | Да |
| Voting token | ERC20Votes | Да |
| Timelock | TimelockController | Да, для production |
| Off-chain voting | Snapshot.org | Рекомендуется |
| Treasury | Safe multisig или Timelock | Да |
| Delegation UI | Tally / Boardroom / Custom | Рекомендуется |
| Forum | Discourse / Commonwealth | Да (социальный слой) |
Технический стек: Solidity 0.8.x + Foundry + OpenZeppelin 5.x. Frontend: wagmi + viem + React. Indexing: The Graph субграф для proposals и votes (без субграфа frontend не может показывать историю без итерации по событиям).
Стоимость рассчитывается после определения governance модели и scope.







