Розробка системи ребалансування LP-позицій
LP-провайдер на Uniswap v3 з позицією в діапазоні $1800-$2200 для пари ETH/USDC. ETH йде на $2500. Позиція повністю конвертувалась в USDC, перестала заробляти комісії. Без ребалансування вона так і лежить мертвим вантажем — комісії не крапають, а IL зафіксований. Ручний мониторинг та пересоздання позиції у потрібний момент — завдання, яке варто автоматизувати одразу, як тільки кількість позицій перевищує одну.
Коли та як ребалансувати
Триггери для ребалансування
Три основних підходи до визначення моменту ребалансування:
Price-based trigger. Ребалансування, коли ціна досягає границі діапазону або заходить у зону N% від границі. Простий, але реагує тільки на цінове событие. Підходить для більшості випадків.
Time-based trigger. Ребалансування кожні N годин незалежно від ціни. Створює передбачувані gas витрати, але часто робить непотрібну роботу.
Fee-accumulation trigger. Ребалансування, коли накопичені несобрані комісії перевищують вартість газу на ребалансування помножену на K (наприклад, K=5). Це економічно оптимальний підхід, але вимагає відслідковування tokensOwed з Uniswap v3 Position Manager.
На практиці використовуємо комбінацію: price-based як основний триггер, fee-accumulation як перевірка доцільності перед виконанням.
Стратегії вибору нового діапазону
Після виходу ціни з діапазону потрібно вибрати новий. Варіанти:
Fixed width centered on current price. Найпростіше: новий діапазон ±N% від поточної ціни. Ширина N залежить від волатильності активу: для ETH/USDC оптимально 10-20%, для стейблкоїн-пар — 0.1-0.5%.
Volatility-adjusted width. Ширина діапазону = k * ATR(period), де ATR — Average True Range за період. При високій волатильності діапазон ширший (менше ребалансувань, вищий IL-ризик), при низькій — вужче (більше ребалансувань, вищі комісії). ATR рахується off-chain по історичним цінам.
Asymmetric range. При трендовому ринку діапазон зміщується у бік тренду: [currentPrice * 0.95, currentPrice * 1.15] при восходящем тренді. Вимагає визначення тренду — наприклад, через відхилення від скользящої середньої.
Технічні проблеми ребалансування
Gas optimization при remove + add liquidity
Одна операція ребалансування у Uniswap v3 складається з:
-
collect()— збір накопичених fee -
decreaseLiquidity()— вивід ліквідності -
collect()повторно — отримання залишків токенів - Swap для відновлення потрібного ratio
-
mint()— створення нової позиції
Всього 4-5 транзакцій при окремому виконанні. Через multicall у NonfungiblePositionManager можна упакувати кілька викликів у одну транзакцію. Це знижує gas на ~40% та убирає ризик зміни стану між кроками.
Swap для відновлення ratio — окремої проблеми. Після вивід ліквідності у вас може бути 80% у токен A та 20% у токен B, а для нового діапазону потрібно 50/50. Своп змінює поділ, але рухає ціну в пулі (slippage) та дає MEV-ботам можливість для сандвіча.
Захист: minAmountOut у swap з допустимим slippage 0.3-0.5%. Або використання flash loans для атомарного ребалансування без проміжного свопу.
Мінімізація impermanent loss при ребалансуванні
Кожна ребалансування фіксує поточний IL. Якщо ціна повернеться до початкового рівня — без ребалансування IL зникає, з ребалансуванням він зафіксований. Занадто часті ребалансування при боковому ринку = накопичений IL без достатнього доходу від комісій.
Backtest стратегії на історичних даних перед деплоєм — обов'язковий крок. Для ETH/USDC на Arbitrum беремо дані з Uniswap v3 subgraph за 6-12 місяців, симулюємо різні стратегії ребалансування, порівняємо net APY після вичету gas та IL.
Keeper інфраструктура
Автоматичні триггери реалізуються через:
Chainlink Automation. Контракт реалізує інтерфейс AutomationCompatibleInterface з функцією checkUpkeep (off-chain розрахунок, потрібна ліи ребалансування) та performUpkeep (on-chain виконання). Оплата в LINK. Надійно, але є затримка до кількох блоків.
Gelato Network. Аналогічно, але з більш гнучкою логікою умов та оплатою в нативному токені. Підтримує Web3 функції як триггери (читання з контракту).
Власний keeper bot. Node.js/TypeScript сервіс з cron або event-driven логікою. Дешевше по операційних витратах, але вимагає власної інфраструктури та мониторингу uptime.
Для production — Chainlink Automation або Gelato для надійності. Власний bot як fallback та для додаткової логіки (оцінка доцільності з урахуванням gas price).
Контракт ребалансувача
interface IRebalancer {
function rebalance(
uint256 tokenId,
int24 newLowerTick,
int24 newUpperTick,
uint256 minAmount0,
uint256 minAmount1
) external returns (uint256 newTokenId);
function shouldRebalance(uint256 tokenId)
external view returns (bool, int24, int24);
}
shouldRebalance — view-функція для keeper checkUpkeep. Перевіряє поточну ціну відносно діапазону позиції та повертає нові тики якщо потрібна ребалансування.
Доступ до функції rebalance — тільки owner позиції або авторизований keeper. Жодних публічних функцій зміни позиції.
Орієнтири за часовими рамками
Базова система ребалансування для однієї позиції з Chainlink Automation — 5 робочих днів. Включає: контракт ребалансувача, off-chain стратегію вибору діапазону, keeper setup та тесті на форку mainnet.







