Разработка кастомных пулов на Uniswap v4
Uniswap v4 — это не очередная версия с улучшенным AMM. Это платформа для создания кастомных пулов. Ключевое изменение: архитектура hooks позволяет выполнять произвольный код до и после любой операции с пулом — инициализации, свапа, добавления/удаления ликвидности, донации. Это открывает пространство, которого не было в v2 и v3: динамические fee, on-chain order books, автоматический rebalancing, MEV-защита прямо в пуле.
Цена этой гибкости — сложность. Хук-контракт работает в контексте PoolManager через unlock callback механизм с BalanceDelta системой учёта. Ошибка в хуке может заблокировать весь пул или слить ликвидность.
Архитектура Uniswap v4: что изменилось принципиально
Singleton PoolManager и BalanceDelta
В v2/v3 каждый пул — отдельный контракт. В v4 все пулы живут внутри одного PoolManager. Это сокращает газ на создание пула с ~500k до ~150k, и делает мультихоп свапы значительно дешевле (нет transfer между контрактами).
Расчёт токенов ведётся через BalanceDelta — не реальные переводы, а дельты, которые накапливаются и рассчитываются в конце unlock callback. Пока PoolManager залочен (в рамках одного unlock), токены физически не переходят. Это открывает flash accounting: сделать свап, использовать полученные токены для чего угодно, вернуть долг — всё в одной транзакции без flash loan.
Система хуков: адрес как битовая маска
Хук-контракт регистрируется при создании пула через PoolKey. Адрес хука кодирует разрешённые callback через leading bits: определённые биты адреса должны быть установлены для активации соответствующих хуков. beforeSwap — бит 7, afterSwap — бит 6, beforeAddLiquidity — бит 5, и так далее.
Это означает, что адрес хук-контракта нельзя выбрать произвольно — нужно майнить ванити-адрес с нужными битами через CREATE2. Инструменты: v4-template от Uniswap, скрипты для mining адреса через Foundry.
Всего 14 возможных хуков:
| Хук | Описание |
|---|---|
beforeInitialize / afterInitialize |
До/после создания пула |
beforeAddLiquidity / afterAddLiquidity |
До/после добавления ликвидности |
beforeRemoveLiquidity / afterRemoveLiquidity |
До/после удаления |
beforeSwap / afterSwap |
До/после свапа |
beforeDonate / afterDonate |
До/после донации в пул |
beforeSwapReturnDelta |
Модификация вывода свапа |
afterSwapReturnDelta |
Взять комиссию после свапа |
afterAddLiquidityReturnDelta |
Изменить баланс LP |
afterRemoveLiquidityReturnDelta |
Изменить баланс при удалении |
Самые интересные кастомные механики
Динамические fee через beforeSwap
В v3 fee tier фиксирован при создании пула (0.05%, 0.3%, 1%). В v4 хук может возвращать lpFeeOverride прямо в beforeSwap, меняя комиссию для каждого свапа динамически. Это позволяет строить:
Волатильность-зависимые fee: Chainlink price feed + sliding window volatility → при высокой волатильности fee 1%, при низкой 0.05%. LP получают справедливое вознаграждение за риск impermanent loss.
TWAP-based fee: если текущая цена отклонилась от TWAP более чем на X%, увеличить fee — защита от oracle-driven арбитража, который обогащает арбитражников за счёт LP.
Limit orders через tick-based хуки
С afterSwap хук знает, что свап произошёл и цена изменилась. Если текущий tick пересёк заранее заданный уровень — можно исполнить limit order: выкупить/продать ликвидность из маппинга заявок. Это полноценный on-chain limit order book без centralized sequencer.
Сложность реализации: газ на итерацию по заявкам в хуке. При 50+ заявок на один tick свап становится дорогим. Решение — lazy execution: заявки исполняются при следующем обращении к тику, не блокируя текущий свап.
TWAMM (Time-Weighted Average Market Maker)
Крупные ордера разбиваются на маленькие виртуальные ордера, исполняемые continuous по времени. Хук накапливает токены от TWAMM-ордеров, постепенно выполняет их через пул, не создавая слиппаж. Это решает проблему whale orders — $10M свап за один блок двигает цену и создаёт sandwich возможности. TWAMM-хук размазывает его на 1000 блоков.
Математика: виртуальные ордера вычисляются через формулу экспоненциального распределения, которая позволяет пересчитать состояние для любого момента времени без пошагового обхода.
Типичные ошибки при разработке хуков
Reentrancy через PoolManager. PoolManager имеет собственный lock, но хук может вызывать внешние контракты, которые снова входят в пул. NoSuchPool, AlreadyUnlocked — частые ошибки при отладке. Правило: в хуках не делать внешних вызовов, кроме read-only запросов.
Некорректный BalanceDelta. Хук возвращает дельту токенов. Если она неправильно рассчитана — PoolManager ревертит с DeltaNotSettled. Распространённый кейс: afterSwapReturnDelta пытается забрать больше, чем есть в дельте после свапа.
Mining адреса для prodution. CREATE2 mining занимает от минут до часов в зависимости от количества нужных битов. Для 14 хуков (все активны) — нужны 14 специфических битов, это ~16 384 попыток в среднем. На GPU — быстро, на CPU с Foundry — от 10 минут до часа.
Стек и процесс разработки
Разработка ведётся на базе официального v4-template репозитория Uniswap. Foundry — единственный адекватный инструмент для тестирования v4 хуков: PoolSwapTest, PoolModifyLiquidityTest хелперы из v4-periphery, fork-тесты на состоянии mainnet/testnet.
Проектирование (2–3 дня): определение механики пула, набора хуков, BalanceDelta логики. На этом этапе — формальная спецификация инвариантов: «пул никогда не может иметь отрицательный баланс», «fee не превышает X% при любом условии».
Разработка хук-контракта (3–5 дней): имплементация callback, mining адреса, вспомогательные контракты (oracle, order book, rebalancer).
Тестирование (3–5 дней): unit-тесты каждого хука в изоляции, интеграционные тесты через PoolSwapTest, fuzz-тесты критических параметров (размер свапа, tick range, fee multiplier), fork-тесты на реальном состоянии.
Аудит и деплой (2–3 дня): Slither, ручной review с фокусом на reentrancy и BalanceDelta корректность, деплой через Foundry forge script с верификацией.
Итого: 1–2 недели для хука с одной механикой. Сложные системы (TWAMM, full order book) — 4–6 недель. Стоимость рассчитывается после описания механики и требований к throughput.







