Skip to main content
本頁內容由 AI 自動翻譯,所有內容以英文版本為準。查看英文版 →
本頁與 products/clmm/accounts(帳戶說明)及 products/clmm/math(數學原理)配套閱讀,是參數與帳戶順序的權威來源;具體位元組佈局請參閱 IDL。

指令一覽

大多數僅限管理員的指令(CreateAmmConfigUpdateAmmConfigUpdatePoolStatusCreateSupportMintAssociatedCreateOperationAccountUpdateOperationAccountCloseProtocolPosition)由程式硬編碼的 admin 公鑰控管。獎勵流管理指令(TransferRewardOwnerCollectRemainingRewards)則由獎勵資助方控管,而非程式管理員。 V2 後綴表示「支援保險庫/NFT 的 Token-2022,需要 bitmap-extension slot」。SDK 預設對新池使用 V2。

CreatePool

參數
帳戶(簡略) 前置條件
  • token_mint_0 < token_mint_1(依位元組順序排列)。
  • amm_config.disable_create_pool == false
  • Mint 未被 Token-2022 擴充允許清單拒絕。
後置條件
  • pool_state.sqrt_price_x64 = sqrt_price_x64tick_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] 範圍內。
  • 所需 tick array 已傳入並初始化(或在此交易中透過 InitTickArray CPI 建立)。
  • 使用者來源 ATA 中至少持有 amount_0_maxamount_1_max
後置條件
  • personal_position 已存在,liquidity 已設定,fee_growth_inside_last 已快照。
  • tick_lowertick_upper 的 tick-array 條目已更新(liquidity_gross += Lliquidity_net ± L、費用增長快照維護)。
  • 若倉位在範圍內(tick_lower ≤ tick_current < tick_upper),則 pool_state.liquidity += L
常見錯誤InvalidTickIndexNotApprovedZeroAmountSpecifiedTransactionTooLarge(tick array 過多時)。

IncreaseLiquidityV2

向已開啟的倉位增加流動性。 參數
帳戶 — 與 OpenPosition 類似,但不需要 NFT mint(倉位已存在;NFT 以擁有者持有 1 個代幣的 ATA 形式傳入)。 效果
  • amount_0_actual / amount_1_actual 從使用者轉入保險庫。
  • 遞增 personal_position.liquiditypool_state.liquidity(若在範圍內),並相應調整端點 tick 的 liquidity_gross / liquidity_net
  • 收取自上次觸碰以來應付的手續費和獎勵,並記入 tokens_fees_owed_{0,1} / reward_amount_owed。這些金額僅在 DecreaseLiquidityCollectReward 時支付,增加流動性時不會直接付出。

DecreaseLiquidityV2

從倉位移除流動性。 參數
帳戶 — 結構與 IncreaseLiquidity 相同。 效果
  • 依當前 sqrt_price_x64 計算移除 L 所對應的 (amount_0, amount_1)
  • 結算自上次觸碰以來累積的手續費/獎勵,方式與 IncreaseLiquidity 相同。
  • amount_0 + fees_owed_0amount_1 + fees_owed_1 從保險庫轉給使用者。
  • 遞減流動性計數器;若新的 personal_position.liquidity == 0,該倉位可執行 ClosePosition
滑點amount_0_minamount_1_min 是使用者在扣除輸出端 Token-2022 轉帳費用後可接受的最低金額。

ClosePosition

銷毀倉位 NFT 並關閉 PersonalPositionState 前置條件
  • personal_position.liquidity == 0
  • tokens_fees_owed_{0,1} == 0
  • 所有獎勵計數器 reward_amount_owed == 0
(即:請先收取所有應得款項並將流動性減至零。) 效果
  • 銷毀 NFT。
  • 關閉 NFT mint 帳戶及 personal_position 帳戶,並將租金退還給 payer

SwapV2

沿流動性曲線行走;依 is_base_input 決定精確輸入或精確輸出模式。 參數
帳戶(簡略) 呼叫方傳入一組按優先順序排列、涵蓋預期交換範圍的 tick array 清單;程式按需取用。SDK 透過 PoolUtils.computeAmountOutFormat 或 API 報價端點計算此清單。 前置條件
  • pool_state.status 允許交換。
  • now >= open_time
  • sqrt_price_limit_x64 位於當前 sqrt_price_x64 在該方向的正確一側。
常見錯誤ExceededSlippageSqrtPriceLimitOverflowTickArrayNotFoundLiquidityInsufficient 呼叫方應了解的 SwapV2 內部行為(2025 年後版本):
  1. 動態費用附加 — 若 pool.dynamic_fee_info 非零,程式依自上次交換以來穿越的 tick 距離更新波動性累加器(套用 products/clmm/fees 中的過濾/衰減規則),並在 AmmConfig.trade_fee_rate 之上加入 dynamic_fee_component。總費率上限為 10%(MAX_FEE_RATE_NUMERATOR / 1_000_000)。
  2. 限價單撮合 — 當價格行走穿越持有開放限價單的 tick 時,程式先按 order_phase FIFO 順序成交該 tick 的限價單流動性,再繼續沿 LP 流動性曲線行走。已成交金額更新 tick.unfilled_ratio_x64tick.part_filled_orders_remaining,供後續結算使用;訂單本身保持未動,直至擁有者呼叫 SettleLimitOrder
  3. 單側費用路由 — 當 pool.fee_on = Token0OnlyToken1Only 時,交換步驟仍計算相同的輸入輸出交易;費用隨後路由至設定的一側。若設定的費用側為輸出端,費用從交換輸出中扣除(使用者收到 out − fee);若為輸入端,行為與 FromInput 相同。請參閱 PoolState 上的 is_fee_on_input(zero_for_one)is_fee_on_token0(zero_for_one)
Swap(V1)實作與 SwapV2 相同的動態費用、單側費用路由及限價單撮合;唯一缺少的功能是 Token-2022 支援——兩個保險庫均須為傳統 SPL Token。任何含有 Token-2022 mint 的池必須透過 SwapV2 交換。聚合器與 SDK 已對所有 CLMM 路段優先選用 V2,呼叫方無需依 mint 類型分支處理。

OpenLimitOrder

在指定 tick 掛出賣單。訂單位於每個 tick 的 FIFO 批次中,在價格穿越時成交。 參數
帳戶(簡略) 前置條件
  • tick_index % pool.tick_spacing == 0,且在 [MIN_TICK, MAX_TICK] 範圍內。
  • tick_index 位於所選方向相對於 pool.tick_current 的正確一側(賣出 token0 → tick 必須在當前之上,反之亦然)。在已穿越的 tick 掛單會立即被撮合,因此會被拒絕。
  • pool_state.status 允許限價單操作(第 5 位元)。
後置條件
  • limit_order 已存在,快照開單時的 tick.order_phasetick.unfilled_ratio_x64
  • tick.orders_amount += amount(在當前批次中)。
  • limit_order_nonce.order_nonce += 1
  • 發出 OpenLimitOrderEvent
常見錯誤InvalidLimitOrderAmount(金額為零或低於池的最低限額)、InvalidTickIndex(超出 [MIN_TICK, MAX_TICK] 範圍,或位於 tick_current 所選方向的錯誤一側)、TickAndSpacingNotMatchtick_index % pool.tick_spacing != 0)、OrderPhaseSaturated

IncreaseLimitOrder

增加現有掛單的數量。僅限訂單的 owner 呼叫。 參數
帳戶 — 與 OpenLimitOrder 類似,但不需要 nonce 帳戶;直接傳入 limit_order PDA。 前置條件
  • limit_order.owner == signer
  • 訂單仍在同一批次中(tick.order_phase == limit_order.order_phase)。若批次已開始成交,訂單為部分結算狀態——呼叫方應先呼叫 DecreaseLimitOrderSettleLimitOrder 以向前推進。
效果
  • 從擁有者 ATA 轉入 amountinput_vault
  • limit_order.total_amount += amounttick.orders_amount += amount

DecreaseLimitOrder

