Это вторая статья из нашего цикла «Хищники в пулах: Искусство и математика JIT-ликвидности». Здесь мы переходим от теории «кражи» к холодному расчету: как алгоритм за 200 миллисекунд решает, стоит ли входить в игру.
Если первая статья была про «что это», то эта — про «сколько это стоит». Чтобы JIT-атака не превратилась в благотворительность в пользу майнеров/валидаторов, бот должен решить уравнение с пятью неизвестными быстрее, чем блок будет сформирован.
1. Ликвидность (L): Главная переменная
В Uniswap v3 ликвидность — это не просто сумма токенов, а коэффициент L, который определяет, сколько активов переместится при изменении цены. Формула свопа (инвариант):

Для JIT-бота критически важно вычислить, какую долю от общего L в данном ценовом диапазоне (тике) он должен занять.
Формула доли комиссии (Fshare):
Fshare = Ljit / Lpool + Ljit
Где:
- Ljit — ликвидность, которую вносит бот.
- Lpool — уже существующая ликвидность пассивных LP в целевом тике.
Практическое правило: Чтобы забрать 95% комиссии, ликвидность бота должна быть в 19 раз больше текущей ликвидности пула в этом диапазоне.
2. Расчет доходности свопа (Gross Profit)
Бот видит в мемпуле транзакцию пользователя на сумму S (в токенах). Зная категорию комиссии пула (ф, например 0.05% или 0.3%), он считает общую комиссию сделки:

Ожидаемая грязная прибыль бота (Pgross):

3. Учет «Газового налога» (Operational Costs)
В отличие от пассивного LP, который платит за газ один раз при входе на месяцы, JIT-бот платит за газ дважды в одном блоке (или одну дорогую транзакцию с множеством вызовов).
Затраты на газ (Cgas):
mint(): ~150k - 200k gas.decreaseLiquidity()+collect(): ~120k - 180k gas.- Плюс приоритетная плата (Priority Fee) для Flashbots, чтобы гарантированно попасть в блок.
В основной сети Ethereum (Mainnet) при цене газа 30 gwei, общие затраты могут составлять $50–$150. В L2 (Arbitrum/Polygon) затраты копеечные ($0.10–$0.50), но там и конкуренция за микро-свопы выше.
4. Вычисление «Точки невозврата» (Break-even Point)
Атака имеет смысл только если:

Где Cslippage — это потери при выводе ликвидности (Impermanent Loss за время одного свопа), а Copportunity — стоимость капитала (например, проценты по Flash Loan).
Малоизвестная деталь: Опытные боты учитывают «Shadow Slippage». Когда бот вливает огромную ликвидность, он делает цену более «жесткой». Если своп пользователя очень большой, боту выгодно влить меньше ликвидности, чтобы цена сдвинулась сильнее, если он планирует арбитражить это движение в следующем блоке. Но для чистого JIT — чем больше ликвидности, тем лучше.
5. Практический пример расчета (Mainnet)
- Пул: ETH/USDC (0.05%)
- Своп жертвы: $500,000.
- Текущая Lpool в тике: $2,000,000.
- Бот вливает Ljit: $18,000,000.
- Итоговая комиссия: $500,000 x 0.0005 = $250.
- Доля бота: 18M / 18M + 2M = 90%.
- Доход бота: $250 x 0.9 = $225.
- Затраты на газ: $120 (при средних условиях).
- Чистая прибыль: $225 - $120 = $105 за один блок.
Кажется немного? Но топовые боты проводят по 500–1000 таких атак в день. Это $50,000 – $100,000 чистой прибыли в сутки практически без рыночного риска.
6. Технический нюанс: Выбор ширины тика
Бот никогда не ставит широкий диапазон. Чем уже диапазон (Ticks), тем выше концентрация капитала и тем выше L при той же сумме активов.
Стандарт JIT: tickLower и tickUpper с разницей в 1 минимальный шаг (например, для пула 0.05% это 10 пунктов).
Код для расчета ликвидности из суммы активов (TypeScript/Ethers):
import { LiquidityAmounts } from '@uniswap/v3-sdk';
import { JSBI } from '@uniswap/sdk-core';
function calculateJitLiquidity(amount0, amount1, currentPrice, tickLower, tickUpper) {
const sqrtRatioX96 = encodePriceSqrt(currentPrice);
const sqrtRatioAX96 = TickMath.getSqrtRatioAtTick(tickLower);
const sqrtRatioBX96 = TickMath.getSqrtRatioAtTick(tickUpper);
return LiquidityAmounts.getLiquidityForAmounts(
sqrtRatioX96,
sqrtRatioAX96,
sqrtRatioBX96,
amount0,
amount1,
false
);
}
Итог статьи
Математика JIT — это битва за эффективность. Если вы видите, что в пуле с комиссией 1% внезапно падает доходность — проверьте мемпул. Скорее всего, там орудует бот, который посчитал, что его L в 50 раз эффективнее вашего.
В следующей статье: Мы перейдем от формул к «железу» и коду. Разберем архитектуру смарт-контракта, который исполняет эти расчеты на лету, и узнаем, почему Rust вытеснил все остальные языки в этой нише.
Мастерство JIT-ликвидности: Полное руководство по MEV в Uniswap: Часть 1 из 5