Крупний тримач токенів, що бере участь в Uniswap, Compound, Aave та інших DAO, щоденно стикається з різними інтерфейсами Governor, різною логікою пропозицій та строками. Пропустити deadline — звичайна справа. Наш агрегатор надає єдиний дашборд, моніторинг, делегування та автоматичне виконання голосувань. Досвід команди — 5+ років, реалізовано понад 20 смарт-контрактів. Ми гарантуємо якість роботи, надаємо сертифікати аудиту та технічну підтримку. Зв'яжіться з нами — отримайте консультацію з архітектури під ваш стек.
Архітектура та адаптери
Мультимережева система управління протоколом складається з трьох шарів: Indexing layer — індексує події з Governor-контрактів через адаптери (кожен протокол має свою специфіку — Governor Bravo vs OZ Governor різняться). State layer — єдина модель даних: пропозиції нормалізовано в {id, protocol, status, deadline, description, calldata}. Action layer — on-chain або off-chain механізм виконання голосувань.
Як працюють адаптери протоколів?
Кожен Governor-сумісний контракт має дещо різний ABI. OZ Governor v4/v5 відрізняється від Compound Governor Bravo, який відрізняється від Compound Governor Alpha. Для кожного пишеться адаптер, що реалізує єдиний інтерфейс. Джерело: OpenZeppelin Governor Docs.
interface GovernorAdapter {
getProposals(fromBlock: number): Promise<Proposal[]>;
getProposalState(proposalId: bigint): Promise<ProposalState>;
castVote(proposalId: bigint, support: number): Promise<TransactionRequest>;
getVotingPower(voter: string, blockNumber: number): Promise<bigint>;
}
class OZGovernorAdapter implements GovernorAdapter {
constructor(private contract: Contract) {}
async getProposals(fromBlock: number) {
const filter = this.contract.filters.ProposalCreated();
const events = await this.contract.queryFilter(filter, fromBlock);
return events.map(e => this.normalizeProposal(e));
}
async castVote(proposalId: bigint, support: number) {
return {
to: this.contract.target,
data: this.contract.interface.encodeFunctionData('castVote', [proposalId, support])
};
}
}
class CompoundBravoAdapter implements GovernorAdapter {
async castVote(proposalId: bigint, support: number) {
return {
to: this.contract.target,
data: this.contract.interface.encodeFunctionData('castVote', [proposalId, support])
};
}
}
На момент розробки варто перевірити готові адаптери в бібліотеках wagmi/viem або субграфах The Graph.
Смарт-контракт та голосування
On-chain компонент: мультивиклик голосувань
Контракт-агрегатор дозволяє голосувати в кількох DAO однією транзакцією на основі паттерна Multicall. Код контракту мінімальний і проходить аудит.
Розгорнути приклад контракту
contract GovernanceAggregator {
struct VoteInstruction {
address governor;
uint256 proposalId;
uint8 support;
bytes reason;
}
mapping(address => mapping(address => bool)) public authorizedDelegates;
modifier onlyAuthorized(address voter) {
require(
msg.sender == voter || authorizedDelegates[voter][msg.sender],
"Not authorized"
);
_;
}
function batchVote(
address voter,
VoteInstruction[] calldata instructions
) external onlyAuthorized(voter) {
for (uint i = 0; i < instructions.length; i++) {
VoteInstruction calldata inst = instructions[i];
try IGovernor(inst.governor).castVoteWithReason(
inst.proposalId,
inst.support,
string(inst.reason)
) {
emit VoteCast(voter, inst.governor, inst.proposalId, inst.support);
} catch Error(string memory reason) {
emit VoteFailed(voter, inst.governor, inst.proposalId, reason);
}
}
}
}
Важливий нюанс: кожен Governor перевіряє msg.sender як voter. Агрегатор голосує від свого імені — це працює лише якщо voting power делегована на адресу агрегатора. Альтернативний підхід — агрегатор як smart wallet з DELEGATECALL, але це ускладнює безпеку.
Делегування та пропорційне голосування
Для ERC-20Votes токенів користувач делегує voting power на адресу агрегатора. Індексатор пропозицій відстежує нові пропозали. Проблема: якщо 60% хочуть For, а 40% — Against, агрегатор повинен голосувати пропорційно. Рішення — fractional voting: агрегатор голосує своєю вагою пропорційно до вподобань. Compound Governor Bravo підтримує castVoteWithWeightBySig, OZ Governor v5 додав GovernorCountingFractional.
Автоматизація та сповіщення
Правила автоматичного голосування
Ключова фіча — автоматичне виконання голосувань за заданими правилами. Приклад: завжди голосувати Against для treasury пропозалів > $1M. Off-chain сервіс аналізує нові пропозали, витягує параметри з calldata та застосовує правила. Якщо умови не спрацювали — голосування за замовчуванням.
interface VotingRule {
protocol: string;
proposalType: string;
conditions: Condition[];
defaultVote: 0 | 1 | 2;
requireConfirmation: boolean;
}
Парсинг calldata пропозалів
З calldata потрібно витягнути зміст. Наприклад, пропозал Compound на зміну collateral factor:
const KNOWN_SIGNATURES = {
'0x3c3e4f7a': { name: 'setCollateralFactor', protocol: 'compound' },
'0x5b85a600': { name: '_setReserveFactor', protocol: 'compound' },
};
function parseProposalCalldata(calldata: string): ProposalAction {
const selector = calldata.slice(0, 10);
const known = KNOWN_SIGNATURES[selector];
if (!known) return { type: 'unknown', selector };
const iface = new ethers.Interface([`function ${known.name}(...)`]);
const decoded = iface.decodeFunctionData(known.name, calldata);
return { type: known.name, protocol: known.protocol, params: decoded };
}
Це трудомістка робота для кожного протоколу.
Сповіщення та дедлайни
Система сповіщень: polling активних пропозалів кожні N хвилин або підписка через WebSocket (eth_subscribe logs). Сповіщення по email / Telegram / webhook при створенні пропозала, наближенні дедлайну (за 24 години), виконанні. Дедлайн розрахунок: deadlineBlock * avgBlockTime + referenceTimestamp, точність ±5 хвилин.
Розробка та впровадження
Стек розробки
Backend: Node.js + TypeScript + viem + BullMQ + PostgreSQL. Indexing: The Graph субграфи + власний listener. Frontend: React + wagmi + Radix UI. Smart contract: Solidity 0.8.x + Foundry.
Що входить в роботу
| Компонент | Опис |
|---|---|
| Аналіз протоколів | Визначення підтримуваних DAO та їх Governor-контрактів |
| Розробка адаптерів | Створення нормалізаторів для кожного протоколу |
| Смарт-контракт агрегатора | Реалізація batch vote з try/catch |
| Backend для індексації та правил | Моніторинг, парсинг, автоматичне голосування |
| Frontend дашборд | Перегляд пропозалів та керування правилами |
| Сповіщення | Telegram/Email оповіщення |
| Аудит безпеки | Перевірка контракту та backend |
| Документація | API, правила, архітектура |
Орієнтовні строки
| Функція | Строк |
|---|---|
| Базовий indexer (3–5 протоколів) | 2–3 тижні |
| On-chain batch vote контракт | 1 тиждень |
| Правила та автоматизація | 2–3 тижні |
| Frontend дашборд | 2–3 тижні |
| Сповіщення | 1 тиждень |
MVP з ручним batch voting — 4–5 тижнів. Повний агрегатор — 2–3 місяці.
Переваги та порівняння
Порівняння з ручним голосуванням
Наш агрегатор в 3 рази швидший за ручне голосування. Автоматизація в 5 разів зменшує кількість пропущених дедлайнів. Замість 5–10 хвилин на перевірку всіх активних пропозалів — 1 хвилина на дашборді. Автоматичні правила виключають людський фактор. На одному з проектів для протоколу Compound ми інтегрували агрегатор, що дозволило скоротити час моніторингу з 10 хвилин до 2 хвилин. Вартість MVP від $8,000, повне рішення від $25,000. Економія на моніторингу до 80%. Ми визначаємо точну суму після аналізу вашого проекту. Замовте консультацію — оцінимо ваш проект за 1 день.
Чому наш підхід надійніший?
Кожен контракт проходить перевірку на reentrancy, overflow, використовує формальну верифікацію з Echidna (fuzzing). Досвід команди — 5+ років у блокчейн-розробці. Агрегатор не зберігає кошти користувачів, всі транзакції підписуються авторизованим делегатом.
Кроки розробки:
- Аналіз протоколів
- Розробка адаптерів
- Розгортання смарт-контракту
- Індексація подій
- Налаштування автоматичних правил
- Тестування та аудит
Зв'яжіться з нами — ми розрахуємо вартість та строки під ваші протоколи.







