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

不变量

池维持 coin_reserve × pc_reserve = k,其中(在 2026-07 OpenBook 移除后):
需要注意两点:
  1. 储备现在仅来自金库。历史上的开放订单项(池作为 OpenBook 限价单托管的代币)已被删除——在移除之前很久就已经是零。你可以直接从链上金库余额计算 k
  2. PnL 应计(need_take_pnl_*)被减去,以便在管理员扫除费用时曲线保持不变。这与 CPMM 的 protocol_fees_* 排除原则相同。
程序通过 calc_total_without_take_pnl_no_orderbook 计算此值(旧的订单簿感知变体已消失)。 每个 Swap* 操作在将 LP 的费用份额加回储备后都强制 k' ≥ k

费用约定

AMM v4 使用比率费用(分子/分母对),而不是 CPMM / CLMM 的 1/1_000_000 约定。链上 Fees 结构体(见程序源代码中的 Fees::initialize)默认为:
解释(已发布的主网默认值):
  • 总交换费: swap_fee = amount_in × 25 / 10_000 = 0.25% 的总输入。
  • 协议份额: pnl_numerator / pnl_denominator = 12 / 100 = 12% 的交换费,相当于 0.25% × 12% = 0.03% 的交易量。此份额应计到 PnL 计数器中,由 WithdrawPnl 扫除。
  • LP 份额: 交换费的剩余 88%,相当于 0.25% × 88% = 0.22% 的交易量。保留在池中并增加 k
  • 无基金份额。 AMM v4 没有 CPMM/CLMM 的基金费用分割。
注意 pnl_numerator / pnl_denominator 是费用的一个分数而非交易量——这是对这些字段名的常见误读。 trade_fee_numerator / trade_fee_denominator(也是 25 / 10_000)历史上由 OpenBook 集成在计算 AMM 限价单网格的费用包含价格时使用。随着 OpenBook 代码的移除,此字段已成为遗留物;活跃的交换费是 swap_fee_* 偏离这些默认值很少见,但在少数遗留池上确实存在;在报价前始终从 AmmInfo.fees 读取费用。

直接交换数学(AMM 路径)

最简单的情况:用户直接对池的金库交换,不与 OpenBook 交互。池的内部储备(包括账上分配)是分母。 SwapBaseIn(精确输入):
此处使用的储备是金库余额(减去应计 PnL)。历史上公式还添加了 AMM 锁定在 OpenBook 订单中的代币;该项已被移除——有效储备现在等于原始金库余额减去待处理 PnL。曾经刷新 OpenBook 端的 MonitorStep / 隐式结算路径已被移除。 SwapBaseOut(精确输出):

订单簿交互(历史)

已移除。 本节描述的网格构造反映了 AMM v4 最初如何将曲线镜像到 OpenBook 市场。OpenBook 集成——包括 MonitorStep 曲柄和 build_orders 网格逻辑——已从程序中移除(2026-07 升级)。下面的数学纯粹作为历史背景保留,说明链上 target_orders / amm_open_orders 账户曾经的大小。
除了用户交换,AMM v4 历史上在 OpenBook 市场上放置了一个网格的限价单。网格从 AmmInfo 参数计算:
  • depth — 每侧的价格级别数。
  • amount_wave — 每个级别的基本大小单位。
  • min_sizecoin_lot_sizepc_lot_size — OpenBook 市场约束。
  • state_data.swap_acc_coin_feeswap_acc_pc_fee — 自上次 TakePnl 以来的累积费用计数器。
程序通过以恒定比率步骤从当前曲线价格走出来推导每个级别的价格:
确切的价格和大小由 build_orders 中计算的 target_orders 确定,并在每个 MonitorStepamm_open_orders 比较。任何偏差都会导致取消 + 新发布。OpenBook 上新填充的订单在下一个刷新 OpenBook 端的操作时结算到池金库中。 集成商很少需要计算网格——Raydium 守护者维护它——但了解以下内容很有用:
  • 具有大量账上流动性的池将该流动性贡献给 k,而不是闲置。
  • 陈旧的 OpenBook 市场(事件队列满、曲柄被阻止)阻止网格更新;AMM 随后可以报价与可见订单簿不同的价格,直到下一次曲柄。

结算步骤(PnL)

0.03% 的协议份额应计到 state_data.need_take_pnl_coinstate_data.need_take_pnl_pcTakePnl 将这些金额移出金库到管理员指定的目标,然后将计数器清零。 关键属性:不变量中的储备始终计算减去应计 PnL,所以 TakePnl 不会移动曲线。这与 CPMM 约定相匹配。

工作示例

池状态:
  • coin_reserve = 1_000_000_000_000(1,000,000 币侧;6 位小数)
  • pc_reserve = 2_000_000_000_000(2,000,000 pc 侧;6 位小数)
  • 费用:默认 swap = 25/10_000pnl = 3/10_000
用户:SwapBaseIn 精确输入 1_000_000_000 币(1,000 币)。
LP 份额(2_200_000)没有单独列出——它只是提高 k' 的剩余部分。

精度规则

  • 储备乘法使用 u128;最终除法向零舍入。
  • swap_fee 向上舍入(以便池不会低收费)。
  • SwapBaseOutamount_in 向上舍入(以便用户不会少付)。
  • 具有极端储备比率的池在非常小的输入上可能会触发 ZeroTradingTokens;与 CPMM 相同的约定。

与 CPMM 的限制

  • AMM v4 的储备现在仅来自金库,所以你可以直接从金库余额报价(减去 need_take_pnl_*)——之前添加 open_orders.free / open_orders.locked 金额的要求不再适用。SDK / API 报价仍然是最简单的选项。
  • AMM v4 不公开结构化的链上 TWAP。想要 AMM v4 支持的价格的外部消费者必须从交易日志自己计算。
  • 不支持 Token-2022。

后续步骤

来源: