Разработка Uniswap v4 хуков (hooks)
Uniswap v3 ограничивает кастомизацию пулов: для динамических комиссий приходилось форкать пул-контракт. v4 переворачивает архитектуру — вместо тысяч отдельных пул-контрактов один singleton PoolManager и 14 callback-функций, реализуемых через хуки. Но каждый хук требует тонкого понимания flash accounting и адресной конфигурации. Мы специализируемся на таких задачах: разрабатываем production-ready хуки с полным покрытием тестами и audit-prep документацией.
Мы разработали хуки для 30+ DeFi проектов, включая динамические комиссии для крупных DEX. Наш опыт — 10+ лет в блокчейне, сертифицированные аудиторы по Solidity. Гарантируем качество кода и безопасность.
Почему адрес хука — это его конфигурация?
В v4 адрес хука — это его конфигурация. Последние 14 бит адреса кодируют, какие callback-функции реализует хук: beforeSwap, afterSwap, beforeAddLiquidity, afterAddLiquidity и другие — итого 14 флагов. PoolManager при регистрации пула читает адрес хука и знает, какие callback вызывать, без дополнительных on-chain запросов.
Следствие: нельзя просто задеплоить контракт и получить нужный адрес. Нужен mining — перебор salt в CREATE2, пока адрес не будет содержать правильные биты. Foundry позволяет это автоматизировать:
bytes32 salt = HookMiner.find(deployer, flags, creationCode, constructorArgs); При неправильных флагах PoolManager.initialize делает revert с HookAddressNotValid. Это первое, на чём спотыкаются при переходе с v3.
BeforeSwap и AfterSwap: асимметрия контроля
beforeSwap может вернуть (bytes4 selector, BeforeSwapDelta delta, uint24 lpFeeOverride). Через delta хук может изменить количество токенов, участвующих в свапе — по сути, перехватить часть потока. Через lpFeeOverride — выставить динамическую комиссию в конкретном хопе вместо статической, заданной при инициализации пула.
afterSwap получает BalanceDelta — итог свапа — и может добавить собственную логику поверх. Типичный кейс: rebate хук, который возвращает часть fee активным LP в виде токенов.
Важный нюанс: хуки работают в контексте транзакции PoolManager. Все операции с токенами идут через flash accounting — реальные ERC-20 трансферы происходят только в конце через settle/take. Если хук пытается сделать прямой transfer внутри callback — это сломает flash accounting и вызовет revert или, хуже, некорректное состояние баланса.
Reentrancy в v4: новые правила
PoolManager защищён Lock модификатором — только один lock-вызов активен одновременно. Хук, пытающийся вызвать PoolManager.swap внутри beforeSwap, получит revert. Это означает, что архитектуры, где хук должен инициировать вторичный свап (например, автоматический rebalancing), требуют отложенного исполнения — через очередь во внешнем контракте или через afterSwap с последующим отдельным вызовом.
Как хук может реализовать динамические комиссии?
Кейс из нашей практики. Мы реализовали хук, который читает TWAP из собственного аккумулятора (обновляется в afterSwap), вычисляет σ за последние N блоков, маппит σ на fee tier: низкая волатильность → 0.01%, высокая → 1%. lpFeeOverride возвращается в beforeSwap. LP автоматически получают защиту при резких движениях рынка без ручного вмешательства.
Другие типовые кейсы:
- Whitelist хук для permissioned пула: проверяет
merkleProofили ERC-721 баланс свипера вbeforeSwap/beforeAddLiquidity. - LVR mitigation через аукцион: before-swap хук реализует commit-reveal схему, где MEV-боты торгуются за право первого свапа. Выручка идёт LP.
Стек и инструменты
Разработка — Foundry с v4-template от Uniswap. Тесты — fork на Ethereum Sepolia (v4 уже задеплоен на тестнете). HookTest базовый контракт предоставляет deployFreshManagerAndRouters — не нужно настраивать mock PoolManager вручную.
Для mining адреса хука — HookMiner из v4-periphery. В CI это выглядит как шаг перед тестами: майним salt, передаём в deployment script.
Верификация корректности флагов — отдельный тест:
assertEq(uint160(address(hook)) & HookFlags.ALL_FLAGS, expectedFlags); Упавший тест сразу показывает, что адрес смайнен неправильно.
Аудит-специфика хуков
Стандартные Slither детекторы не знают про v4 callback-контракт. Пишем кастомные детекторы под конкретные паттерны:
- прямой ERC-20 transfer внутри callback (нарушение flash accounting)
- чтение
slot0напрямую вместо через PoolManager (устаревший паттерн из v3) - отсутствие проверки
msg.sender == address(poolManager)в callback-функциях
Последний пункт критичен: если хук не проверяет, кто вызывает beforeSwap, любой может вызвать его напрямую с произвольными параметрами. В зависимости от логики это может привести к манипуляции состоянием хука без реального свапа.
Сравнение Uniswap v3 и v4 с хуками
| Параметр | Uniswap v3 | Uniswap v4 с хуками |
|---|---|---|
| Архитектура пула | Отдельный контракт на каждый пул | Singleton PoolManager + |
| hooks | ||
| Кастомизация комиссии | Фиксированная при инициализации | Динамическая через |
| lpFeeOverride | ||
| Газ на создание пула | ~500k gas | ~50k gas (в 10 раз меньше) |
| Возможность whitelist | Нет (только форк) | Встроенная через |
| beforeSwap | ||
| Фреймворк для тестов | Hardhat/Foundry | Foundry + HookTest |
Что входит в работу
| Этап | Результат | Срок |
|---|---|---|
| Аналитика | Техническое задание, схема взаимодействия | 2-3 дня |
| Проектирование | Storage layout, интерфейс owner-функций | 2-3 дня |
| Разработка | Код всех callback, тесты на Sepolia, fuzz | 1-2 недели |
| Аудит | Кастомные детекторы Slither, ручной review | 1 неделя |
| Деплой | HookMiner CI, deployment script, мониторинг | 2 дня |
| Обучение команды | Документация, архитектурные рекомендации | 1 день |
Процесс работы
- Аналитика (2-3 дня). Формализуем логику хука: какие callback нужны, есть ли собственный storage, нужен ли доступ к oracle. Проверяем совместимость с существующей архитектурой пула.
- Проектирование (2-3 дня). Схема взаимодействия хука с PoolManager, определение storage layout (минимизируем SLOAD в горячих путях), интерфейс для конфигурирования хука owner-ом.
- Разработка (1-2 недели). Реализация callback-функций, тесты на fork Sepolia, fuzz-тесты на граничные значения входных параметров.
- Аудит. Кастомные Slither детекторы + ручной review всех путей, где хук меняет
BeforeSwapDelta. Документация инвариантов для внешнего аудитора. - Деплой. HookMiner в CI, deployment script через Foundry с верификацией флагов. Мониторинг через событийный лог PoolManager первые 72 часа после деплоя.
Ориентиры по срокам
Простой хук (single callback, только чтение) — 4-6 дней. Хук с динамическими комиссиями и собственным оракулом — 1-2 недели. Комплексный хук с аукционной механикой или собственной системой учёта LP-позиций — 3-4 недели. Стоимость рассчитывается после анализа технического задания.
Ознакомьтесь с официальной документацией Uniswap v4 для углублённого понимания спецификации.
Получите консультацию по вашему проекту
Закажите разработку хука — оценим задачу за 24 часа. Свяжитесь с нами для обсуждения архитектуры и сроков.







