跳转到主要内容

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.

本页内容由 AI 自动翻译,所有内容以英文版本为准。查看英文版 →

路由器不执行数学运算

路由程序不实现任何定价逻辑。它纯粹是一个编排器:接受一条路由,将账户传递给子程序,并链接代币流。 每个跳转从其自己的池程序曲线进行定价:
  • AMM v4 跳转:使用常数乘积公式(x · y = k)加上 OpenBook 混合定价。参见 products/amm-v4/math
  • CPMM 跳转:使用常数乘积公式,支持可配置的费用分层。参见 products/cpmm/math
  • CLMM 跳转:使用集中流动性 tick 数学。参见 algorithms/clmm-math
  • 稳定币池跳转:为类似资产使用稳定交换曲线。参见 products/stable/math
路由器的唯一作用是:
  1. 通过 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 是否在指定边界内。边界以称为 limit_pricesVecDeque<u128> 传递:
  • 路由中每个 CLMM 跳转一个 sqrt_price_x64
  • sqrt_price_x64 是 CLMM 使用的基于 tick 的价格表示。参见 algorithms/clmm-math 了解定义。
  • 路由器强制执行:
  sqrt_price_lower <= pool.sqrt_price_x64 <= sqrt_price_upper
对于每个 CLMM 跳转,如果价格超出边界,则拒绝交换。

指令变体和 limit_prices

  • SwapBaseInWithUserAccount, SwapBaseOutWithUserAccount (传统,标签 0 和 1)limit_prices VecDeque 必需。如果任何跳转是 CLMM 池,空队列会被拒绝并返回错误。你必须为每个 CLMM 跳转按顺序提供一个价格。
  • SwapBaseIn, SwapBaseOut (当前,标签 8 和 9)limit_prices VecDeque 可选。空队列被静默忽略;不执行价格检查。新代码应使用这些指令。

构建 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:每个池可配置,从输入金额中扣除。
  • 稳定币池:与 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(lamport 或代币最小单位)。
  • 曲线计算在需要时使用 u128 中间值以避免溢出。
  • 舍入约定取决于子程序。路由器不重新舍入。
如果由于极端价格比率跳转产生零金额(例如,在 1B:1 池上交换 1 lamport),路由器将该零传播到下一个跳转,后者可能将其拒绝为不足。参见各个池的错误代码。

后续内容