Крупний тримач токенів, що бере участь в 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+ років у блокчейн-розробці. Агрегатор не зберігає кошти користувачів, всі транзакції підписуються авторизованим делегатом.
Кроки розробки:
- Аналіз протоколів
- Розробка адаптерів
- Розгортання смарт-контракту
- Індексація подій
- Налаштування автоматичних правил
- Тестування та аудит
Зв'яжіться з нами — ми розрахуємо вартість та строки під ваші протоколи.







