author: DominicusIn
Зачем отдельный контур управления#
Основной сайт — статический Hugo. Но инженерный контур этого репозитория
(contracts/dao/) содержит набор Solidity-контрактов, которые моделируют
минимальное, но самодостаточное DAO. Три примитива:
- GovernanceToken — ERC-20 с жёстким
MAX_SUPPLYи mint-only-by-owner; - SoulboundToken — non-transferable SBT для репутации (роль
MINTER_ROLE); - ProposalEngine — голосование с кворумом, защитой от двойного голоса, commit-reveal схемой и таймлоком.
Ниже — почему именно такие решения, а не «просто snapshot голосов».
Кворум как защита от пустого консенсуса#
ProposalEngine требует минимум 4% от общегоSupply для того, чтобы
предложение вообще могло пройти. Без кворума даже единогласное голосование
одного кита проваливается (defeats a proposal that fails quorum).
Это закрывает классическую дыру «1 токен из 1 млн решает всё»: если явка низкая, предложение не принимается, а не принимается «по умолчанию за».
Commit-reveal против фронтраннинга#
Прямое голосование («голосуй A/B прямо сейчас») токсично: видя чужие голоса в мемпуле, крупный держатель может дожимать исход под себя. Схема commit-reveal разбивает голос на две фазы:
- Commit — голосующий публикует
keccak256(choice || nonce), не раскрывая выбор. Хэш нельзя обратить, поэтому наблюдатели мемпула не знают, за что голос. - Reveal — после окончания фазы коммитов голосующий раскрывает
choiceиnonce; контракт пересчитывает хэш и сверяет с коммитом.
Плохой ревил (неверный nonce или несовпадение хэша) отклоняется
(rejects a bad reveal (front-running mitigation)). В этот момент голос не
засчитывается, а злоумышленник уже «светил» свой выбор — играть вслепую
больше нельзя.
Двойной голос заблокирован на уровне storage#
ProposalEngine ведёт per-proposal маппинг проголосовавших адресов и
откатывает повторный голос (blocks double voting by the same address).
Это дешевле, чем полагаться на off-chain агрегатор, и не зависит от того,
через какой UI шёл голос.
Таймлок перед исполнением#
Даже принятое предложение не исполняется мгновенно: enforces 2-day timelock before execution. Окно даёт сообществу время на exit или紧急ный review, если
в коде предложения нашли проблему после голосования. В реальном DAO это —
минимальная защита от «rogue proposal», прошедшего быстрый консенсус.
Soulbound-репутация#
SoulboundToken делает репутацию non-transferable: токен нельзя продать или
передать (is non-transferable (reverts on transfer)). Значит «вес» профиля
нельзя купить на вторичном рынке — только заработать через on-chain действия
под MINTER_ROLE. Это отделяет сигнал репутации от чистого баланса токенов.
Тесты как спецификация#
Весь контур покрыт hardhat test (9 passing): cap enforcement, non-transfer,
quorum, double-vote, bad reveal, timelock, defeat-on-low-quorum. Тесты здесь —
не «покрытие ради процента», а executable-спецификация поведения, которую
CI прогоняет на каждый push в contracts/**.
Что дальше#
Следующий шаг — вынести исполнение принятых предложений в отдельный
TimelockController (OpenZeppelin) вместо собственного 2-дневного окна, чтобы
исполнение шло через единый, аудированный примитив. И поднять локальный
Hardhat-node для игрового deployment без Sepolia-RPC.