DAO. Solidity
ДАО (англ. DAO — decentralized autonomous organization) — это децентрализованная автономная организация.
Процесс голосования, посредством которого ДАО принимает решения, называется on-chain governance, и он стал центральным компонентом децентрализованных протоколов. ДАО принимает решения, такие как настройка параметров, обновление смарт-контрактов, интеграция с другими протоколами, управление казначейством, выдача грантов и т. д.
Предложение (Propose) - это действие, которое будет исполнено от имени ДАО, если члены ДАО поддержат его.
Стадии через которые проходит предложение от создания до выполнения:
- После создания предложения оно имеет статус Pending - ожидает начала голосования.
- После прохождения времени необходимого для ознакомления с предложением, покупки токенов голосования и т.п. начинается период голосования и предложение имеет статус Active.
- После того как завершился период голосования происходит подсчет голосов. Если набралось достаточное количество голосов и кворум был достигнут, то предложение имеет состояние Succeeded. Если кворум не достигнут и предложение отклонено - Defeated.
- Далее предложение помещается в очередь на исполнение - Queued.
- Если предлжение находится слишком долго в очереди, то состояние меняется на Expired.
- Исполненное предложение имеет стату Executed.
- Также предложение может быть отменено до исполнения - Canseled.
Пример организации и взаимодействие со смарт-контрактами ДАО
Разберем пример построения ДАО с использованием библиотеки OpenZeppeline v5.0. Нам нужны несколько контрактов для организации ДАО:
TokenGiver - контракт, который будет продавать пользователю токены голосования за USDT.
ERC20Vote - Токен голосования.
Governor DAO - контракт, который отвечает за создание предожений, голосование и планирование исполнения предожений.
TimeLockController - дополнительный контракт, который выполненяет предложение, одобреное контрактом Governor.
Target Contract From Propose - тестовый контракт, за взаимодействие с которым будут голосовать пользователи в нашем тестовом предложении.
- Proposer создает предложение (состояние предложения Pending)
- User приобретает токены голосования (состояние предложения Pending или Active)
- User делегирует право голосования (себе или кому то другому) (состояние предложения Pending или Active)
- User голосует против, за, или воздержался (состояние предложения Active)
- Executer ставит предложение в очередь на исполнение (состояние предложения Succeeded)
- Executer запускает исполнение предложение от имени ДАО (состояние предложения Queued или Expired)
Создаем контракт, наследуемся от ERC20Votes. Decimals буду использовать равный 6ти, что бы было проще осуществлять обмен с USDT
Создаем контракт для продажи токенов за USDT
Приведу часть контракта собственно DAO. Наследуемся от следующих контрактов:
Governor - основной контракт, для работы с предложениями. Реализует основную логику, которую мы будем дополнять.
GovernorCountingSimple - модуль, реализующий голосование с 3мя вариантами (Против, За, Воздержался)
GovernorVotes - модуль, для расчета веса голоса в зависимости от количества токенов голосования
GovernorVotesQuorumFraction - модуль, отвечающий за кворум
GovernorTimelockControl - модуль, отвечающий за взаимодействие Governor'а и TimeLockController'а
Также приведу часть тестов написанных на Foundry:
Переменные и подготовка контрактов
Тест создающий предложение, голосующий, и исполняющий предложение
- После изменения количества токенов голосования нужно вызвать delegate()
- Для расчета времени используется block.number, а не timestamp
- Прежде чем исполнить предложение его нужно поместить в очередь на исполнение