Перейти к содержанию
Learning Platform
Продвинутый
40 минут
Uniswap V3 Concentrated Liquidity Ticks NFT Positions Uniswap V4 Hooks

Требуемые знания:

  • 03-uniswap-v2-math

Uniswap V3: Concentrated Liquidity

Зачем это блокчейну?

Uniswap V2 работает, но неэффективен: ликвидность размазана по всему ценовому диапазону от 0 до бесконечности. V3 позволяет LP выбирать конкретный ценовой диапазон — это может увеличить эффективность капитала в 4000+ раз.

Concentrated Liquidity — одна из самых значимых инноваций в DeFi. Она фундаментально изменила экономику предоставления ликвидности и стала стандартом для современных DEX.

Тики и ценовые диапазоны

Интуитивное объяснение

Представьте числовую ось с отметками (тиками). Каждый тик соответствует определенной цене. LP выбирает два тика: нижний и верхний — это его ценовой диапазон. Ликвидность активна только когда текущая цена находится внутри этого диапазона.

Uniswap V3: тики и ценовые диапазоны
$1635$2440$2000IN RANGE -- earning fees
tick_lower:74000
tick_upper:78000
price(tick_lower) = 1.0001^74000
$1635.38
price(tick_upper) = 1.0001^78000
$2439.65
Текущая цена (tick 76012)
$1999.84
Ширина диапазона
4,000 тиков
Формулаprice(i) = 1.0001^i. Каждый тик = 1 basis point (0.01%). Выход цены за диапазон превращает позицию в 100% одного токена.

Формула тика

Цена для каждого тика определяется формулой:

price(i)=1.0001iprice(i) = 1.0001^i

Каждый тик = 1 basis point = 0.01% изменения цены.

Примеры:

  • Тик 0: price = 1.0001^0 = 1.0000
  • Тик 1: price = 1.0001^1 = 1.0001 (+0.01%)
  • Тик 100: price = 1.0001^100 = 1.01005 (+1%)
  • Тик 76012: price = 1.0001^76012 ~ 2000 USDC/ETH

Обратная формула

Чтобы найти тик для заданной цены:

i=ln(price)ln(1.0001)i = \frac{\ln(price)}{\ln(1.0001)}

Tick Spacing

Не все тики доступны для создания позиций. Tick spacing зависит от комиссии пула:

Fee tierTick spacingМежду тиками
0.01%10.01%
0.05%100.1%
0.3%600.6%
1%2002%

LP может размещать ликвидность только на кратных tick spacing. Это оптимизация gas: меньше точек пересечения при свопе = дешевле.

Виртуальные vs реальные резервы

Concentrated Liquidity: реальные vs виртуальные резервы
Token XToken Yp_ap_bV2 (full range)V3 (active)
V2 (full range): Ликвидность по всей кривой [0, infinity). Виртуальные резервы = реальные резервы.
V3 (concentrated): LP размещает ликвидность только между p_a и p_b. Реальных токенов нужно значительно меньше.
Out of range: Позиция неактивна, LP не зарабатывает fees. Конвертируется в 100% одного токена.
Виртуальные резервыV3 LP предоставляет реальные токены только для выбранного диапазона. Протокол рассчитывает виртуальные резервы так, чтобы в пределах [p_a, p_b] формула xy=k работала корректно.

Ключевая идея

В V2 формула xy = k использует реальные резервы. Чтобы обеспечить ликвидность для любой цены от 0 до бесконечности, нужно огромное количество токенов.

V3 переворачивает подход: LP предоставляет реальные токены только для диапазона [p_a, p_b]. Протокол рассчитывает виртуальные резервы так, чтобы внутри этого диапазона формула xy = k работала корректно.

Математика виртуальных резервов

Для позиции в диапазоне [p_a, p_b] с ликвидностью L:

Виртуальные резервы:
x_virtual = L / sqrt(P)
y_virtual = L * sqrt(P)

Реальные токены (только для диапазона):
x_real = L * (1/sqrt(P) - 1/sqrt(p_b))
y_real = L * (sqrt(P) - sqrt(p_a))

