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

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.

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

Что такое кривая привязки

Кривая привязки — это детерминированная функция цены p(s), которая связывает цену токена с объёмом, находящимся в обращении (s — количество проданного предложения). Покупатели отправляют залог контракту; контракт выпускает новые единицы токена по предельной цене, задаваемой кривой. Продавцы возвращают единицы токена и получают интегрированный возврат. Два ключевых отличия от CPMM-пула:
  • Контрагент не требуется. Контракт-издатель — это маркет-мейкер; ликвидность существует по определению.
  • Монотонная цена. Цена растёт с каждой чистой покупкой и падает с каждой чистой продажей.
Кривые привязки — стандартный механизм запуска, когда издатель не хочет предварительно наполнять AMM-пул залогом.

Универсальные формулы цены

Для любой непрерывной функции цены p(s): Спотовая цена при предложении s:
p(s) = формула кривой
Стоимость покупки предложения от s_0 до s_1 (где s_1 > s_0):
cost(s_0, s_1) = ∫_{s_0}^{s_1} p(s) ds = P(s_1) − P(s_0)
где P(s) = ∫ p(s) ds — первообразная кривой. Геометрически cost — это площадь под кривой p между s_0 и s_1. Доход от продажи предложения обратно от s_1 к s_0:
proceeds(s_1, s_0) = cost(s_0, s_1)
(Симметрия: покупка и продажа на одном и том же интервале обмениваются одинаковым залогом — за исключением комиссий.) Средняя цена для покупки:
avg = cost(s_0, s_1) / (s_1 − s_0)

Распространённые типы кривых

Линейная

p(s) = a + b · s
P(s)            = a·s + (b/2)·s²
cost(s_0, s_1)  = a·(s_1 − s_0) + (b/2)·(s_1² − s_0²)
Цена растёт пропорционально предложению. Используется для «плавных» запусков, когда издатель хочет предсказуемую, умеренную наценку в течение жизни проекта.

Квадратичная

p(s) = k · s²                      // или k · (s / S_max)² для нормализованной формы
P(s)            = (k / 3) · s³
cost(s_0, s_1)  = (k / 3) · (s_1³ − s_0³)
Цена растёт квадратично. Ранние покупатели получают почти нулевую цену (плоская начальная область); поздние покупатели платят крутую премию. Это тип кривой, который LaunchLab использует по умолчанию (curve_type = 0).

Virtual-reserves CPMM (стиль Pump)

Кривая — это стандартный CPMM с воображаемым начальным резервом quote V_q:
effective_y = V_q + collateral_received
effective_x = S_max − s
(effective_x) · (effective_y) = V_q · S_max      // инвариант
Спотовая цена:
p(s) = effective_y / effective_x
     = V_q · S_max / (S_max − s)² · ... (выводится через неявное дифференцирование)
Стоимость перемещения от s_0 к s_1:
cost(s_0, s_1) = V_q · S_max / (S_max − s_1) − V_q · S_max / (S_max − s_0)
              = V_q · (s_1 − s_0) · S_max / ((S_max − s_0) · (S_max − s_1))
Этот вариант обладает элегантным свойством: при выпуске (где s = S_graduate), предельная цена равна цене открытия нижестоящего CPMM-пула, заполненного резервами (S_max − S_graduate, V_q + cost(0, S_graduate)). Передача неразрывна. LaunchLab предоставляет это как curve_type = 1.

Дискретная реализация

На цепи s и cost — оба целые числа (единицы минимального номинала). Непрерывный интеграл cost(s_0, s_1) вычисляется прямо из закрытой формы, когда она существует (линейная, квадратичная). Для кривых без закрытой обратной формы (квадратичная, при известной cost найти s_1) используется итерация Ньютона:
# Решить квадратичное уравнение: (k/3)·s_1³ = (k/3)·s_0³ + cost
# Инициализировать с s_guess ≈ cbrt(3·cost/k + s_0³)
for i in 0..MAX_ITER:
    f    = (k/3)·s_guess³ − (k/3)·s_0³ − cost
    f'   = k·s_guess²
    step = f / f'
    s_guess -= step
    if |step| < precision_floor: break
