Розробка yield-агрегатора
Ми займаємося розробкою yield-агрегаторів вже декілька років і знаємо всі підводні камені архітектури vault та стратегій. Нижче — реальні кейси та перевірені рішення, які допоможуть уникнути втрат від bank run або MEV. Під ключ: від проектування до деплою та моніторингу.
Vault задеплоєно, стратегія працює — фармить COMP на Compound, продає через Uniswap V3, реінвестує в позицію. На шостому тижні COMP токен різко виріс у ціні, і всі holders почали виводити кошти одночасно. Стратегія тримала 80% активів у Compound, ліквідності для виведення не вистачало. Контракт почав екстрено виводити з протоколу, платячи 3-4% slippage на кожній операції. Користувачі, які виходили останніми, отримали на 6% менше. Це не баг у контракті — це архітектурний прорахунок в управлінні ліквідністю vault.
Які ризики приховує стандарт ERC-4626?
Проблема liquidity buffer та bank run
Класичний vault за ERC-4626 зберігає shares та assets у співвідношенні totalAssets / totalSupply. Якщо 90% активів розгорнуті в стратегії (що правильно з точки зору прибутковості), то при масовому виведенні контракт змушений екстрено закривати позиції. Як зазначено в стандарті ERC-4626, vault повинен управляти буфером ліквідності для запобігання bank run.
Два варіанти, які ми використовуємо залежно від профілю стратегії:
Idle buffer (10-20% активів тримаємо у vault)
Простий підхід: невеликий відсоток активів не інвестується, слугує буфером для невеликих withdrawals без взаємодії з протоколами. Yearn Finance використовує debtRatio — кожна стратегія отримує ліміт на управління активами, решта залишається у vault.
Withdrawal queue з затримкою
Для стратегій з довгими локапами (Curve gauge locks, Convex) — черга на виведення з затримкою 24-72 години. Користувач отримує «withdraw ticket» — NFT або запис у маппінгу, який можна виконати після розблокування.
Reentrancy в ERC-4626 через ERC-777 токени
ERC-4626 стандарт не забороняє використовувати ERC-777 як underlying asset. При withdraw() → _burn(shares) → external transfer → хук tokensReceived у отримувача є можливість повторно викликати deposit() або withdraw(). Якщо totalAssets оновлюється після transfer — share price маніпулюється в цей момент.
Стандартне рішення: nonReentrant на всі функції, які змінюють totalAssets або totalSupply. Додатково — перевірка totalAssets до та після операції як assertion.
Як захистити vault від MEV-атак?
Harvest timing та MEV
Функція harvest(), яка збирає rewards та реінвестує, — ласий шматок для MEV. Перед harvest() токен нагород коштує X, після продажу — X - slippage. Sandwich атакуючий ставить ордер перед harvest, отримує прибуток від руху ціни.
Рішення:
- Продаж rewards через private mempool (Flashbots Protect, MEV Blocker)
- TWAP-продаж: ділимо продаж на декілька транзакцій за декілька блоків
- Використання CoW Protocol / 1inch Fusion для batch settlement
Другий варіант простіший у реалізації, але збільшує gas overhead на 30-50%. Порівняння методів:
| Метод | Gas overhead | Захист від sandwich | Складність |
|---|---|---|---|
| Private mempool | +5-10% | Висока | Середня |
| TWAP-продаж | +30-50% | Середня | Низька |
| Batch settlement | +15-25% | Висока | Висока |
Порівняно з публічним викликом, private mempool знижує ризик sandwich на 90%. Це дозволяє заощадити близько $1500 на місяць на втратах від MEV для пулу з TVL $1M.
Як ми будуємо yield aggregator
Архітектура vault + strategy
Дотримуємося паттерну Yearn v2/v3: vault відокремлений від стратегій. Vault управляє ERC-4626 логікою, обліком shares, лімітами. Стратегії — окремі контракти з єдиним інтерфейсом:
IStrategy {
function deposit(uint256 assets) external;
function withdraw(uint256 assets) external returns (uint256 loss);
function totalAssets() external view returns (uint256);
function harvest() external returns (uint256 profit, uint256 loss);
}
Це дозволяє додавати нові стратегії без зміни vault контракту. Vault тримає список активних стратегій з debtRatio для кожної — відсоток від totalAssets, який стратегія може використовувати.
Multi-strategy allocation
Для vault з декількома стратегіями потрібен allocation механізм. Простий варіант: фіксовані debtRatio через governance. Просунутий: автоматичний rebalancer на основі APY даних.
Автоматичний rebalancer — складніший, тому що APY з протоколів не можна читати on-chain надійно. Aave повертає currentLiquidityRate в ray (1e27), Compound — supplyRatePerBlock. Потрібна нормалізація та конвертація в річний відсоток. І це тільки поточний APY — не враховує rewards токени, gas overhead на rebalance, slippage.
У більшості випадків ми реалізуємо off-chain keeper, який читає APY, обчислює оптимальний розподіл і викликає rebalance() на vault раз на 6-24 години. On-chain контракт тільки перевіряє, що виклик від авторизованого keeper.
Chainlink Automation для harvest
Замість ручного виклику harvest — Chainlink Automation (колишній Keepers). Контракт реалізує AutomationCompatibleInterface:
function checkUpkeep(bytes calldata) external view returns (bool upkeepNeeded, bytes memory);
function performUpkeep(bytes calldata performData) external;
checkUpkeep перевіряє: чи пройшло достатньо часу з останнього harvest, чи накопичилося достатньо rewards для окупності gas. Якщо обидві умови — upkeepNeeded = true, Chainlink нода викликає performUpkeep. Це прибирає залежність від ручного управління і дає гарантію регулярного harvest. Автоматизація через Chainlink Automation скорочує витрати на газ приблизно на $2000 на місяць для пулу TVL $1M.
Урахування performance fee
Performance fee — відсоток від прибутку, який йде protocol treasury. Технічно: при кожному harvest рахується profit = totalAssets_after - totalAssets_before. Від прибутку береться performanceFee (зазвичай 10-20%) і конвертується в shares, які міняться на fee recipient.
Важливий нюанс: fee потрібно мінтити в shares, а не відправляти assets. Інакше при великому обсязі fees протокол постійно вилучає ліквідність зі стратегій.
Підтримувані протоколи та стратегії
| Протокол | Тип стратегії | Складність інтеграції | Додаткові ризики |
|---|---|---|---|
| Aave V3 | Lending supply | Низька | Oracle risk |
| Compound V3 | Lending supply | Низька | Oracle risk |
| Uniswap V3 | LP (concentrated) | Висока | Impermanent loss |
| Curve + Convex | LP + gauge | Середня | Gauge lock |
| Pendle | Yield tokenization | Висока | PT/YT expiry |
| GMX | Perp liquidity | Висока | Directional risk |
Uniswap V3 LP — найскладніша стратегія через управління діапазонами. Активна стратегія (rebalance діапазонів) потребує постійного моніторингу ціни та виклику rebalance() при виході позиції з діапазону, інакше LP позиція перестає заробляти fees. Ми використовуємо Arrakis або Gamma Protocol як базовий шар для managed LP позицій замість реалізації з нуля.
Процес розробки
-
Аналітика (3-5 днів). Вибір протоколів для інтеграції, визначення стратегій, оцінка APY та ризиків. Документування інваріантів vault:
totalAssets >= totalDebt, share price монотонно зростає при прибутковій роботі. - Розробка vault core (2-3 тижні). ERC-4626 реалізація, система управління стратегіями, fee механізм, emergency pause.
- Розробка стратегій (1-2 тижні кожна). Інтеграція з кожним протоколом, harvest логіка, тестування на mainnet fork.
- Тестування (1-2 тижні). Fork-тести з симуляцією масових withdrawals, harvest сценаріїв, emergency exit. Fuzz-тести на інваріанти через Echidna.
- Деплой та моніторинг. The Graph субграф для індексації vault подій, Grafana дашборд для моніторингу TVL, APY, harvest frequency.
Що входить в роботу
- Смарт-контракти vault та всіх стратегій (ERC-4626, IStrategy)
- Fork-тести та fuzz-тести (Echidna) для інваріантів
- Субграф на The Graph для аналітики
- Повна документація: архітектура, deployment, виклики функцій
- Розгортання в mainnet/testnet
- Налаштування моніторингу (Grafana, Tenderly)
- Підтримка протягом місяця після деплою
Орієнтири за термінами
Vault з однією стратегією (Aave lending) — 3-4 тижні. Multi-strategy vault з автоматичним harvest через Chainlink — 6-8 тижнів. Повноцінний aggregator з UI, декількома стратегіями та governance — 2-3 місяці. Вартість розраховується індивідуально.
Типові помилки при розробці yield aggregator
- Відсутність буфера ліквідності -> bank run - Використання ERC-777 без nonReentrant -> reentrancy - Публічний harvest без захисту від MEV -> sandwich атаки - Ігнорування gas overhead при частому ребалансі - Неправильний розрахунок performance fee (в assets замість shares)Замовте розробку yield-агрегатора з гарантією безпеки та оптимізацією під ваш протокол. Наші інженери мають багаторічний досвід у DeFi та допоможуть уникнути типових помилок. Цікавить розробка yield-агрегатора? Зв'яжіться з нами для оцінки проекту або отримайте консультацію з архітектури DeFi-рішень.







