Разработка системы JIT (Just-In-Time) ликвидности
JIT-ликвидность — это MEV стратегия, которую Uniswap Labs называет «добросовестным MEV» в отличие от sandwich атак. Механика: в том же блоке что и крупный своп, провайдер добавляет концентрированную ликвидность вокруг текущей цены, зарабатывает на fees с этого свопа, и в том же блоке выводит ликвидность. За одну транзакцию — три on-chain операции плюс fee за своп.
В ноябре 2022-го адрес 0x0a59... заработал $250k за один месяц исключительно на JIT. При этом другие LP в тех же пулах теряли часть своей доли комиссий. JIT-бот буквально «вставляется» перед крупным трейдом и перехватывает значительную часть fees.
Почему JIT работает: математика Uniswap v3
Концентрированная ликвидность и доля fees
В Uniswap v3 fee от свопа распределяется пропорционально ликвидности в активном tick range. Если в момент свопа JIT-позиция добавила $1M ликвидности в tick [P-0.1%, P+0.1%], а все остальные LP имеют $500k в этом range — JIT получает 1M/1.5M = 66.7% от fee этого свопа.
Стратегия выгодна при:
- Своп достаточно крупный (иначе fee не покрывает газ на 3 операции)
- Tick range достаточно узкий (больше доля, меньше impermanent loss за время удержания)
- Позиция удерживается один блок (нулевой impermanent loss риск)
Минимальный размер свопа для безубытка при 0.3% fee tier на Ethereum mainnet (газ ~30 gwei):
-
addLiquidity+removeLiquidity+collect≈ 350k gas ≈ $25 при ETH=$2000 - Нужно собрать >$25 fees → своп должен быть >$8300
На L2 (Arbitrum): тот же расчёт даёт минимальный своп ~$500. Значительно больше возможностей.
Проблема latency: блок уже минуется
JIT требует видеть своп в мемпуле до его включения в блок. Private mempool через Flashbots MEV-Share или публичный мемпул через websocket. Между обнаружением транзакции и включением своего bundle — секунды.
Оптимальная инфраструктура:
- Собственная нода с MEV-Geth или reth с mempool websocket
- Подключение к Flashbots MEV-Share для просмотра hints о pending свопах
- Bundle submission через
eth_sendBundle— атомарное включение всех трёх транзакций в один блок
Без bundle submission JIT не работает: если addLiquidity и своп попадут в разные блоки — стратегия бессмысленна и убыточна.
Архитектура JIT-системы
Off-chain компоненты
Mempool scanner: WebSocket подписка к ноде, фильтрация свопов Uniswap v3 по exactInputSingle/exactInput selector. Декодирование calldata для определения пула, размера, slippage.
Profitability calculator: для каждого кандидата считает:
- Ожидаемый fee =
swapAmount * feeTier - Долю fee =
depositAmount / (poolLiquidity + depositAmount) - Газ-стоимость bundle =
(addLiq + removeLiq + collect) * gasPrice - Net profit = (fee * доля) - газ
Если net profit > threshold ($10–50) — bundle отправляется.
Bundle builder: формирует три транзакции для Flashbots bundle:
-
tx1:mintпозиции в нужном tick range -
tx2: оригинальный своп (backrun) -
tx3:burn+collectпозиции
Smart contract для JIT-операций
Контракт обёртывает операции с ликвидностью и минимизирует газ:
function executeJIT(
address pool,
int24 tickLower,
int24 tickUpper,
uint128 liquidity,
bytes calldata swapData // оригинальный calldata свопа
) external onlyOperator {
// tx1: add liquidity
INonfungiblePositionManager(NPM).mint(MintParams({...}));
// tx2: forward swap (в bundle через Flashbots — отдельная tx)
// tx3: remove liquidity + collect
INonfungiblePositionManager(NPM).decreaseLiquidity(...);
INonfungiblePositionManager(NPM).collect(...);
}
Важно: контракт должен иметь достаточный баланс обоих токенов пула для добавления ликвидности. Управление балансами — критичный операционный аспект: при дисбалансе токенов часть ликвидности не может быть добавлена в нужном range.
Tick range selection
Узкий range максимизирует долю fee, но повышает риск: если своп двигает цену за пределы range — JIT-позиция перестаёт быть активной и не собирает fees. Для свопа без существенного price impact (< 0.5%) достаточно range ±0.3% от текущей цены. Для крупных свопов с price impact 1–2% range нужно расширить до ±2%.
Расчёт tick range по price impact:
// tickLower = log(1 - priceImpact) / log(1.0001)
// tickUpper = log(1 + priceImpact) / log(1.0001)
// Плюс буфер 20-30 ticks для надёжности
Риски и ограничения
Revert риск bundle. Если оригинальный своп ревертится (например, slippage protection трейдера), весь bundle ревертится. Газ на addLiquidity при этом теряется. Mitigation: включать только свопы с мягким slippage tolerance (>1%).
Конкуренция с другими JIT-ботами. На высоколиквидных парах (ETH/USDC, ETH/USDT) десятки ботов конкурируют за одни и те же свопы. Газовая война через priority fee может уничтожить прибыль. Более прибыльна стратегия на mid-cap парах где конкуренция ниже.
Uniswap v4 и JIT. С приходом хуков, пулы могут ввести beforeAddLiquidity хук с minimum holding time — прямой countermeasure против JIT. Ряд пулов уже тестирует такие механизмы.
Процесс и сроки
Разработка off-chain компонентов (4–5 дней): mempool scanner, profitability calculator, bundle builder с интеграцией Flashbots.
Разработка on-chain контракта (2–3 дня): JIT executor, access control, gas-оптимизация.
Инфраструктура (2–3 дня): нода (reth/geth), MEV-Share интеграция, monitoring.
Тестирование (2–3 дня): simulations на mainnet fork, back-testing исторических свопов для оценки прибыльности.
Итого: 1–2 недели. Стоимость рассчитывается после уточнения целевых пулов и сетей.







