Skip to main content
本页内容由 AI 自动翻译,所有内容以英文版本为准。查看英文版 →
本页与 products/clmm/accounts(账户说明)和 products/clmm/math(数学原理)配套。本页对参数和账户顺序具有权威性;具体的字节布局来自 IDL。 2026-09 程序升级在 Anchor 1.0.2 / Solana 3.1.10 上重建了 CLMM,添加了管理员指令 CollectExcessLamports,并改变了 CreateAmmConfig 写入 owner / fund_owner 的内容。没有用户面向的指令改变了其账户、参数或数学。详见 2026-09-30 更新日志条目。 2026-10-22 程序升级将 CreatePermissionedPool 重命名为 CreateCustomizablePoolV2,使其可由任何人调用,并移除了 Permission 账户及其两个管理员指令。详见 2026-10-22 更新日志条目。

指令清单

没有初始化 tick 数组指令,也不需要。 Tick 数组在 OpenPosition* / IncreaseLiquidity* 内部由 TickArrayState::get_or_create_tick_array 创建,由 payer 支付。将(可能仍未初始化的、系统拥有的)tick 数组 PDA 作为 tick_array_lower / tick_array_upper 传入,程序在缺失时分配它。OpenLimitOrder 对其单个 tick_array 执行相同操作。
大多数管理员专用指令(CreateAmmConfig、UpdateAmmConfig、UpdatePoolStatus、CreateOperationAccount、UpdateOperationAccount、CloseProtocolPosition)由程序的硬编码 admin 公钥门控。CreateSupportMintAssociated / CloseSupportMintAssociated 接受 admin 公钥或专用的支持铸币所有者密钥;CollectExcessLamports 接受 admin 公钥或专用的清理 lamports 钱包。奖励流管理员指令(TransferRewardOwner、CollectRemainingRewards)由奖励资金提供者门控,而非程序管理员。 V2 后缀表示”在保管库/NFT 上支持 Token-2022,需要位图扩展槽”。SDK 默认为新池选择 V2。

CreatePool

参数
账户(简化)
槽 10 和 11 是按铸币的,不是”SPL Token 然后 Token-2022”。每个都受匹配铸币上的 mint::token_program 约束,因此对于 token_mint_0 是 Token-2022 且 token_mint_1 是经典 SPL 的池,你必须在槽 10 中传入 Token-2022,在槽 11 中传入 SPL Token。CreateCustomizablePool 和 CreateCustomizablePoolV2 使用相同的两个槽。
前置条件
  • 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 的 13 个声明账户。dynamic_fee_config 不是声明账户。
当 enable_dynamic_fee = true 时,要快照的 DynamicFeeConfig 必须作为最后一个 remaining_account 提供 — 处理程序读取 ctx.remaining_accounts.last()。任何 SupportMintAssociated 绕过 PDA 必须因此在其之前,否则程序快照错误的账户并在反序列化时失败。在设置标志的同时省略它会导致 AccountLack 失败。
前置条件 — 与 CreatePool 相同。如果 enable_dynamic_fee = false,不需要 remaining_account,任何传入的都仅被扫描以查找支持铸币记录。 后置条件
  • pool_state.fee_on 设置为选定的 CollectFeeOn 变体。
  • 如果启用了动态费用:pool_state.dynamic_fee_info 从提供的 DynamicFeeConfig 初始化(复制五个校准参数;状态字段清零)。
  • 否则:pool_state.dynamic_fee_info 被清零(= 此池永远不活跃动态费用)。
fee_on 和动态费用启用位仅在池创建时设置。没有原地升级 — 通过旧版 CreatePool 创建的池无法追溯获得动态费用或单边费用。新部署应默认使用此指令。

CreateCustomizablePoolV2