減少或完全取消掛單。退回未成交餘額至擁有者,以及過去部分成交已結算的輸出代幣。 參數
帳戶 — 同時需要輸入與輸出代幣兩側: 效果
  • 依批次的 unfilled_ratio_x64 重新計算自開單以來的已成交金額。
  • 將已成交的輸出代幣傳送至 output_token_account
  • amount 的未成交輸入退回至 input_token_account
  • 相應更新 limit_order。若新的未成交餘額為零,程式關閉該帳戶並將租金退還給 owner

SettleLimitOrder

將已成交的輸出代幣推送給擁有者,而不改變訂單的未成交餘額。適用於 auto_withdraw keeper 對長期部分成交訂單進行分批支付的場景。 呼叫方 — 訂單的 owner,或程式的 limit_order_admin(一個執行自動 keeper 循環的鏈下操作熱錢包)。keeper 沒有其他權限——它只能將已成交的輸出代幣推送至訂單 owner 的 ATA,無法移動使用者其他資金。 帳戶 效果
  • 使用 (limit_order.unfilled_ratio_x64, tick.unfilled_ratio_x64) 計算累積應付輸出金額。
  • 將差額轉至 output_token_account
  • 更新 limit_order.settled_output
  • 關閉訂單;針對剩餘輸入的訂單仍保持開啟狀態。

CloseLimitOrder

關閉已完全成交的訂單帳戶。無論由誰簽署,租金始終退還給 limit_order.owner 呼叫方ownerlimit_order_admin 前置條件
  • 訂單未成交餘額為零(amount == total_amount 已成交並結算,或擁有者先前已將訂單減至零但忘記關閉)。
效果
  • 關閉 limit_order;租金傳送至 limit_order.owner

CreateDynamicFeeConfig(管理員)

以 u16 索引建立可重複使用的參數集。 參數
帳戶 常見錯誤 — 若 decay_period <= filter_period 或任何值為 0 的欄位超出範圍,則回傳 InvalidDynamicFeeConfigParams

UpdateDynamicFeeConfig(管理員)

修改現有的 DynamicFeeConfig。已在建立時快照該設定的池不會被追溯更新;只有後續建立並參照此設定的新池才會採用新值。 參數 — 與 CreateDynamicFeeConfig 相同的五個校準欄位(filter_perioddecay_periodreduction_factordynamic_fee_controlmax_volatility_accumulator);index 在建立時固定,此處不再傳入。

CollectProtocolFee / CollectFundFee

結構與 CPMM 的 CollectProtocolFee / CollectFundFee 完全相同。簽署者必須符合 AmmConfig.owner / AmmConfig.fund_owner。將池保險庫中累積的協議費/基金費轉至接收方,並將對應的 PoolState.protocol_fees_* / fund_fees_* 欄位歸零。

InitializeReward

為池附加新的獎勵流。每個池最多可同時啟用 3 個獎勵流。 參數
帳戶 前置條件
  • 池目前啟用的獎勵流少於 3 個。
  • 資助方在此指令執行時向保險庫存入 total_emission = emissions_per_second × (end_time − open_time) 數量的獎勵代幣。
  • 獎勵 mint 已依 operation_state 加入白名單。

SetRewardParams

延長、補充或修改現有獎勵流的發放速率。通常由池建立者或 Raydium 多簽呼叫。鏈上有相應限制:一般可以延長 end_time 或提高發放量,但不能追溯縮減。請查閱 operation_state 的擁有者清單。

UpdateRewardInfos

純帳務操作——透過 emissions_per_second × Δt / liquidityreward_growth_global_x64 結算至當前時間。每個涉及流動性的指令內部均會呼叫此操作。也作為獨立指令對外開放,以便 UI 或 crank 等外部角色主動觸發。

CollectReward

倉位擁有者領取應得的獎勵代幣。 帳戶 效果
  • 結算獎勵增長(方式與手續費相同)。
  • 將應付金額轉至接收方 ATA,並將 reward_amount_owed[i] 歸零。

狀態變更矩陣

下一步

資料來源: