Перейти к основному содержанию

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.

Эта страница переведена с помощью ИИ. За эталон принимается английская версия.Открыть английскую версию →

Инвариант

Маркет-мейкер с постоянным произведением (CPMM) держит два резерва x и y и обеспечивает:
x · y ≥ k       (после каждой сделки)
где k — произведение резервов до сделки. Для рынка без комиссий x · y = k точно. С комиссиями k строго растёт (доля LP от комиссии остаётся в резервах). Инвариант специально сделан геометрическим: он гарантирует, что независимо от того, насколько малым становится один резерв, другой растёт неограниченно, чтобы уравновесить его — то есть пул никогда не может быть полностью истощен с какой-либо стороны.

Ценообразование

Спот-цена

Маржинальная цена y в терминах x в любой момент — это касательная к кривой:
p = y / x
(вывод: неявное дифференцирование x · y = k даёт dy/dx = −y/x; игнорируя знак, |dy/dx| = y/x). Это цена, которую пул предлагает для бесконечно малой сделки. Для любой конечной сделки реализованная цена хуже из-за проскальзывания вдоль кривой.

Своп с точным входом (даёте Δx, получаете Δy)

С комиссиями, пусть f — ставка комиссии (например, f = 0.0025 для 25 bps). Применяем комиссию к входу, затем используем инвариант для решения выхода:
Δx_after_fee = Δx · (1 − f)
Δy           = y · Δx_after_fee / (x + Δx_after_fee)
Резервы после сделки:
x' = x + Δx
y' = y − Δy
Полная сумма Δx входит в резервы. Доля LP от комиссии остаётся в x'; доля протокола исключается из кривой через отдельный учёт (см. Варианты учёта комиссий ниже).

Своп с точным выходом (получаете Δy, платите минимальный Δx)

Δx_after_fee = x · Δy / (y − Δy)
Δx           = Δx_after_fee / (1 − f)
Δx округляется в большую сторону, чтобы пул не недозарядил.

Проскальзывание и ценовое воздействие

Ценовое воздействие измеряет, насколько спот-цена пула изменяется в результате сделки:
p_before = y / x
p_after  = y' / x' = (y − Δy) / (x + Δx)
impact   = (p_before − p_after) / p_before
Для малого Δx / x разложение в ряд первого порядка даёт:
impact ≈ 2 · Δx / x      (игнорируя комиссии)
Интуиция: своп на 1% вызывает примерно 2% ценовое воздействие. Этот коэффициент 2 — причина того, что CPMM пулы, котирующие средние сделки, выглядят «тонкими» по сравнению с рынками с биржевым стаканом — вы не просто покупаете по текущему лучшему биду, вы идёте вверх по собственной маржинальной цене. Эффективная цена, которую платит трейдер:
effective = Δx / Δy
Спрэд между p_before и effective — это проскальзывание. Проскальзывание в UI обычно выражается как (effective − p_before) / p_before; computeAmountOut SDK возвращает оба значения amountOut и priceImpact по этой причине.

Проверка инварианта в коде

После своп протоколы перепроверяют:
k' = x' · y'  ≥  k  =  x · y
Любое нарушение — это ошибка программы или переполнение при арифметических операциях. Инструкции своп Raydium делают эту проверку явной как постусловие:
let k_before = coin_reserve_before as u128 * pc_reserve_before as u128;
let k_after  = coin_reserve_after  as u128 * pc_reserve_after  as u128;
require!(k_after >= k_before, ErrorCode::InvariantViolation);

Варианты учёта комиссий

Проверка инварианта предполагает, что комиссия LP остаётся в резервах. Разные продукты Raydium по-разному обрабатывают компоненты протокола, фонда и автора:

Соглашение CPMM

Комиссии — это u64 значения, похожие на базисные пункты, с делителем 1_000_000. Торговая комиссия делится на trade_fee_rate (всего) и затем подразделяется через protocol_fee_rate, fund_fee_rate, creator_fee_rate. На каждом своп:
trade_fee     = ceil(Δx · trade_fee_rate / 1_000_000)
protocol_fee  = trade_fee · protocol_fee_rate / 1_000_000
fund_fee      = trade_fee · fund_fee_rate     / 1_000_000
creator_fee   = trade_fee · creator_fee_rate  / 1_000_000
lp_fee        = trade_fee − protocol_fee − fund_fee − creator_fee
Три доли, не относящиеся к LP, накапливаются в отдельных счётчиках (protocol_fees_*, fund_fees_*, creator_fees_*), которые исключены из резервов, используемых в инварианте. Вот как комиссии можно снять без перемещения кривой. См. products/cpmm/fees.