CreatePool 和 CreateCustomizablePool 都从 ["pool", amm_config, token_mint_0, token_mint_1] 派生池 PDA,因此每个 (config, mint0, mint1) 三元组恰好对应一个规范池地址——在相同种子处的第二次 init 会失败。CreateCustomizablePoolV2 通过将客户端提供的 seed_index: u16 折叠到池 PDA 种子中来解除这一限制,允许同一交易对和费率层级下存在多个池——每个池都有自己的地址。任何人都可以调用它。 池的其他所有方面都与 CreateCustomizablePool 相同:它采用相同的 CreateCustomizableParams 并支持单边费用和动态费用选择加入。
在 2026-10-22 升级 之前,该指令被称为 CreatePermissionedPool,需要支付者持有管理员颁发的 Permission PDA。升级后重命名了该指令,移除了 permission 账户并删除了权限机制。由于名称改变,判别器也随之改变,针对 CreatePermissionedPool 构建的客户端必须重新构建。
参数
账户 remaining_accounts:当 Token-2022 mint 需要时的支持 mint 注册表 PDA,以及当 enable_dynamic_fee = true 时最后的 DynamicFeeConfig——与 CreateCustomizablePool 相同。 前置条件
  • seed_index != 0。seed_index 为 0 保留给旧版池,此处会被拒绝;[0, 0] 种子分量是使旧版池地址折叠为经典四种子形式的原因。
  • 派生地址处不存在池。
  • 与 CreatePool 相同的 mint/允许列表规则。
后置条件
  • 新的 pool_state 存在于 seed_index 派生的地址处,其中 pool_state.seed_index = seed_index。
  • 所有其他后状态与 CreateCustomizablePool 匹配(费用模式、可选动态费用)。
由于 pool_creator 未被检查,任何支付者都可以将任何地址写入 pool_state.owner。该地址可以在池上调用 InitializeReward,但这不能证明谁创建了池。集成商不应根据 V2 池的 owner 标记或排名。

OpenPositionV2 / OpenPositionWithToken22Nft

在现有池内创建新头寸。 参数
账户——两个变体有不同的账户列表。OpenPositionV2 声明 22 个;OpenPositionWithToken22Nft 声明 20 个。 OpenPositionV2,按顺序: OpenPositionWithToken22Nft 是相同的列表,但移除了 metadata_account(5)和 metadata_program(19)——它通过 NFT mint 上的 Token-2022 元数据扩展来写入头寸的元数据——共 20 个账户。其 position_nft_mint 是裸 Signer,position_nft_account 是 UncheckedAccount。
tick_array_bitmap_extension 不是任一变体上的声明账户。 当头寸的范围超出池的内联 tick_array_bitmap(±512 tick 数组)时,在 remaining_accounts[0] 处追加种子为 ["pool_tick_array_bitmap_extension", pool_state] 的 TickArrayBitmapExtension PDA。
数学——见 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 数组 PDA。它们不需要已存在——get_or_create_tick_array 在此指令内以 payer 的费用分配缺失的。没有单独的初始化 tick 数组指令。
  • 用户在源 ATA 中至少有 amount_0_max 和 amount_1_max。
后置条件
  • personal_position 存在,liquidity 已设置,fee_growth_inside_last 已快照。
  • tick_lower 和 tick_upper 处的 tick 数组条目已更新(liquidity_gross += L,liquidity_net ± L,费用增长快照已维护)。
  • 如果头寸在范围内(tick_lower ≤ tick_current < tick_upper),则 pool_state.liquidity += L。
  • 头寸 NFT mint 记录 pool_state 作为冻结权限。在单个 NFT 被铸造后,mint 权限被移除。记录冻结权限不会改变 NFT 代币账户的状态。
  • NFT 代币账户保持未冻结,除非指令是 OpenPositionV2 或 OpenPositionWithToken22Nft 且任一保管库 mint 的冻结权限与 CLMM 的受限发行者列表匹配。只有匹配的 V2 路径冻结账户。OpenPosition V1 不冻结。
常见错误——TickInvalidOrder(tick_lower >= tick_upper)、TickAndSpacingNotMatch(端点不是 tick_spacing 的倍数)、InvalidTickIndex(超出 [MIN_TICK, MAX_TICK])、MissingTickArrayBitmapExtensionAccount(范围超出内联位图且未追加扩展)、NotApproved(pool_state.status 阻止打开)、ZeroAmountSpecified。
头寸冻结不添加声明的指令账户或参数。客户端可以使用现有的 V2 布局打开这些头寸。行为在链上从 vault_0_mint 和 vault_1_mint 选择。

