Эта страница переведена с помощью ИИ. За эталон принимается английская версия.Открыть английскую версию →
Эта страница дополняет
products/clmm/accounts (описание аккаунтов) и products/clmm/math (описание математики). Здесь приведены авторитетные сведения об аргументах и порядке аккаунтов; конкретные байтовые раскладки берите из IDL.Список инструкций
Большинство инструкций только для admin (
CreateAmmConfig, UpdateAmmConfig, UpdatePoolStatus, CreateSupportMintAssociated, CreateOperationAccount, UpdateOperationAccount, CloseProtocolPosition) защищены захардкоженным pubkey admin программы. Инструкции admin потока вознаграждений (TransferRewardOwner, CollectRemainingRewards) защищены фандером вознаграждения, а не admin программы.
Суффикс V2 означает «поддержка Token-2022 на хранилищах/NFT, требуется слот bitmap-extension». SDK по умолчанию использует V2 для новых пулов.
CreatePool
Аргументы
Предусловия
token_mint_0 < token_mint_1по порядку байт.amm_config.disable_create_pool == false.- Минты не отклонены белым списком расширений Token-2022.
pool_state.sqrt_price_x64 = sqrt_price_x64,tick_current = floor(log_{1.0001}(price)).pool_state.liquidity = 0(позиций ещё нет).pool_state.fee_on = FromInput(устаревшее значение по умолчанию).pool_state.dynamic_fee_infoобнулён (динамическая комиссия отключена).
CreateCustomizablePool
Рекомендуется для новых пулов. Работает так же, как CreatePool, добавляя режим сбора комиссий на уровне пула и опциональное включение динамической комиссии.
Аргументы
CreatePool, плюс при enable_dynamic_fee = true:
Предусловия — те же, что у
CreatePool. Если enable_dynamic_fee = false, dynamic_fee_config игнорируется.
Постусловия
pool_state.fee_onустанавливается в выбранный вариантCollectFeeOn.- Если динамическая комиссия включена:
pool_state.dynamic_fee_infoинициализируется из переданногоDynamicFeeConfig(копируются пять калибровочных параметров; поля состояния обнуляются). - В противном случае:
pool_state.dynamic_fee_infoобнулён (динамическая комиссия навсегда неактивна для этого пула).
fee_on и бит включения динамической комиссии устанавливаются только при создании пула. Обновление на месте невозможно — пулы, созданные через устаревший CreatePool, не могут получить динамическую комиссию или одностороннюю комиссию задним числом. Для новых развёртываний следует использовать эту инструкцию.
OpenPositionV2 / OpenPositionWithToken22Nft
Создать новую позицию в существующем пуле.
Аргументы
Математика — см.
products/clmm/math. По значению base_flag программа приводит либо liquidity, либо (amount_0_max, amount_1_max) к фактическому L и фактически потреблённым суммам токенов.
Предусловия
tick_lower < tick_upper, оба кратныpool.tick_spacing, в диапазоне[MIN_TICK, MAX_TICK].- Требуемые массивы тиков переданы и инициализированы (или созданы здесь через CPI
InitTickArrayв транзакции). - У пользователя не менее
amount_0_maxиamount_1_maxв исходных ATA.
personal_positionсуществует,liquidityустановлено,fee_growth_inside_lastзафиксировано.- Записи массива тиков на
tick_lowerиtick_upperобновлены (liquidity_gross += L,liquidity_net ± L, снимки роста комиссий сохранены). pool_state.liquidity += L, если позиция в диапазоне (tick_lower ≤ tick_current < tick_upper).
InvalidTickIndex, NotApproved, ZeroAmountSpecified, TransactionTooLarge (при слишком большом количестве массивов тиков).
IncreaseLiquidityV2
Добавить ликвидность в уже открытую позицию.
Аргументы
OpenPosition, за исключением минта NFT (позиция уже существует; NFT передаётся как ATA владельца, содержащая 1 токен).
Эффект
- Переводит
amount_0_actual/amount_1_actualот пользователя в хранилища. - Увеличивает
personal_position.liquidityиpool_state.liquidity(если в диапазоне), а такжеliquidity_gross/liquidity_netграничных тиков. - Собирает комиссии и вознаграждения, накопленные с последнего обращения, и зачисляет их в
tokens_fees_owed_{0,1}/reward_amount_owed. Выплата происходит только при вызовеDecreaseLiquidityилиCollectReward, но не при увеличении позиции.
DecreaseLiquidityV2
Снять ликвидность из позиции.
Аргументы
IncreaseLiquidity.
Эффект
- Вычисляет
(amount_0, amount_1)для удалённогоLпри текущемsqrt_price_x64. - Начисляет комиссии и вознаграждения, накопленные с последнего обращения, — аналогично
IncreaseLiquidity. - Переводит
amount_0 + fees_owed_0иamount_1 + fees_owed_1из хранилищ пользователю. - Уменьшает счётчики ликвидности; если новое
personal_position.liquidity == 0, позицию можно закрыть черезClosePosition.
amount_0_min и amount_1_min — минимумы, которые пользователь принимает с учётом комиссий за перевод Token-2022 на стороне вывода.
ClosePosition
Сжечь NFT позиции и закрыть PersonalPositionState.
Предусловия
personal_position.liquidity == 0.tokens_fees_owed_{0,1} == 0.- Все счётчики вознаграждений
reward_amount_owed == 0.
- Сжигает NFT.
- Закрывает аккаунт минта NFT и аккаунт
personal_position, возвращая рентуpayer.
SwapV2
Обход кривой ликвидности; точный ввод или точный вывод в зависимости от is_base_input.
Аргументы
Вызывающий передаёт ранжированный список массивов тиков, охватывающих ожидаемый обход swap; программа использует столько, сколько нужно. SDK вычисляет этот список через
PoolUtils.computeAmountOutFormat или конечную точку котировок API.
Предусловия
pool_state.statusразрешает swap.now >= open_time.sqrt_price_limit_x64находится на корректной стороне отsqrt_price_x64для выбранного направления.
ExceededSlippage, SqrtPriceLimitOverflow, TickArrayNotFound, LiquidityInsufficient.
Что SwapV2 делает внутри и что важно знать вызывающему (релиз после 2025 года):
- Надбавка динамической комиссии — если
pool.dynamic_fee_infoненулевой, программа обновляет аккумулятор волатильности, используя расстояние по тикам, пройденное с момента последнего swap (с правилами фильтра/затухания изproducts/clmm/fees), и добавляетdynamic_fee_componentповерхAmmConfig.trade_fee_rate. Суммарная комиссия ограничена 10% (MAX_FEE_RATE_NUMERATOR / 1_000_000). - Исполнение лимитных ордеров — когда обход цены пересекает тик с открытыми лимитными ордерами, программа сначала исполняет доступную ликвидность лимитных ордеров на этом тике (FIFO по
order_phase), затем продолжает по кривой ликвидности LP. Исполненные суммы обновляютtick.unfilled_ratio_x64иtick.part_filled_orders_remainingдля последующего расчёта; сами ордера остаются незавершёнными до тех пор, пока владелец не вызоветSettleLimitOrder. - Маршрутизация комиссий на одну сторону — при
pool.fee_on = Token0OnlyилиToken1Onlyшаг swap по-прежнему вычисляет то же соотношение ввода и вывода; комиссия затем направляется на настроенную сторону. Для направлений, где настроенная сторона комиссии является выводом, комиссия вычитается из вывода swap (пользователь получаетout − fee); для направлений, где это ввод, поведение совпадает сFromInput. См.is_fee_on_input(zero_for_one)иis_fee_on_token0(zero_for_one)наPoolState.
Swap (V1) реализует те же динамическую комиссию, маршрутизацию комиссий на одну сторону и исполнение лимитных ордеров, что и SwapV2; единственная недостающая возможность — поддержка Token-2022: оба хранилища должны быть классическим SPL Token. Пулы с любым минтом Token-2022 должны использовать SwapV2 для swap-операций. Агрегатор и SDK уже предпочитают V2 для каждого плеча CLMM, поэтому вызывающим не нужно ветвиться по типу минта.
OpenLimitOrder
Разместить ордер на продажу на конкретном тике. Ордер находится в FIFO-когорте на тике и исполняется по мере прохождения цены.
Аргументы
Предусловия
tick_index % pool.tick_spacing == 0и в диапазоне[MIN_TICK, MAX_TICK].tick_indexнаходится на правильной стороне отpool.tick_currentдля выбранного направления (продажа token0 → тик должен быть выше текущего, и наоборот). Продажа на уже пройденном тике будет немедленно исполнена и отклонена.pool_state.statusразрешает операцию с лимитным ордером (бит 5).
limit_orderсуществует, зафиксированыtick.order_phaseиtick.unfilled_ratio_x64на момент открытия.tick.orders_amount += amount(в текущей когорте).limit_order_nonce.order_nonce += 1.- Эмитировано
OpenLimitOrderEvent.
InvalidLimitOrderAmount (ноль или ниже минимума пула), InvalidTickIndex (за пределами [MIN_TICK, MAX_TICK] или не на той стороне от tick_current для выбранного направления), TickAndSpacingNotMatch (tick_index % pool.tick_spacing != 0), OrderPhaseSaturated.
IncreaseLimitOrder
Увеличить существующий открытый ордер. Может вызвать только owner ордера.
Аргументы
OpenLimitOrder, без nonce-аккаунта; PDA limit_order передаётся напрямую.
Предусловия
limit_order.owner == signer.- Ордер всё ещё находится в той же когорте (
tick.order_phase == limit_order.order_phase). Если когорта уже начала исполняться, ордер частично завершён — вызывающему следует сначала вызватьDecreaseLimitOrderилиSettleLimitOrderдля продвижения вперёд.
- Переводит
amountиз ATA владельца вinput_vault. limit_order.total_amount += amount;tick.orders_amount += amount.
DecreaseLimitOrder
Уменьшить или полностью отменить открытый ордер. Возвращает владельцу неисполненный остаток плюс любой вывод, уже зачисленный предыдущими частичными исполнениями.
Аргументы
Эффект
- Пересчитывает исполненную сумму ордера по
unfilled_ratio_x64когорты с момента открытия. - Отправляет исполненный вывод на
output_token_account. - Возвращает
amountнеисполненного ввода наinput_token_account. - Соответственно обновляет
limit_order. Если новый неисполненный остаток равен нулю, программа закрывает аккаунт и возвращает рентуowner.
SettleLimitOrder
Передать исполненные выходные токены владельцу, не изменяя неисполненный остаток ордера. Полезно, когда keeper-ы с auto_withdraw хотят постепенно выплачивать долгосрочные частичные исполнения.
Вызывающий — либо owner ордера, либо limit_order_admin программы (офчейновый операционный горячий кошелёк, выполняющий автоматический keeper-цикл). У keeper-а нет других полномочий — он не может перемещать средства пользователей за пределами передачи исполненного вывода на ATA owner ордера.
Аккаунты
Эффект
- Вычисляет накопленный вывод по
(limit_order.unfilled_ratio_x64, tick.unfilled_ratio_x64). - Переводит дельту на
output_token_account. - Обновляет
limit_order.settled_output. - Не закрывает ордер; он остаётся открытым против любого оставшегося ввода.
CloseLimitOrder
Закрыть полностью исполненный аккаунт ордера. Рента всегда возвращается limit_order.owner независимо от того, кто подписывает.
Вызывающий — либо owner, либо limit_order_admin.
Предусловия
- Неисполненный остаток ордера равен нулю (либо
amount == total_amountбыло исполнено и рассчитано, либо владелец ранее уменьшил ордер до нуля и забыл закрыть).
- Закрывает
limit_order; рента отправляетсяlimit_order.owner.
CreateDynamicFeeConfig (admin)
Создать переиспользуемый набор параметров с индексом u16.
Аргументы
Частые ошибки —
InvalidDynamicFeeConfigParams, если decay_period <= filter_period или любое поле с нулевым значением выходит за допустимые пределы.
UpdateDynamicFeeConfig (admin)
Изменить существующий DynamicFeeConfig. Пулы, уже снявшие снимок конфига при создании, не обновляются задним числом; новые значения подхватят только пулы, созданные после этого изменения и ссылающиеся на данный конфиг.
Аргументы — те же пять калибровочных полей, что у CreateDynamicFeeConfig (filter_period, decay_period, reduction_factor, dynamic_fee_control, max_volatility_accumulator); index фиксируется при создании и здесь не передаётся повторно.
CollectProtocolFee / CollectFundFee
Идентичны по форме аналогичным инструкциям CPMM. Подписант должен совпадать с AmmConfig.owner / AmmConfig.fund_owner. Очищает накопленные протокольные/фондовые комиссии из хранилищ пула в адрес получателя, обнуляя соответствующие поля PoolState.protocol_fees_* / fund_fees_*.
InitializeReward
Подключить новый поток вознаграждений к пулу. Одновременно может быть активно не более 3 потоков.
Аргументы
Предусловия
- На пуле активно менее 3 потоков.
- Фандер вносит
total_emission = emissions_per_second × (end_time − open_time)токенов вознаграждения в хранилище в рамках этой инструкции. - Минт вознаграждения входит в белый список
operation_state.
SetRewardParams
Продлить, пополнить или изменить скорость эмиссии существующего потока вознаграждений. Обычно вызывается создателем пула или мультисигом Raydium. Ограничения хранятся ончейн: как правило, можно увеличить end_time или эмиссию, но нельзя уменьшить их задним числом. Проверьте список владельцев operation_state.
UpdateRewardInfos
Чисто бухгалтерская операция — начисляет reward_growth_global_x64 до текущего момента путём умножения emissions_per_second × Δt / liquidity. Вызывается внутри каждой инструкции, затрагивающей ликвидность. Доступна как самостоятельная инструкция, поскольку внешние участники (UI, кранки) иногда хотят запустить её явно.
CollectReward
Владелец позиции забирает накопленные токены вознаграждения.
Аккаунты
Эффект
- Начисляет рост вознаграждений (по той же схеме, что и комиссии).
- Переводит причитающуюся сумму на ATA получателя, обнуляет
reward_amount_owed[i].
Матрица изменения состояния
Что дальше
products/clmm/code-demos— запускаемые примеры на TypeScript.products/clmm/fees— подробности о начислении комиссий и вознаграждений.reference/error-codes— полная таблица Anchor-ошибок CLMM.
raydium-io/raydium-clmm—programs/amm/src/instructions- Raydium SDK v2 —
@raydium-io/raydium-sdk-v2

