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

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.

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

Роутер не выполняет расчёты

Программа маршрутизации не реализует никакую логику расчёта цен. Это чистый оркестратор: он принимает маршрут, передаёт аккаунты дочерним программам и соединяет потоки токенов. Каждый хоп использует кривую своего пула:
  • AMM v4 хопы: используют формулу константного произведения (x · y = k) с гибридным ценообразованием OpenBook. См. products/amm-v4/math.
  • CPMM хопы: используют формулу константного произведения с настраиваемыми комиссионными уровнями. См. products/cpmm/math.
  • CLMM хопы: используют математику сконцентрированной ликвидности. См. algorithms/clmm-math.
  • Stable хопы: используют кривую стабильного своппа для взаимозаменяемых активов. См. products/stable/math.
Участие роутера заключается только в:
  1. Вызове инструкции swap каждого пула через CPI.
  2. Сборе выходного количества.
  3. Передаче его как входного количества для следующего хопа.
  4. Проверке финального выхода относительно лимита проскальзывания вызывающей стороны.

Накопление проскальзывания

На маршруте с несколькими хопами проскальзывание на каждом хопе накапливается. Небольшое проскальзывание на хопе 1 становится бо́льшим на хопе 2, потому что объём, поступающий на хоп 2, уже снижен. Пример:
Маршрут: USDC → SOL → STEP

Пул 1 (USDC / SOL):
  Вход: 1000 USDC
  Проскальзывание: 1% (спот дал бы 0.5 SOL, но вы получаете 0.495 SOL)
  Выход: 0.495 SOL

Пул 2 (SOL / STEP):
  Вход: 0.495 SOL (уже снижено)
  Проскальзывание: 1% (спот дал бы 495 STEP, но вы получаете 490 STEP)
  Выход: 490 STEP

Общее эффективное проскальзывание USDC → STEP: 1.99%, не 1% + 1% = 2%.
Когда вы указываете minimum_amount_out, роутер проверяет ваш финальный выход относительно этого глобального лимита. Каждый хоп также проверяет свой своп относительно своей локальной комиссионной структуры, но роутер не пересчитывает маршрут по ходу — вы должны предварительно вычислить маршрут и заложить достаточный допуск проскальзывания.

CLMM хопы и limit_prices

Для каждого хопа в пул CLMM роутер проверяет, что текущая sqrt_price_x64 пула находится в пределах указанных границ. Границы передаются как VecDeque<u128> под названием limit_prices:
  • Одна sqrt_price_x64 на каждый CLMM хоп в маршруте.
  • sqrt_price_x64 — это представление цены на основе тиков, используемое CLMM. См. algorithms/clmm-math для определения.
  • Роутер проверяет:
  sqrt_price_lower <= pool.sqrt_price_x64 <= sqrt_price_upper
для каждого CLMM хопа, отклоняя своп, если цена выходит за пределы.

Варианты инструкций и limit_prices

  • SwapBaseInWithUserAccount, SwapBaseOutWithUserAccount (Legacy, теги 0 и 1): VecDeque limit_prices обязателен. Пустая дека отклоняется с ошибкой, если какой-либо хоп является CLMM пулом. Вы должны предоставить одну цену на каждый CLMM хоп по порядку.
  • SwapBaseIn, SwapBaseOut (Current, теги 8 и 9): VecDeque limit_prices опционален. Пустая дека игнорируется молча; проверка цены не выполняется. Новый код должен использовать эти инструкции.

Построение limit_prices

Для маршрута с M CLMM хопами дека должна содержать ровно M записей. Упорядочите их по хопам:
limit_prices = [
  sqrt_price_for_first_clmm_hop,
  sqrt_price_for_second_clmm_hop,
  ...
]

Когда проверять limit_prices

sqrt_price_x64 — это снимок текущей цены пула. Она постоянно меняется по мере выполнения свопов. Вы должны:
  1. Получить текущее состояние пула из сети.
  2. Вычислить приемлемые границы (например, ±0.5% от текущей цены).
  3. Закодировать эти границы в limit_prices.
  4. Включить границы в вашу инструкцию роутера.
Если цена пула выйдет за пределы ваших границ до того, как транзакция будет обработана, роутер отклонит её.

Обработка комиссий

Каждый пул берёт свою комиссию согласно своей конфигурации:
  • AMM v4: 0.25% (фиксированная) разделена между LP, протоколом и фондом.
  • CPMM: настраиваемая для каждого AmmConfig (по умолчанию 0.25%, разделение зависит от уровня).
  • CLMM: настраиваемая для каждого пула, взимается с входного количества.
  • Stable: как AMM v4, 0.25% разделена.
Роутер не берёт собственную комиссию. Вся обработка комиссий делегируется каждому дочернему пулу. Выход из хопа N уже имеет вычтенную комиссию этого хопа. См. документацию по комиссиям отдельного пула:

Пример учёта на нескольких хопах

Предположим, вы маршрутизируете USDC → SOL → STEP через два пула константного произведения, каждый с комиссией 0.25%:
Вход: 1000 USDC
Пул 1 (USDC/SOL):
  Взятая комиссия: ceil(1000 * 0.25%) = 2.5 USDC
  Чистый вход в кривую: 997.5 USDC
  Выход кривой (без проскальзывания): 0.5 SOL
  Допуск проскальзывания: предположим 1%, получаете ~0.495 SOL

Пул 2 (SOL/STEP):
  Вход: 0.495 SOL
  Взятая комиссия: ceil(0.495 * 0.25%) ≈ 0.001 SOL
  Чистый вход в кривую: 0.494 SOL
  Выход кривой: ~494 STEP
  Допуск проскальзывания: 1%, получаете ~489 STEP

Финальный выход: ~489 STEP
Роутер проверяет:
489 >= minimum_amount_out  // указано вызывающей стороной
Если ложь, весь маршрут атомарно терпит неудачу.

Соображения точности

Как все программы Solana, роутер использует целочисленную арифметику:
  • Все количества — u64 (lamports или наименьшие единицы токенов).
  • Расчёты кривых используют u128 промежуточные значения где необходимо, чтобы избежать переполнения.
  • Соглашения об округлении зависят от дочерней программы. Роутер не переокругляет.
Если хоп выдаёт нулевое количество из-за экстремальных коэффициентов цены (например, своп 1 lamport на пуле 1B:1), роутер передаёт этот нуль следующему хопу, который может затем отклонить его как недостаточный. См. коды ошибок отдельного пула.

Что дальше