Соглашение AMM v4

Комиссии — это соотношения numerator / denominator с делителем 10_000. Разделение фиксировано при создании пула и сохраняется в AmmInfo.fees:
swap_fee  = ceil(Δx · swap_fee_numerator / swap_fee_denominator)    // напр. 0.25%
pnl_share = swap_fee · pnl_numerator / swap_fee_numerator            // напр. 0.03 / 0.25 = 12%
lp_share  = swap_fee − pnl_share                                     // 0.22% от объёма
pnl_share накапливается в state_data.need_take_pnl_* и исключается из резервов; lp_share остаётся в хранилище. См. products/amm-v4/fees. Оба соглашения сохраняют инвариант одинаково — различие чисто косметическое (делитель + количество подкатегорий).

Правила округления

  • Расчёт комиссии округляется в большую сторону. Гарантирует, что пул никогда не заряжает комиссию меньше.
  • Выходное количество округляется в меньшую сторону. Гарантирует, что инвариант строго выполняется (k' > k даже до добавления комиссии).
  • Входное количество для точного выхода округляется в большую сторону. Гарантирует, что пользователь не недоплачивает.
Вся арифметика использует u128 для промежуточных произведений x · Δx, чтобы избежать переполнения при больших резервах. Конечные результаты приводятся обратно к u64 с проверкой насыщения.

Граничные случаи

Пустой пул

До первого Deposit, x = y = 0. Инструкции своп отклоняют попытки до депозита.

Нулевой выход

Если Δx настолько мало, что округленный вниз Δy равен 0, инструкция прерывается с ZeroTradingTokens. Это предотвращает извлечение стоимости без платежа; также означает, что пыльные свопы на сильно несбалансированных пулах не удаются.

Пыльные LP

Первый Deposit имеет специальную обработку: он вычисляет начальное предложение LP как sqrt(x · y) и сжигает небольшое количество (обычно 100 LP-единиц), чтобы предотвратить «атаку инфляции первого депозитора» (когда злоумышленник делает пожертвование в хранилище и завышает стоимость LP-токена). Последующие депозиты используют математику пропорционального распределения.

Связь с арбитражем

Цена CPMM пула изменяется только через:
  1. Сделки через сам пул (пользователи идут по кривой).
  2. Пожертвования (отправка токенов в хранилище без своп).
Поскольку сделки детерминировано перемещают цену вдоль кривой, любой пул, цена которого отличается от цены на более широком рынке, создаёт возможность арбитража. Арбитражёры приводят цену пула обратно к рыночной цене в ожидании. Вот почему говорят, что CPMM пулы «котируют цену без оракула»: рынок находит цену через арбитраж, а не когда пул читает её снаружи. Обратная сторона: сам пул является контрагентом арбитражёра, поэтому любая прибыль от арбитража — это безвозмездный убыток LP (минус комиссия, захватываемая LP).

Практические примеры

Пример 1 — маленькая сделка, пренебрежимое проскальзывание

Пул: x = 1_000_000, y = 2_000_000, k = 2·10^12. Комиссия f = 0.0025. Сделка Δx = 1_000:
Δx_after_fee = 1000 · 0.9975  = 997.5
Δy           = 2_000_000 · 997.5 / (1_000_000 + 997.5)
             = 1_995_000_000 / 1_000_997.5
             ≈ 1_993.01
Эффективная цена: 1000 / 1993.01 ≈ 0.5018. Спот до: 0.5. Воздействие: ~0.36%.

Пример 2 — средняя сделка, заметное проскальзывание

Тот же пул, Δx = 100_000 (10% от x):
Δx_after_fee = 100_000 · 0.9975 = 99_750
Δy           = 2_000_000 · 99_750 / (1_000_000 + 99_750)
             = 199_500_000_000 / 1_099_750
             ≈ 181_405
Эффективная: 100_000 / 181_405 ≈ 0.5513. Воздействие: ~10.3% — примерно половина от правила 2 · 10% = 20% (это правило является верхним пределом для пула с постоянным произведением без комиссий; торговая комиссия плюс инверсия в формуле снижают её).

Ссылки

  • products/cpmm/math — конкретные выборы округления и делителя комиссии CPMM.
  • products/amm-v4/math — как резервы AMM v4, интегрированные с OpenBook, расширяют эту модель.
  • algorithms/slippage-and-price-impact — отдельная страница про масштабирование допуска проскальзывания для UI.
Источники:
  • Uniswap v2 whitepaper — каноническое описание x · y = k.
  • Исходный код программы Raydium CPMM.
  • Исходный код программы Raydium AMM v4.