Где P — текущая цена.

Что происходит при выходе из диапазона?

  • Цена уходит выше p_b: Позиция становится 100% Token A (дешевый токен). Все Token B проданы.
  • Цена уходит ниже p_a: Позиция становится 100% Token B (дорогой токен). Все Token A проданы.
  • В обоих случаях: LP не зарабатывает комиссии, пока цена не вернется в диапазон.

NFT позиции

V2 vs V3 LP токены

ХарактеристикаV2V3
Тип токенаERC-20ERC-721 (NFT)
ВзаимозаменяемостьДаНет
Диапазон[0, infinity)[tick_lower, tick_upper]
УправлениеNonfungiblePositionManagerNonfungiblePositionManager

Каждая V3 позиция уникальна: разный диапазон = разный NFT. Даже два LP с одинаковым диапазоном имеют разные NFT (разная ликвидность, разные earned fees).

NonfungiblePositionManager

Пользователи взаимодействуют с V3 через NonfungiblePositionManager:

  • mint() — создать позицию (выбрать диапазон, внести токены)
  • increaseLiquidity() — добавить ликвидность в существующую позицию
  • decreaseLiquidity() — убрать ликвидность
  • collect() — собрать накопленные комиссии

Капитальная эффективность

Расчет эффективности

Для диапазона [p_a, p_b] вокруг текущей цены P:

efficiency=PPpapbpbP\text{efficiency} = \frac{\sqrt{P}}{\sqrt{P} - \sqrt{p_a}} \cdot \frac{\sqrt{p_b}}{\sqrt{p_b} - \sqrt{P}}

Пример: ETH/USDC, P = $2000, диапазон [1500, 2500]:

sqrt(2000) = 44.72
sqrt(1500) = 38.73
sqrt(2500) = 50.00

efficiency_x = 44.72 / (44.72 - 38.73) = 44.72 / 5.99 = 7.47
efficiency_y = 50.00 / (50.00 - 44.72) = 50.00 / 5.28 = 9.47

Итого: ~4.24x эффективнее V2 по среднему

Трейдофф

Узкий диапазонШирокий диапазон
Больше комиссий на единицу капиталаМеньше комиссий
Выше IL внутри диапазонаНиже IL
Чаще выходит из диапазонаРедко выходит
Больше ребалансировок (gas)Меньше управления
Для профессионаловДля пассивных LP

Алгоритмический уровень: V3 своп

V3 своп сложнее V2, потому что ликвидность разная на каждом тике:

# Упрощенный V3 своп (pseudocode)
def v3_swap(amount_in, zero_for_one):
    remaining = amount_in
    total_output = 0

    while remaining > 0:
        current_tick = get_current_tick()
        liquidity = get_liquidity_at(current_tick)

        # Рассчитать, сколько можно обменять в текущем тик-диапазоне
        next_tick = get_next_initialized_tick(current_tick, zero_for_one)
        (consumed, output) = compute_swap_step(
            remaining, liquidity, current_tick, next_tick
        )

        remaining -= consumed
        total_output += output

        if consumed_reaches_next_tick:
            # Пересекаем тик: активировать/деактивировать позиции
            cross_tick(next_tick)
            # Ликвидность на следующем тике может быть другой!

    return total_output

Ключевое отличие от V2: В V2 один расчет по формуле. В V3 своп может пересечь несколько тиков, и на каждом тике ликвидность (L) может измениться.

Gas implications

Пересечение тика стоит gas (~20K-40K gas за тик). Большие свопы через много тиков — дороже. Это еще один трейдофф concentrated liquidity.

Uniswap V4: Singleton и Hooks

