Интеграция с Aragon (DAO-фреймворк)
Aragon — один из старейших DAO-фреймворков (с 2017 года), прошедший через несколько архитектурных итераций. Текущая версия — Aragon OSx (Open Source, запущена в 2023) — полная переработка: модульная plugin-архитектура вместо монолитного App-фреймворка v1. Если вы рассматриваете Aragon для нового проекта — речь именно об OSx.
Архитектура Aragon OSx
DAO, PermissionManager, Plugin
Три центральных концепции:
DAO контракт — минималистичный core. Хранит treasury, имеет execute() для вызова произвольных действий. Сам по себе ничего не знает о голосовании.
PermissionManager — встроен в DAO. Управляет кто (subject) может что (permission) делать с кем (target). Вся логика доступа — через permissions, не hardcoded roles.
Plugin — смарт-контракт с конкретной функциональностью (voting, multisig, token management). Plugin устанавливается в DAO через PluginSetup + PluginSetupProcessor. При установке plugin получает нужные permissions через PermissionManager.
DAO
├── PermissionManager
│ ├── TokenVoting plugin → EXECUTE_PERMISSION on DAO
│ ├── Multisig plugin → EXECUTE_PERMISSION on DAO
│ └── AdminPlugin → ROOT_PERMISSION (для начальной настройки)
└── execute() → вызывает целевые контракты
Ключевая идея: DAO может иметь несколько governance механизмов одновременно. Например, multisig для оперативных решений с малым бюджетом + token voting для крупных решений.
Установка плагинов
Установка через PluginSetupProcessor — специальный permissioned контракт Aragon. Процесс двухфазный:
-
prepareInstallation()— deploy plugin контракта, вычисление нужных permissions (возвращаетPreparedSetupData) -
applyInstallation()— применить permissions в DAO
Почему двухфазный: permissions применяются только если сам DAO одобрил это через governance proposal. Нельзя установить plugin в DAO без одобрения его членов (если DAO уже активна).
// Данные для applyInstallation
struct ApplyInstallationParams {
PluginRepo pluginSetupRepo; // репозиторий плагина
IPluginSetup.SetupPayload setupPayload;
PermissionLib.MultiTargetPermission[] permissions; // разрешения для применения
bytes32 helpersHash;
}
PluginRepo и версионирование
Каждый plugin имеет свой PluginRepo — реестр версий. Это позволяет обновлять плагин через governance без изменения DAO core. Версия: [release, build]. Release — несовместимые изменения, build — патчи.
Aragon поддерживает ENS names для PluginRepo: token-voting.plugin.dao.eth — официальный TokenVoting плагин. Кастомные плагины деплоятся аналогично.
Официальные плагины Aragon
TokenVoting
Самый используемый плагин. Voting power = ERC20Votes баланс на snapshot. Конфигурируется при установке:
const tokenVotingSettings = {
votingMode: VotingMode.EarlyExecution, // или Standard, VoteReplacement
supportThreshold: pctToRatio(50), // 50% FOR для прохождения
minParticipation: pctToRatio(15), // 15% quorum
minDuration: 60 * 60 * 24 * 3, // минимум 3 дня
minProposerVotingPower: BigInt("1000000000000000000"), // 1 токен
}
VotingMode.EarlyExecution — proposal может быть исполнен до окончания voting period, если результат математически предрешён. Удобно для срочных изменений с явным консенсусом.
Multisig
N-of-M мультисиг как governance плагин. Proposal создаётся одним из членов, исполняется после M подписей. Полезно как emergency override или для операционных решений без ожидания полного token voting.
Интеграция двух плагинов: TokenVoting для стратегических решений + Multisig для оперативных с лимитом суммы.
Admin
Специальный плагин для начальной фазы: один адрес (founder multisig) имеет ROOT_PERMISSION. Позволяет быстро настроить DAO до передачи управления token-holder-ам. Должен быть деинсталлирован после перехода к децентрализованному governance — оставить Admin плагин активным = centralization risk.
Разработка кастомного плагина
Структура PluginSetup
Для кастомного плагина нужно два контракта: сам Plugin и его PluginSetup (factory + permissions декларация).
contract CustomVotingPlugin is Plugin {
bytes32 public constant EXECUTE_PROPOSAL_PERMISSION_ID = keccak256("EXECUTE_PROPOSAL_PERMISSION");
constructor(IDAO _dao) Plugin(_dao) {}
function executeProposal(uint256 proposalId) external auth(EXECUTE_PROPOSAL_PERMISSION_ID) {
// логика исполнения
dao().execute(
bytes32(proposalId),
actions,
allowFailureMap
);
}
}
contract CustomVotingPluginSetup is PluginSetup {
function prepareInstallation(address _dao, bytes calldata _data)
external
returns (address plugin, PreparedSetupData memory preparedSetupData)
{
// Deploy plugin
plugin = address(new CustomVotingPlugin(IDAO(_dao)));
// Declare permissions
PermissionLib.MultiTargetPermission[] memory permissions =
new PermissionLib.MultiTargetPermission[](1);
permissions[0] = PermissionLib.MultiTargetPermission({
operation: PermissionLib.Operation.Grant,
where: _dao,
who: plugin,
condition: PermissionLib.NO_CONDITION,
permissionId: DAO(payable(_dao)).EXECUTE_PERMISSION_ID()
});
preparedSetupData.permissions = permissions;
}
}
Условные permissions (Condition)
PermissionManager поддерживает условия: permission grants только при выполнении on-chain условия. Пример: плагин может вызвать execute() только для транзакций с суммой < 10 ETH.
contract ValueCondition is IPermissionCondition {
uint256 public maxValue;
function isGranted(address, address, bytes32, bytes calldata _data)
external view returns (bool)
{
(,CallstateLib.Action[] memory actions,) = abi.decode(_data, (bytes32, CallstateLib.Action[], uint256));
for (uint i = 0; i < actions.length; i++) {
if (actions[i].value > maxValue) return false;
}
return true;
}
}
Это позволяет строить сложную permission логику без изменения core контрактов.
SDK интеграция
Aragon SDK (TypeScript) существенно упрощает взаимодействие:
import { Client, TokenVotingClient, VotingMode } from "@aragon/sdk-client";
import { context } from "./context"; // Web3Provider + конфиг
const client = new Client(context);
const tokenVotingClient = new TokenVotingClient(context);
// Создание proposal
const proposalParams = {
pluginAddress: TOKEN_VOTING_PLUGIN_ADDRESS,
metadataUri: await client.methods.pinMetadata({
title: "Увеличить комиссию протокола",
summary: "Предлагаю поднять fee с 0.3% до 0.5%",
description: "Детальное обоснование...",
resources: [],
}),
actions: [
client.encoding.updateFeeAction(protocolAddress, 50),
],
executeOnPass: true,
creatorVote: Vote.YES,
};
const tx = await tokenVotingClient.methods.createProposal(proposalParams);
SDK обрабатывает IPFS pinning для metadata (metadata хранится off-chain, только URI on-chain), encoding actions, event listening.
Когда выбирать Aragon vs OpenZeppelin Governor
| Критерий | Aragon OSx | OZ Governor |
|---|---|---|
| Plugin экосистема | Богатая, готовые плагины | Минимальная |
| Кастомизация | Высокая через plugins | Высокая через модули |
| SDK/tooling | Отличный TypeScript SDK | Ограниченный |
| Сложность деплоя | Выше | Ниже |
| Учёт специфики | PermissionManager — мощно | Проще, но less flexible |
| Audited baseline | Да, core контракты | Да, OZ стандарты |
Aragon предпочтителен если: нужна multi-plugin governance, планируется эволюция механизмов со временем, важна экосистема совместимых компонентов. OZ Governor предпочтителен если: нужен simple и audited базовый Governor без overhead-а, команда уже знакома с OZ, нет планов на сложную plugin архитектуру.
Разработка DAO на Aragon OSx с кастомным плагином и SDK интеграцией — 4-8 недель. Настройка стандартных плагинов (TokenVoting + Multisig) с frontend — 2-3 недели.







