Эта страница переведена с помощью ИИ. За эталон принимается английская версия.Открыть английскую версию →
Эта страница дополняет
products/clmm/accounts (что такое аккаунты) и products/clmm/math (что такое математика). Она является авторитетным источником для аргументов и порядка аккаунтов; конкретные макеты байтов берутся из IDL.Инвентарь инструкций
Большинство инструкций только для администратора (
CreateAmmConfig, UpdateAmmConfig, UpdatePoolStatus, CreateSupportMintAssociated, CreateOperationAccount, UpdateOperationAccount, CloseProtocolPosition) контролируются жестко закодированным публичным ключом admin программы. CreatePermissionPda / ClosePermissionPda принимают либо публичный ключ admin, либо выделенный ключ permission_pda_admin. Инструкции администратора потока вознаграждения (TransferRewardOwner, CollectRemainingRewards) контролируются финансистом вознаграждения, а не администратором программы.
Суффикс V2 означает “поддерживает Token-2022 на хранилищах/NFT, требует слота расширения битовой карты”. 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, не могут ретроактивно получить динамическую комиссию или одностороннюю комиссию. Новые развертывания должны по умолчанию использовать эту инструкцию.
CreatePermissionedPool
Как CreatePool, так и CreateCustomizablePool выводят PDA пула из ["pool", amm_config, token_mint_0, token_mint_1], поэтому существует ровно один канонический адрес пула на тройку (config, mint0, mint1) — второй init с теми же семенами не удается. CreatePermissionedPool снимает это ограничение, встраивая предоставленный клиентом seed_index: u16 в семена PDA пула, позволяя несколько пулов для одной пары и уровня комиссии — каждый по своему адресу. Поскольку произвольный адрес пула — это привилегированная возможность, плательщик должен иметь PDA Permission, который его авторизует.
Все остальное о пуле идентично CreateCustomizablePool: он принимает те же CreateCustomizableParams и поддерживает одностороннюю комиссию и опциональную динамическую комиссию.
Аргументы
CreateCustomizablePool, плюс, в начале:
PDA
pool_state выводится из ["pool", amm_config, token_mint_0, token_mint_1, seed_index.to_le_bytes()].
Предусловия
seed_index != 0.seed_indexиз0зарезервирован для устаревших пулов и отклоняется здесь; компонент семени[0, 0]— это то, что заставляет адрес устаревшего пула свернуться в классическую четырехсемейную форму.- PDA
permissionдляpayerсуществует (создан администратором черезCreatePermissionPda). - Те же правила монет/белого списка, что и
CreatePool.
- Новый
pool_stateсуществует по адресу, выведенному изseed_index, сpool_state.seed_index = seed_index. - Все остальное состояние соответствует
CreateCustomizablePool(режим комиссии, опциональная динамическая комиссия).
Эта инструкция не расширяет общий доступ к созданию пула — бесправное создание продолжается через
CreatePool / CreateCustomizablePool, которые остаются одним пулом на пару. CreatePermissionedPool существует для конкретного случая, когда оператор в белом списке нуждается в нескольких пулах для одной пары (например, различные начальные цены или когорты запуска) и имеет PDA Permission, предоставленный администратором.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).- Минт NFT позиции записывает
pool_stateкак полномочие заморозки. Полномочие минта удаляется после выпуска одного NFT. Запись полномочия заморозки не изменяет состояние аккаунта токена NFT. - Аккаунт токена NFT остается разморозенным, если инструкция не является
OpenPositionV2илиOpenPositionWithToken22Nftи полномочие заморозки хранилища совпадает со списком ограниченных издателей CLMM. Только этот соответствующий путь V2 замораживает аккаунт.OpenPositionV1 не замораживает.
InvalidTickIndex, NotApproved, ZeroAmountSpecified, TransactionTooLarge (если слишком много массивов тиков).
Замораживание позиции не добавляет объявленные аккаунты инструкций или аргументы. Клиенты могут открывать эти позиции с существующими макетами V2. Поведение выбирается на цепи из
vault_0_mint и vault_1_mint.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.
Объявленные аккаунты
Оставшиеся аккаунты
- Разморозенный NFT: ничего не требуется; дополнительный аккаунт пула безвреден, потому что обработчик его не читает.
- Замороженный NFT: добавить
personal_position.pool_idкак первый оставшийся аккаунт. Программа загружает его какPoolStateи использует его семена PDA для подписания разморозки.
personal_position.liquidity == 0.tokens_fees_owed_{0,1} == 0.- Все счетчики вознаграждений
reward_amount_owed == 0.
- Если аккаунт токена NFT заморожен, проверяет, что первый оставшийся аккаунт равен
personal_position.pool_id, затем размораживает его с помощью PDA пула. - Сжигает NFT.
- Закрывает аккаунт токена NFT и
personal_position, возвращая арендную платуnft_owner. Если NFT позиции использует Token-2022, он также закрывает минт NFT; классические минты SPL Token не могут быть закрыты и остаются с нулевым предложением.
AccountLack при закрытии замороженной позиции. Передача пула для каждого закрытия — это самая простая совместимая стратегия.
SwapV2
Пройти кривую ликвидности; точный вход или точный выход в зависимости от is_base_input.
Аргументы
Вызывающие передают ранжированный список массивов тиков, охватывающих ожидаемый проход своп; программа использует столько, сколько ей нужно. SDK вычисляет этот список через
PoolUtils.computeAmountOutFormat или конечную точку котировки API.
Предусловия
pool_state.statusпозволяет своп.now >= open_time.sqrt_price_limit_x64находится на правильной сторонеsqrt_price_x64для направления.
ExceededSlippage, SqrtPriceLimitOverflow, TickArrayNotFound, LiquidityInsufficient.
Что SwapV2 делает внутри, что вызывающие должны знать (выпуск после 2025 года):
- Надбавка за динамическую комиссию — если
pool.dynamic_fee_infoненулевой, программа обновляет накопитель волатильности, используя расстояние тика, пройденное с последнего своп (с правилами фильтра/затухания из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, шаг своп все еще вычисляет одинаковый вход-выход торговли; комиссия затем маршрутизируется на настроенную сторону. Для направлений, где настроенная сторона комиссии является выходом, комиссия вычитается из выхода своп (пользователь получает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. Агрегатор и SDK уже предпочитают V2 для каждого этапа CLMM, поэтому вызывающим не нужно ветвиться по типу минта.
OpenLimitOrder
Разместить ордер на продажу на конкретном тике. Ордер находится в когорте FIFO для каждого тика и заполняется при пересечении цены.
Аргументы
Изменение списка аккаунтов (выпуск 2026-07).
OpenLimitOrder теперь также принимает аккаунты выходной стороны — output_token_account, output_vault и output_vault_mint — в дополнение к входной стороне. Они используются только для проверки: программа отклоняет ордер, если входной или выходной аккаунт токена владельца заморожен. Это гарантирует, что заполнение может быть фактически урегулировано на выходном ATA владельца, что важно для минтов Token-2022 с белым списком/замороженных по умолчанию (например, разрешенные токены), где аккаунт может быть еще не разморожен. Клиенты, построенные на основе старого одностороннего списка аккаунтов, должны добавить три выходных аккаунта.- Ни
input_token_account, ниoutput_token_accountне заморожены (иначеNotApproved). pool_state.statusпозволяет как своп (бит 4), так и операции лимитного ордера (бит 5) (иначеNotApproved).tick_index % pool.tick_spacing == 0и в пределах[MIN_TICK, MAX_TICK].tick_indexнаходится на правильной сторонеpool.tick_currentдля выбранного направления (продажа token0 → тик должен быть выше текущего, и наоборот). Продажа на уже пересеченном тике будет немедленно сопоставлена и отклонена.
limit_orderсуществует, снимаяtick.order_phaseиtick.unfilled_ratio_x64при открытии.tick.orders_amount += amount(в текущей когорте).limit_order_nonce.order_nonce += 1.- Выпущено
OpenLimitOrderEvent.
NotApproved (входной или выходной аккаунт токена заморожен, или пул имеет отключенный своп/лимитный ордер), InvalidLimitOrderAmount (ноль или ниже минимума пула), InvalidTickIndex (вне [MIN_TICK, MAX_TICK], или на неправильной стороне tick_current для выбранного направления), TickAndSpacingNotMatch (tick_index % pool.tick_spacing != 0), OrderPhaseSaturated.
IncreaseLimitOrder
Добавить к существующему открытому ордеру. Может быть вызвана только владельцем ордера.
Аргументы
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
Отправить заполненные выходные токены владельцу без изменения неисполненного остатка ордера. Полезно, когда хранители auto_withdraw хотят капельно выплачивать долгосрочные частичные заполнения.
Вызывающий — либо владелец ордера, либо limit_order_admin программы (горячий кошелек оперативной работы, который запускает автоматизированный цикл хранителя). Хранитель не имеет других полномочий — он не может перемещать средства пользователя вне отправки заполненного выхода на ATA владельца ордера.
Аккаунты
Эффект
- Вычисляет кумулятивный выход, причитающийся, используя
(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
Идентичная форма 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, cranks) иногда хотят ее запустить.
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

