Розробка системи автоматичного ребалансування індексу
Крипто-індексний фонд без автоматичного ребалансування — це не індекс, це снапшот. За квартал розподіли дрейфують на 15-30% від цільових ваг через різну дохідність активів. Ручне ребалансування раз на місяць — це газ, час та відставання від цільових ваг до 40% на пику волатильності. Автоматична система повинна вирішувати три завдання одночасно: тригери ребалансування, оптимальний маршрут свопів та мінімізація втрат від проскальзування та MEV.
Механіка тригерів ребалансування
Дрейф порога проти часу
Дрейф порога — ребалансування при відхиленні ваги будь-якого активу від цільового на X%. Більш газоефективно: ребалансування відбувається тільки коли потрібно. Проблема: у високовалатильному середовищі можна ребалансуватися занадто часто (thrashing). Рішення: cooldown період — мінімальний інтервал між ребалансуваннями.
На основі часу — за розписанням (щодня, щотижня). Передбачувано, але неефективно: може переконфігурувати портфель коли дрейф мінімальний та газ витрачається без сенсу.
Комбінований тригер — ребалансування при drift > threshold AND time_since_last > cooldown. Стандарт для production систем.
Розрахунок поточних ваг на ланцюзі вимагає актуальних цін. Використовуємо Chainlink для отримання USD-вартості кожного активу в портфелі. Розрахунок: current_weight[i] = (balance[i] * price[i]) / total_aum.
Виконання на основі Keeper
On-chain контракт зберігає цільові ваги та логіку тригеру, але сам не ініціює ребалансування. Це завдання off-chain keeper — Chainlink Automation, Gelato Network, або кастомний keeper з условним виконанням.
Keeper викликає checkUpkeep() — контракт повертає (bool upkeepNeeded, bytes memory performData). Якщо upkeepNeeded = true — keeper викликає performUpkeep(performData) з даними про свопи.
Це розділення важливо: контракт не зберігає логіку вибору маршруту — це off-chain завдання. Контракт тільки верифікує що запропоновані свопи відповідають цільовим вагам з допустимим відхиленням.
Оптимізація свопів при ребалансуванні
Нетирування перед свопами
Перед виконанням свопів система розраховує нетто-зміну для кожного активу. Якщо потрібно продати ETH на 10k USDC та купити BTC на 8k USDC — не робимо два свопи через проміжний USDC. Робимо один: ETH → BTC напряму (якщо ліквідний маршрут існує) + ETH → USDC на різницю 2k.
Нетирування скорочує кількість свопів на 30-50% у типовому портфелі з 5-10 активів.
Проскальзування та розмір свопу
Крупний своп через один пул Uniswap v3 дає ціновий вплив. При ребалансуванні портфеля $1M+ своп $200k ETH → USDC в пулі з $5M ліквідністю — це ~4% ціновий вплив. Рішення:
Розділ за часом — розбити ребалансування на кілька транзакцій з інтервалом. TWAP-style виконання. Більш газозатратно, але менший ціновий вплив.
Агрегація через 1inch або Paraswap — off-chain маршрутизація знаходить оптимальний розділ між пулами. Інтеграція через 1inch AggregationRouter: swap(IAggregationExecutor executor, SwapDescription calldata desc, bytes calldata data). Дані для data генеруються off-chain через 1inch API.
Захист від MEV — крупні свопи ребалансування видні в mempool. Фронтран додає до втрат від проскальзування ще 0,5-1%. Рішення: Flashbots protected транзакції або 1inch Fusion (intent-based, без mempool).
Валідація виконання
Після свопів контракт перевіряє, що реалізовані ваги не відхилилися від цільових більш ніж на execution_tolerance (зазвичай 1-2%). Якщо відхилення вище — транзакція ревертується. Це запобігає ситуаціям коли ринкові умови змінилися між розрахунком та виконанням.
function _validateWeights(uint256[] memory actualBalances, uint256[] memory targetWeights) internal view {
for (uint i = 0; i < actualBalances.length; i++) {
uint256 actualWeight = (actualBalances[i] * prices[i] * PRECISION) / totalAUM;
uint256 diff = actualWeight > targetWeights[i]
? actualWeight - targetWeights[i]
: targetWeights[i] - actualWeight;
require(diff <= executionTolerance, "Weight drift too high");
}
}
Управління індексом та governance
Оновлення складу індексу
Додавання нового активу в індекс — це більше ніж встановлення targetWeights[newAsset] = X. Потрібно: додати канал ціни Chainlink, перевірити ліквідність активу на DEX (мінімальний поріг TVL пулів), оновити маршрутизацію. Зміни складу через timelock + governance голосування.
Пауза ребалансування та circuit breaker
У екстремальній волатильності (flash crash, depeg стейблкоїну) автоматичне ребалансування може зафіксувати втрати в гіршому момент. Адреса guardian з правом паузи — стандартна практика. Додатково: circuit breaker — якщо ціна активу впала >30% за останні 4 години, ребалансування автоматично зупиняється.
Процес розробки
Дизайн механіки (3-5 днів). Визначаємо: склад індексу, методологію ваг (equal weight, market cap weight, custom), параметри тригерів, джерела цін.
Контракти (1-2 тижні). IndexVault (ERC-4626 сумісний) + RebalanceEngine + PriceOracle адаптер. Foundry fork тести на mainnet з історичними ціновими даними.
Інтеграція keeper (3-5 днів). Налаштування Chainlink Automation, off-chain routing сервіс (Node.js + 1inch API), моніторинг виконання.
Тестування (1 тиждень). Backtest на історичних даних — симулюємо ребалансування за останні 12 місяців, розраховуємо проскальзування та газ витрати. Порівнюємо з buy-and-hold benchmark.
Оцінки за часом
Базова система для індексу з 3-5 активів з часовим ребалансуванням — 1-2 тижні. Повна система з дрейф-тригерами, keeper автоматизацією, MEV-захистом та governance — 3-4 тижні.
Вартість розраховується після обговорення складу індексу та вимог до автоматизації.