IncreaseLiquidityV2

向已打开的头寸添加流动性。 参数
账户——15 个,不可从 OpenPosition 派生:没有 rent、没有 system_program、没有 associated_token_program 和没有元数据账户。 当头寸的范围超出内联位图时,在 remaining_accounts[0] 处前置 TickArrayBitmapExtension PDA。 效果
  • 从用户转账 amount_0_actual / amount_1_actual 到保管库。
  • 增加 personal_position.liquidity 和 pool_state.liquidity(如果在范围内),并相应地增加端点 tick 的 liquidity_gross / liquidity_net。
  • 收集自上次触及以来应得的费用和奖励,并将其记入 token_fees_owed_{0,1} / reward_amount_owed。这些仅在 DecreaseLiquidity / DecreaseLiquidityV2 时支付,不在增加时支付——没有独立的收集指令。

DecreaseLiquidityV2

从头寸移除流动性。 参数
账户——16 个,不与 IncreaseLiquidityV2 相同的形状或顺序:personal_position 和 pool_state 互换,保管库在 tick 数组之前,用户端账户命名为 recipient_token_account_*,还有额外的 memo_program。 剩余账户——每个活跃奖励被收集时三个,按 reward_token_vault(W)、recipient_token_account(W)、reward_vault_mint 的顺序。当头寸的范围超出内联位图时,前置 TickArrayBitmapExtension PDA。
这也是唯一收集费用和奖励的方式。要在不改变头寸的情况下收集,使用 liquidity = 0、amount_0_min = 0、amount_1_min = 0 调用它。
效果
  • 给定当前 sqrt_price_x64,计算移除的 L 对应的 (amount_0, amount_1)。
  • 结算自上次触及以来累积的费用/奖励,与 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 铸币无法关闭,供应量保持为零。
解冻、销毁和关闭是原子操作。NFT 在这些步骤之间无法变为可转移。 条件客户端兼容性 — 声明的 IDL 布局未改变,因此旧版客户端继续关闭现有的和未冻结的头寸。省略池剩余账户的旧版构建器在关闭冻结头寸时会因 AccountLack 失败。为每次关闭都传递池是最简单的兼容策略。

SwapV2

沿流动性曲线行走;根据 is_base_input 进行精确输入或精确输出。 参数
账户(简化版) 调用者传递覆盖预期交换行走的排序 tick 数组列表;程序根据需要使用尽可能多的数组。SDK 通过 PoolUtils.computeAmountOutFormat 或 API 的报价端点计算此列表。 前置条件
  • pool_state.status 允许交换。
  • now >= open_time。
  • sqrt_price_limit_x64 在 sqrt_price_x64 的正确一侧用于该方向。