LaunchLab ограничивает итерации примерно 10 и откатывает с ошибкой NotConverged, если остаток всё ещё выше допуска. На практике это срабатывает только на краях области; обычные свопы сходятся за 2–3 итерации.

Интеграция комиссий

Комиссии применяются поверх стоимости кривой, не внутри неё. При покупке:
cost_curve  = cost(base_sold, base_sold + base_out)
fee         = ceil(cost_curve · buy_numerator / buy_denominator)
quote_in    = cost_curve + fee
При продаже:
proceeds_curve = cost(base_sold − base_in, base_sold)
fee            = ceil(proceeds_curve · sell_numerator / sell_denominator)
quote_out      = proceeds_curve − fee
LP-часть комиссии остаётся в quote_vault и фактически делает кривую более крутой для будущих покупателей — резерв растёт без выпуска дополнительного предложения. Части протокола и создателя отслеживаются в отдельных счётчиках для последующего снятия.

Порог выпуска

Кривая «выпускается», когда она получила достаточно залога для запуска внешнего AMM-пула по цене, соответствующей текущей цене кривой. Для квадратичной кривой с параметрами (k, S_max, S_graduate):
quote_to_graduate = cost(0, S_graduate) · (1 + buy_fee_rate)
                  = (k / 3) · S_graduate³ · (1 + f_buy)
Как только quote_vault ≥ quote_to_graduate, инструкция Graduate создаёт CPMM-пул с:
cpmm_base_reserve  = S_max − S_graduate        // непроданное предложение кривой
cpmm_quote_reserve = quote_vault − accrued_fee_counters
cpmm_initial_price = cpmm_quote_reserve / cpmm_base_reserve
Для кривой virtual-reserves по конструкции:
cpmm_initial_price == p(S_graduate)           // точное равенство
Для квадратичной кривой равенство приблизительно; «люфт» поглощается округлением S_graduate (обычно 0.8 · S_max) и избыточным залогом от финальной покупки, пересекающей порог.

Непостоянство против CPMM-пула

Чистый запуск с кривой привязки имеет нулевое непостоянство в смысле Uniswap: нет «другой стороны» рынка для переуравновешивания. Кривая выпускает предложение по требованию, и единственный «LP» — это сам контракт. После выпуска полученный CPMM-пул ведёт себя как любой другой CPMM-пул — если LP не был сожжён, он подвержен обычной динамике непостоянных потерь. Вот почему сжигание после выпуска — доминирующая политика в публичных запусках: оно делает пул постоянным и устраняет ценовые шоки, вызванные выводом LP.

Выполненный пример

Кривая: квадратичная, k = 40, S_max = 1e9, S_graduate = 0.8 · S_max = 8e8. Комиссия на покупку 1%.

Цена при s = 5e8

p(5e8) = 40 · (5e8 / 1e9)² = 40 · 0.25 = 10
10 единиц quote на одну единицу base.

Стоимость первой покупки 1e6 base

cost(0, 1e6) = (40/3) · (1e6)³
             = (40/3) · 1e18
             ≈ 1.333e19     (наименьшие единицы quote)
С комиссией 1%:
quote_in = 1.333e19 · 1.01 ≈ 1.347e19

Порог выпуска

cost(0, 8e8) = (40/3) · (8e8)³
             = (40/3) · 5.12e26
             ≈ 6.827e27
quote_to_graduate ≈ 6.827e27 · 1.01 ≈ 6.895e27

Цена при выпуске

p(8e8) = 40 · 0.64 = 25.6

Резервы CPMM после выпуска

cpmm_base  = 1e9 − 8e8 = 2e8
cpmm_quote ≈ 6.827e27  (минус вычеты счётчиков комиссий)
cpmm_price ≈ 3.41e19 на единицу base — что соответствует p(8e8) после учёта единиц измерения
(Единицы измерения: десятичные значения требуют тщательного отслеживания; пример иллюстративный.)

Ссылки

Источники:
  • Исходный код программы Raydium LaunchLab (реализация квадратичной кривой и virtual-reserves).
  • Белая книга Bancor (линейные кривые привязки, исторический контекст).
  • Публичные анализы ошибок Pump.fun (вариант virtual-reserves).