Documentation Index
Fetch the complete documentation index at: https://docs.raydium.io/llms.txt
Use this file to discover all available pages before exploring further.
Эта страница переведена с помощью ИИ. За эталон принимается английская версия.Открыть английскую версию →
Почему sqrt-price, а не price
CLMM семейства Uniswap-v3 представляют цену как её квадратный корень, хранящийся в виде фиксированной точкиQ64.64:
- Линейная математика ликвидности. Объём token0 или token1 в диапазоне цен оказывается линейной функцией
sqrt_price, а неprice. Хранениеsqrt_priceпозволяет шагу свопа вычислять эти линейные формулы без вычисления квадратного корня. - Контроль переполнения. Произведение
sqrt_price · Lумещается вu256при всех разумных параметрах;price · Lможет переполниться намного раньше. - Равномерная математика тиков. Поскольку тики определены как
1.0001^i, тоsqrt(price) = 1.00005^iтакже является точной степенью лестницы 1.00005. Каждое пересечение тика переводится в небольшое умножение в пространствеsqrt_price_x64.
price = (sqrt_price_x64 / 2^64)^2.
Решётка тиков
Цены дискретизируются на сетку:tick_i — это i32. Активный диапазон — [MIN_TICK, MAX_TICK] = [−443636, 443636], что даёт диапазон цен примерно [2^−128, 2^128]. Значение tick_spacing каждого пула устанавливается его уровнем комиссии: меньшие значения для узких пар (например, уровень 0.01% для стейблкойнов использует spacing 1), большие значения для волатильных пар (уровень 0.25% использует 60, уровень 1% использует 120).
Позиции должны иметь tick_lower и tick_upper, выравненные по tick_spacing. Активные тики пула (те, у которых начинается или заканчивается ликвидность) — единственные тики, которые интересуют шаг свопа.
Преобразование ликвидности в объёмы
Для позиции с ликвидностьюL и диапазоном цен [sqrt_lo, sqrt_hi] (все значения в sqrt_price):
| Состояние пула | Объём token0 | Объём token1 |
|---|---|---|
Цена выше диапазона (sqrt_p ≥ sqrt_hi) | 0 | L · (sqrt_hi − sqrt_lo) |
| Цена внутри диапазона | L · (sqrt_hi − sqrt_p) / (sqrt_p · sqrt_hi) | L · (sqrt_p − sqrt_lo) |
Цена ниже диапазона (sqrt_p ≤ sqrt_lo) | L · (sqrt_hi − sqrt_lo) / (sqrt_lo · sqrt_hi) | 0 |
(x_v, y_v), выбранными так, чтобы текущие (sqrt_p, L) пула были согласованы с L = sqrt(x_v · y_v). Интегрирование от sqrt_p до границы диапазона даёт указанные выше объёмы.
Обратные формулы (используются при создании позиции с заданным amount0 или amount1):
Шаг свопа внутри одного тика
Внутри одного диапазона тика пул ведёт себя как CPMM. При текущемsqrt_p и целевом sqrt_target:
Шаг с точным входом
При заданномΔin_remaining:
0→1 снижает sqrt_p (цена падает по мере продажи token0). Своп 1→0 повышает её. Формулы симметричны с перестановкой sqrt_p и sqrt_target.
Шаг с точным выходом
Та же структура, но решаем дляΔin вместо Δout.
Цикл свопа между несколькими тиками
Своп итерирует по тикам до истощения входа или достижения лимита цены:single_step использует текущий L пула. L изменяется только при пересечении инициализированного тика. Ликвидность между тиками постоянна, что позволяет получить замкнутую формулу для шага.
liquidity_net в тике — это знаковая сумма ликвидностей позиций, начинающихся в этом тике, минус те, что заканчиваются там. При пересечении вверх добавляем liquidity_net; при пересечении вниз вычитаем.
Когда в пуле открыты лимитные ордера на тике, шаг пересечения тика также оппортунистически потребляет часть входного объёма свопа для заполнения этих ордеров (FIFO по группам). Алгоритм сопоставления и динамическая комиссия, которая может быть применена поверх базового шага, документированы в products/clmm/math; они не изменяют замкнутые формулы одного шага выше.
Аккумуляторы роста комиссий
CLMM отслеживает комиссии на единицу активной ликвидности, за каждую сторону, глобально и по тикам:single_step:
fee_growth_global для другой стороны не меняется на этом шаге, так как никакой токен с той стороны не был выплачен как входной.)
При пересечении тика программа меняет fee_growth_outside:
tick_current. Когда tick_current находится выше тика, outside означает “ниже”. Когда tick_current ниже, outside означает “выше”. Смена меняет интерпретацию.
fee_growth_inside для позиции
При заданной позиции [tick_lower, tick_upper] и текущем tick_current:
s:
IncreaseLiquidity, DecreaseLiquidity, CollectFees).
Пример с расчётами — пересечение одного тика
Пул (упрощённо):sqrt_p_x64 = 2^64 · 1.0 = 2^64(цена = 1.0)L = 1_000_000tick_current = 0- Следующий инициализированный тик ниже:
tick = −60,sqrt_price = 1.0001^(−30) ≈ 0.99700,liquidity_net = −400_000(этот тик заканчивает позицию, поэтому нисходящее пересечение удаляет 400k) - Процент комиссии: 0.25%
Δin = 10_000 token0, направление = 0→1.
Шаг 1 — до sqrt_target = 0.99700 · 2^64:
L = 600_000:
Следующий инициализированный тик (скажем, tick = −120) находится на sqrt = 0.99402. Пересчитываем amount_in_to_target:
Δin_remaining. Пересекаем снова. Продолжаем до тех пор, пока Δin_remaining не достигнет нуля.
Полная последовательность Δout накапливается в финальный выход свопа.
Инициализация и охрана от переполнения
MIN_SQRT_PRICE_X64иMAX_SQRT_PRICE_X64соответствуютtick = ±443636. Любой своп, который попытается вытолкнутьsqrt_pза пределы этого диапазона, будет отменён.- Параметр
sqrt_price_limitпользователя должен находиться в том же интервале; программа проверяет это. - Произведения
L · Δsqrtвычисляются вu256, а затем сдвигаются обратно вu128для предотвращения переполнения.
Различия с Uniswap v3
- Oracle.
ObservationStateRaydium хранит буфер(block_timestamp, tick_cumulative, seconds_per_liquidity_cumulative)в виде кольца; немного другой формат провода, чем у Uniswap, но такая же математика TWAP. - Token-2022. CLMM Raydium поддерживает мелинты Token-2022; вариант с комиссией за передачу требует дополнительных корректировок объёмов до и после свопа. См.
algorithms/token-2022-transfer-fees. - Bitmap тиков. Raydium упаковывает bitmap инициализированных тиков в
[u64; 16]на пул для быстрогоfind_next_initialized_tick; Uniswap использует on-chain маппинг per-word. Компромисс между размером хранилища и стоимостью поиска. - Слоты вознаграждений. Raydium поддерживает 3 потока вознаграждений на пул с отдельными счётчиками
reward_growth_global_x64; такая же структура, как у аккумулятора роста комиссий.
Указатели
products/clmm/math— on-chain реализация и пример с расчётами с фактическими полями структуры CLMM.products/clmm/ticks-and-positions— решётка тиков, семантикаliquidity_net/gross, активного диапазона.products/clmm/fees— аккумулятор роста комиссий в действии.
- Whitepaper Uniswap v3 (каноническое выведение математики sqrt-price).
- Исходный код программы Raydium CLMM.


