Інтеграція з 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 — реєстр версій. Це дозволяє оновлювати plugin через governance без зміни DAO core. Версія: [release, build]. Release — несумісні зміни, build — патчі.
Aragon підтримує ENS імена для 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 плагін активним = централізаційний ризик.
Розробка кастомного плагіну
Структура 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)));
// Декларуємо 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 — потужно | Простіше, але менш гнучко |
| Audited baseline | Так, core контракти | Так, OZ стандарти |
Aragon переважніший якщо: потрібна multi-plugin governance, планується еволюція механізмів з часом, важлива екосистема сумісних компонентів. OZ Governor переважніший якщо: потрібен простий та audited базовий Governor без overhead-у, команда вже знайома з OZ, нема планів на складну plugin архітектуру.
Розробка DAO на Aragon OSx з кастомним плагіном та SDK інтеграцією — 4-8 тижнів. Настройка стандартних плагінів (TokenVoting + Multisig) з frontend — 2-3 тижні.