Uniswap V4: singleton и hooks
Singleton Pattern
V2/V3: каждый пул -- отдельный контракт (Factory + create2). V4: ВСЕ пулы живут в одном контракте PoolManager. Создание пула = запись в mapping, не деплой контракта.
V2/V3
{ } { } { }
N контрактов
->
V4
{ }
1 контракт
Hooks: 10 точек кастомизации
beforeInitialize
afterInitialize
beforeAddLiquidity
afterAddLiquidity
beforeRemoveLiquidity
afterRemoveLiquidity
beforeSwap
afterSwap
beforeDonate
afterDonate
FeatureV2V3V4
Pool deployment
Отдельный контрактОтдельный контрактSingleton PoolManager
Creation cost
~4.5M gas~4.5M gas~99.99% дешевле
Multi-hop
Промежуточные переводыПромежуточные переводыFlash accounting
Кастомизация
НетНетHooks (10 точек)
Native ETH
Требует WETHТребует WETHНативная поддержка
V4 запущен 30 января 2025Singleton + hooks + flash accounting (EIP-1153 transient storage). V2 math и V3 concentrated liquidity -- фундаментальные концепции, V4 -- эволюция архитектуры.

Singleton Pattern

V4, запущенный 30 января 2025, революционно меняет архитектуру:

  • V2/V3: Каждый пул — отдельный контракт. Factory создает через create2
  • V4: ВСЕ пулы живут в одном контракте PoolManager (singleton)
  • Создание пула = запись в mapping, не деплой контракта
  • Gas на создание: ~99.99% дешевле

Flash Accounting (EIP-1153)

Multi-hop свопы в V2/V3 требуют промежуточных переводов токенов между пулами. V4 использует transient storage (EIP-1153) для flash accounting:

V2/V3: ETH -> Pool1 -> USDC -> Pool2 -> DAI (3 transfer)
V4:    ETH -> PoolManager [internal accounting] -> DAI (1 transfer in, 1 transfer out)

Экономия gas на multi-hop: 30-50%.

Hooks

Hooks — 10 точек в lifecycle пула, где можно вставить кастомную логику:

  1. beforeInitialize / afterInitialize — создание пула
  2. beforeAddLiquidity / afterAddLiquidity — добавление ликвидности
  3. beforeRemoveLiquidity / afterRemoveLiquidity — удаление ликвидности
  4. beforeSwap / afterSwap — свопы
  5. beforeDonate / afterDonate — донаты в пул

Что можно сделать с hooks:

  • Динамические комиссии (выше при волатильности)
  • TWAP oracle (без отдельного контракта)
  • Limit orders
  • Автоматическая ребалансировка позиций
  • KYC/compliance проверки
  • MEV protection

Native ETH

V4 поддерживает нативный ETH без обертки в WETH. Это экономит ~21K gas на свопах с ETH.

Примечание: V4 в этом курсе — концептуальный материал. V2 math и V3 concentrated liquidity — фундаментальные концепции. V4 — эволюция архитектуры, а не формулы AMM.

Математический уровень

Tick math

price(i)=1.0001iprice(i) = 1.0001^i i=ln(price)ln(1.0001)i = \left\lfloor \frac{\ln(price)}{\ln(1.0001)} \right\rfloor

Ликвидность V3

L=xyL = \sqrt{x \cdot y}

Хранится как uint128. Цена хранится как P\sqrt{P} в формате Q64.96 (fixed-point с 96 битами дробной части):

PQ64.96=P296\sqrt{P}_{Q64.96} = \sqrt{P} \cdot 2^{96}

Капитальная эффективность формально

Для обеспечения той же глубины в диапазоне [p_a, p_b], V3 требует:

capitalV3=capitalV2pbpa2papb\text{capital}_{V3} = \text{capital}_{V2} \cdot \frac{p_b - p_a}{2\sqrt{p_a \cdot p_b}}

При pa=1500,pb=2500p_a = 1500, p_b = 2500:

ratio = (2500 - 1500) / (2 * sqrt(1500 * 2500))
      = 1000 / (2 * 1936.49)
      = 1000 / 3872.98
      = 0.258

V3 нужно 25.8% капитала V2 = эффективность 3.87x

Что дальше

В следующем уроке (DEFI-05) разберем Impermanent Loss — главный риск LP:

  • Формула IL = 2*sqrt(r)/(1+r) - 1
  • Пошаговый вывод формулы
  • Когда LP прибыльно (fee APR vs IL)
  • Управление позицией в V2 и V3

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс