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 自动翻译,所有内容以英文版本为准。查看英文版 →
两笔独立手续费,四个目的地
CPMM 对每次交换征收两笔独立费率的手续费:- 交易手续费 — 按
AmmConfig.trade_fee_rate收取,拆分为三个目的地:- LP 份额 — 留在保管库中并增加
k。通过销毁 LP token 隐式领取。 - 协议份额 — 累计到
PoolState.protocol_fees_token*;由protocol_owner通过CollectProtocolFee扫出。 - 基金份额 — 累计到
PoolState.fund_fees_token*;由fund_owner通过CollectFundFee扫出。
- LP 份额 — 留在保管库中并增加
- 创建者手续费(可选,按池配置)— 按
AmmConfig.creator_fee_rate独立收取(不同于交易手续费),累计到PoolState.creator_fees_token*,由pool_state.pool_creator通过CollectCreatorFee扫出。仅在使用enable_creator_fee = true创建池时启用。
trade_fee 推导,永远不从 creator_fee 推导。一个池配置为 creator_fee_rate = 1000(0.10%)和 trade_fee_rate = 2500(0.25%)时,在创建者手续费按输入计算的交换中,输入端的总费率为 0.35%,其中创建者保留 0.10%,交易手续费桶获得 0.25%。
交易手续费费率(trade_fee_rate、protocol_fee_rate、fund_fee_rate)和 creator_fee_rate 都存储在 AmmConfig 上。按池的 enable_creator_fee 标志和 creator_fee_on 模式(创建者手续费取自交换哪一端)存储在 PoolState 上。见 products/cpmm/accounts。
费率和单位
所有费率都是u64 类型,以 1 / FEE_RATE_DENOMINATOR 为单位,其中 FEE_RATE_DENOMINATOR = 1_000_000。
trade_fee_rate是交换成交量的一部分。2500⇒ 相关端(输入或输出,取决于creator_fee_on— 见下文”手续费取自交换的哪一端”)的 0.25%。creator_fee_rate是交换成交量的一部分,独立于交易手续费采集。1000⇒ 相关端的 0.10%。protocol_fee_rate和fund_fee_rate是交易手续费的一部分,不是成交量的一部分。120_000⇒ 交易手续费的 12%。
AmmConfig[index=0](标准 0.25% 池)的默认参数供参考:
| 字段 | 数值 | 有效百分比 |
|---|---|---|
trade_fee_rate | 2500 | 成交量的 0.25%(交易手续费桶) |
protocol_fee_rate | 120000 | 交易手续费的 12% ≈ 成交量的 0.030% |
fund_fee_rate | 40000 | 交易手续费的 4% ≈ 成交量的 0.010% |
creator_fee_rate | 0(默认) | 0%(独立桶) |
| → LP 份额有效 | 成交量的 0.210% |
AmmConfig[0] 且 enable_creator_fee = false 的 $1,000 交换:总交易手续费 $2.50,其中 $2.10 留给 LP,$0.30 给协议,$0.10 给基金。创建者桶为 0,因为创建者手续费被禁用。
如果同一池配置为 enable_creator_fee = true 且 creator_fee_rate = 1000(0.10%),用户需额外支付 $1.00 到创建者桶 — 从由 creator_fee_on 配置的同一端采集 — 总手续费为 $3.50。交易手续费桶及其协议/基金拆分保持不变。
根据 GET https://api-v3.raydium.io/main/cpmm-config 确认当前主网数值 — 费率由管理员可变,应该是动态读取而不是硬编码的。
代码中的拆分
- 输入端的总手续费向上舍入,所以池永远不会欠费。
trade_fee的子拆分(protocol、fund)向下舍入,所以它们的和永远不超过trade_fee;剩余部分是 LP 份额。lp_share = trade_fee − protocol_fee − fund_fee(creator_fee 不在此处扣除,因为它是独立桶)。- 创建者手续费从输入或输出端采集,取决于
PoolState.creator_fee_on(见下一节)。无论哪一端,费率都不变。
手续费从交换的哪一端采集
CPMM 有一个按池的creator_fee_on 设置(BothToken / OnlyToken0 / OnlyToken1),决定创建者手续费是从给定交换的输入端还是输出端采集。运行时帮助函数 is_creator_fee_on_input(direction) 对每次交换将其化简为布尔值:
creator_fee_on | 交换 0 → 1 | 交换 1 → 0 |
|---|---|---|
BothToken (0) | 输入端 | 输入端 |
OnlyToken0 (1) | 输入端 | 输出端 |
OnlyToken1 (2) | 输出端 | 输入端 |
amount_in 扣除。报价数学:从输入端扣除组合 trade_rate + creator_rate。
当创建者手续费在输出端时,只有交易手续费从 amount_in 扣除;曲线生成未扣费的输出,然后创建者手续费从该输出扣除。报价数学:从输入端扣除 trade_rate;从输出端扣除 creator_rate。
交易手续费本身总是在输入端采集(标准 Uniswap-V2 模式)。只有创建者手续费可以在输出端。
“累计”手续费如何与曲线互动
一个重要的微妙之处:协议、基金和创建者手续费在被称为相应Collect* 指令之前,物理上留在保管库中。但它们从曲线对保管库余额的看法中被排除。
一次交换后的具体图景:
k' ≥ k 时使用 curve_x(以及类似的 curve_y)。这就是非 LP 手续费到达其目的地而不膨胀池中 LP 份额的方式。
你应该在设计时考虑的后果:
- 从原始余额报价是错误的。 如果你从
getTokenAccountBalance构建报价程序,你会一致地高估池将遵守的价格。始终减去累计手续费,或通过SwapBaseInput/ API 模拟。 CollectProtocolFee不移动价格。 它将 token 移出保管库并清零protocol_fees_token*计数器,所以curve_x和curve_y保持不变。- LP 手续费不累计到计数器。 它们隐含在保管库余额中。LP 对累计 LP 手续费的权利通过销毁 LP token(即通过
Withdraw)行使 — 没有CollectLpFee。
与 Token-2022 转账手续费的交互
Token-2022 转账手续费由造币厂应用,不是由 CPMM。它们作用于每次 token 转账 — 交换、存款、提取以及Collect* 扫出。CPMM 的交易手续费数学是针对实际到达保管库的金额计算的,即净扣除输入造币厂的转账手续费(如有)。
因此,在最坏情况下,用户在输入精确的交换中支付三笔不同的税:
- 输入造币厂在
amount_in上的转账手续费(给造币厂的手续费权限账户)。 - 池的
trade_fee在剩余部分上(按上述拆分)。 - 输出造币厂在
amount_out上的转账手续费(给造币厂的手续费权限账户)。
minimum_amount_out 以用户实际接收的额度计。如果你在写自己的报价程序,镜像该行为,否则你的滑点检查会系统性地过于宽松。
见 algorithms/token-2022-transfer-fees 了解详细推导。
创建者手续费
创建者手续费是可选的且按池配置。费率存储在AmmConfig.creator_fee_rate 上;启用标志和端(creator_fee_on)存储在 PoolState 上:
- 在池创建时启用。
Initialize默认设置enable_creator_fee = false;通过InitializeWithPermission创建的池(由 LaunchLab 毕业和其他门控路径使用)可以传递enable_creator_fee = true并选择creator_fee_on。 - 费率与费率层共享。 费率本身是
AmmConfig.creator_fee_rate,跨绑定到该配置的每个池都是同一个值。每个池随后决定是否收取它(enable_creator_fee)以及从交换的哪一端收取它(creator_fee_on)。当enable_creator_fee = false时,不管配置值如何,池的有效创建者手续费率为零(见源中的PoolState::adjust_creator_fee_rate)。 - 独立于交易手续费。 创建者手续费永远不会减少 LP / 协议 / 基金份额 — 它是独立费率,单独应用,在自己的计数器中累计。
- 通过
CollectCreatorFee扫出,由PoolState.pool_creator签名。 - 创建后不能重新启用或重新路由。 使用
enable_creator_fee = false初始化的池永远不会收取创建者手续费;使用特定creator_fee_on初始化的池无法切换端。
CollectCreatorFee。
收集操作流程
| 签名者 | 指令 | 清零的源计数器 | 典型节奏 |
|---|---|---|---|
amm_config.protocol_owner | CollectProtocolFee | protocol_fees_token{0,1} | 每周或按程序 |
amm_config.fund_owner | CollectFundFee | fund_fees_token{0,1} | 每周或按程序 |
pool_state.pool_creator | CollectCreatorFee | creator_fees_token{0,1} | 任何时间 |
security/admin-and-multisig。创建者签名者是运行 Initialize 的账户。
更改费率层
费率可以由管理员通过UpdateAmmConfig 更改(见 products/cpmm/instructions)。更改对下次交换对绑定到该 AmmConfig 的每个池生效 — 没有迁移,因为池在每次交换时加载配置。
管理员不能做的:
- 将池从一个
AmmConfig移到另一个。 - 追溯重新定价已累计的手续费。
- 在没有
protocol_owner/fund_owner签名者的情况下收取手续费。
从运行的池读取手续费
与 CLMM 和 AMM v4 的比较
见reference/fee-comparison 了解并排矩阵。总结:
- AMM v4 使用固定 0.25% 交易手续费,有不同的 LP/协议拆分,没有基金手续费。
- CLMM 手续费按 tick-spacing 层级,按头寸累计(不是按池),通过
DecreaseLiquidity或CollectFees领取。
后续步骤
products/cpmm/math— 交易手续费扣除如何插入曲线。products/cpmm/instructions—Collect*指令账户列表。algorithms/token-2022-transfer-fees— 如何正确组合池交易手续费和造币厂转账手续费。