常见错误 — TooLittleOutputReceived(精确输入滑点)、TooMuchInputPaid(精确输出滑点)、SqrtPriceLimitOverflow、NotEnoughTickArrayAccount、InvalidFirstTickArrayAccount、MissingTickArrayBitmapExtensionAccount、LiquidityInsufficient、NotApproved(在 pool_state.status 上设置了交换位)。CLMM 没有 ExceededSlippage 变体 — 那是 CPMM 的 — 也没有 TickArrayNotFound。 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 时,程序首先在该 tick 处填充可用的限价单流动性(按 order_phase 的 FIFO),然后沿 LP 流动性曲线继续。填充的数量更新 tick.unfilled_ratio_x64 和 tick.part_filled_orders_remaining 以供后续结算;订单本身保持未花费状态,直到其所有者调用 SettleLimitOrder。
  3. 单边费用路由 — 当 pool.fee_on = Token0Only 或 Token1Only 时,交换步骤仍然计算相同的输入-输出交易;费用随后被路由到配置的一侧。对于配置费用侧是输出的方向,费用从交换输出中扣除(用户收到 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 铸币的池必须通过 SwapV2 进行交换。聚合器和 SDK 已经为每个 CLMM 腿优先选择 V2,因此调用者不必根据铸币类型进行分支。

OpenLimitOrder

在特定 tick 处下达卖单。订单位于每个 tick 的 FIFO 队列中,并在价格经过时填充。 参数
账户(简化版) 剩余账户 — [0] tick_array_bitmap_extension,仅当初始化起始索引落在池内联位图之外的 tick 数组时需要。否则不传递任何内容。
没有 rent 账户:结构体在 system_program 处结束,13 个声明的账户。位置 14 处的杂散 rent 恰好落在可选位图扩展被读取的位置,因此订单看起来可以工作,直到第一次必须创建内联位图之外的 tick 数组 — 然后失败。
账户列表变更(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 → tick 必须在当前之上,反之亦然)。在已经穿过的 tick 处卖出会立即匹配并被拒绝。
后置条件
  • limit_order 存在,在打开时快照 tick.order_phase 和 tick.unfilled_ratio_x64。
  • tick.orders_amount += amount(在当前队列中)。
  • limit_order_nonce.order_nonce += 1。
  • 发出 OpenLimitOrderEvent。
常见错误 — NotApproved(输入或输出代币账户冻结,或池禁用了交换/限价单)、ZeroAmountSpecified(输入侧转账费用后 amount == 0)、InvalidLimitOrderAmount(数量会在该 tick 处产生低于 1 个基本单位的输出,或溢出 u64)、InvalidTickIndex(超出 [MIN_TICK, MAX_TICK],或在所选方向的 tick_current 错误一侧)、TickAndSpacingNotMatch(tick_index % pool.tick_spacing != 0)、OrderPhaseSaturated。

IncreaseLimitOrder

添加到现有开放订单。仅可由订单的 owner 调用。 参数
账户 — 8 个,仅输入侧。它删除了 nonce 账户、所有三个输出侧账户和 system_program。 前置条件
  • limit_order.owner == signer。
  • 订单仍在同一队列中(tick.order_phase == limit_order.order_phase)。如果队列已开始填充,订单已部分结算 — 调用者应首先调用 DecreaseLimitOrder 或 SettleLimitOrder 来推进。
效果
  • 从所有者 ATA 转账 amount 到 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 守护进程想要分批支付长期运行的部分填充时很有用。 调用者 — 订单的 owner,或程序的 limit_order_admin(运行自动化守护进程循环的离链操作热钱包)。守护进程没有其他权限 — 它只能将已填充的输出推送到订单的 owner 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(管理员)

在 u16 索引下创建可重用的参数集。 参数
账户 常见错误 — 如果 decay_period <= filter_period 或任何 0 值字段超出范围,则为 InvalidDynamicFeeConfigParams。

UpdateDynamicFeeConfig(管理员)

修改现有的 DynamicFeeConfig。已在创建时快照配置的池不会被追溯更新;只有新创建的引用此配置的池才会获取新值。 参数 — 与 CreateDynamicFeeConfig 相同的五个校准字段(filter_period、decay_period、reduction_factor、dynamic_fee_control、max_volatility_accumulator);index 在创建时固定,此处不重新传递。

CollectProtocolFee / CollectFundFee

从池的金库中扫除累积的协议/基金费用到收款人,将相应的 PoolState.protocol_fees_* / fund_fees_* 字段清零。这不是 CPMM 的布局 — CLMM 没有 authority 账户,收款人字段名为 recipient_token_account_{0,1} 而不是 recipient_token_{0,1}_account。 参数 — amount_0_requested: u64、amount_1_requested: u64。
2026-09 中的变更:新配置不再从签名者获取其费用所有者。 create_amm_config 现在将程序的硬编码 protocol_fee_owner::ID 写入 owner,将 fund_fee_owner::ID 写入 fund_owner。之前,它将管理员签名者的密钥复制到两者中。在主网上,这些已经是存储在所有 21 个现有配置上的相同密钥。地址在 reference/program-addresses 中。上面接受的签名者保持不变。管理员仍然可以从任何配置中收集,现有的 AmmConfig 账户不会被重写。从账户中读取 owner / fund_owner 而不是假设任一值。UpdateAmmConfig 参数 3 和 4 仍然可以轮换它们。

CollectExcessLamports

管理员扫除 CLMM 控制的账户上超过租金豁免最低值的 lamport。它在 2026-09 升级中添加,以回收 SIMD-0437 租金减少 在每个步骤之前创建的账户上留下的过度资金。 只有超额部分移动。代币余额、账户数据、所有者、池状态和价格曲线保持不变。已经处于最低值的账户保持原样,因此在每次推出步骤后可以安全地重新运行该指令。 参数:无。 账户 范围:每次调用一个池。 CLMM 没有程序范围的金库权限。每个池的金库由其自己的 PoolState 拥有。因此,每个代币程序源必须在第 2 个槽位中有 pool_state 作为其权限:token_vault_0、token_vault_1 或该池的奖励金库之一。如果你传递另一个池的金库或用户的代币账户,代币程序的所有者检查失败,整个指令恢复。它不会被跳过。位置 NFT 铸币不能被扫除,因为当位置打开时其铸币权限被撤销。 每个源账户的处理方式 程序对 remaining_accounts 进行两次遍历:首先是每个代币程序 CPI,然后是直接借记。交错两者会导致运行时的 UnbalancedInstruction 错误,因此顺序在程序中是固定的,你不必自己排序列表。
第 2 遍涵盖用户支付租金的账户。 此处传递的 PersonalPositionState 或 LimitOrderState 像任何其他 CLMM 拥有的账户一样放弃其超额。它保持租金豁免并保留其数据。当它稍后关闭时,所有者获得账户此时持有的任何内容,在扫除后是当前租金最低值。
交易大小是一次调用中有多少源的真正限制。这与 solana-fundamentals/rent-and-reclaimable-rent 中描述的钱包端扫除的约束相同。 常见错误:
  • NotApproved(6000):错误的签名者。
  • LamportsCalculateError(6052):wSOL 往返没有净为零。
  • 代币程序所有者不匹配错误:代币源不由 pool_state 拥有。
  • InsufficientFunds:程序拥有的账户持有少于其自己的租金最低值。
无 SDK 构建器。 @raydium-io/raydium-sdk-v2 不为此管理员路径提供构建器。从 IDL 手动编码。

InitializeReward

向池添加新的奖励流。最多 3 个流可以同时活跃。 参数 — 单个结构体,param: InitializeRewardParam:
线路编码是三个字段背靠背,所以手工构建的指令不受影响 — 但 IDL 驱动的客户端必须传递一个 param 对象而不是三个位置参数。 账户 前置条件
  • 池上当前活跃的流少于 3 个。
  • 资金提供者将 total_emission = emissions_per_second × (end_time − open_time) 价值的奖励代币作为此指令的一部分存入金库。
  • 按 operation_state 白名单的奖励铸币。

SetRewardParams

扩展、充值或更改现有奖励流的发放速率。通常由池创建者或 Raydium 多签调用。约束在链上:你通常可以扩展 end_time 或增加发放,而不是追溯性地缩小它们。检查 operation_state 的所有者列表。

UpdateRewardInfos

纯粹的簿记 — 通过将 emissions_per_second × Δt / liquidity 相乘,将 reward_growth_global_x64 结算到当前时间。由每个涉及流动性的指令内部调用。作为独立指令公开,因为外部参与者(UI、cranks)有时想要触发它。

收集奖励

没有独立的收集奖励指令。 程序不公开 CollectReward 入口点,已发布的 IDL 中也没有。
欠位置的奖励由 DecreaseLiquidity / DecreaseLiquidityV2 支付。要在不改变位置的情况下收集,使用 liquidity = 0、amount_0_min = 0、amount_1_min = 0 调用它。奖励金库和收款人账户在 remaining_accounts 中按每个活跃奖励的三个一组,顺序为 reward_token_vault(W)、recipient_token_account(W)、reward_vault_mint。 CollectRemainingRewards 是另一回事:它让奖励资金提供者在流的 end_time 之后扫除从未分配给任何位置的代币。

状态变更矩阵

后续步骤

来源: