本文深入探讨了 bonding curve 的数学原理,重点分析了其与恒定乘积做市商(CPAMM)的联系,并通过 Mini Pump 项目的代码实现,详细解释了 bonding curve 在 Pump.fun 等平台上的应用,包括价格设定、曲线形状控制以及交易逻辑,还讨论了 bonding curve 解决流动性启动问题的优势。
联合曲线是一个数学函数,它定义了代币的供应量和价格之间的关系。在 Pump.fun 的案例中,该曲线的工作原理是,随着使用 SOL 购买的代币数量增加,代币价格呈指数级增长。
联合曲线有不同的类型——线性、对数、指数等等。 这些曲线中的许多都可以从恒定乘积自动做市商 (AMM) 公式(如 x · y = k)的机制中导出或类似于该机制。 然而,并非所有联合曲线都可以通过该公式来表达。 例如,阶梯式定价曲线不遵循平滑的数学函数,但通过稍微修改,可以模仿类似的行为。
注意:本文档应与 完整的代码库 一起阅读,该代码库很大程度上受到 Pump Science Implementation 和 联合曲线可视化工具 的启发。 它们共同提供了对该主题的全面理解。
现在,让我们深入探讨。
恒定乘积做市商 (CPAMM) 采用以下公式:
x⋅y=k
其中:
x 和 y 分别是资产 x 和资产 y 的数量。
比率 x / y 表示现货价格。
当发生交易时,x 和 y 的值会发生变化,但 k(恒定乘积)必须保持不变。
数学上:
x = 交易前资产 x 的数量
y = 交易前资产 y 的数量
当用户通过将代币 y 发送到池中来购买代币 x 时,池会根据此原则进行调整:
(x−x′)⋅(y+y′)=k
其中:
x′ = 发送给用户的代币 x 的数量
y′ = 用户发送到池中的代币 y 的数量
k 的值始终保持不变。
另一种表示方式:
设:
x = 交易前资产 a 的数量
y = 交易前资产 b 的数量
x′ = 交易后资产 a 的数量
y′ = 交易后资产 b 的数量
由于两个乘积都应等于 k,因此我们有:
x⋅y=k(交易前)
x′⋅y′=k(交易后)
我们可以重新排列公式以求解 x′:
x′=x⋅yy′
这为我们提供了交易后池中剩余的代币 x 的新数量。
在 AMM 中,x 和 y 由流动性提供者提供,但在联合曲线实现的情况下,我们引入任意数量的 x(虚拟 Sol 流动性)和 y(虚拟代币流动性),允许我们模拟任何流动性场景。
以下解释的代码实现在 Mini Pump 中可以找到。 结合此解释关注代码库,以便更好地理解。
如今,联合曲线的主要用例是在Launchpad中,可以通过指数联合曲线出售铸造的代币来启动代币,而无需初始流动性——如在 Pump Fun 和 Pump Science 中所见。 Mini Pump 是基于联合曲线的Launchpad的极简实现,具有所有必要的功能:
管理员可以配置全局设置。
任何人都可以创建代币并启动它,将 10 亿个代币铸造到联合曲线。
用户可以在联合曲线上买卖。
一旦售出 8 亿个代币以获得大约所需的 SOL,管理员可以提取剩余的 2 亿个代币和所有 SOL,以便在他们选择的 DEX 上创建一个池。 这一步也可以通过直接从程序向 DEX 程序发出 CPI 调用来实现自动化。
全局配置 由管理员在部署后初始化,以定义联合曲线的形状。

owner → 负责设置配置的协议所有者。
tokens_to_sell → 通过联合曲线出售的代币总数(例如,8 亿)。
total_tokens_to_mint → 要铸造的代币总数,包括用于 DEX 迁移的代币(例如,10 亿)。
virtual_sol_liquidity (x) → 添加的虚拟 SOL,用于确定初始价格(例如,30 SOL)。
virtual_token_liquidity (y) → 用于设置初始价格的虚拟代币,通常等于 total_tokens_to_mint(例如,10 亿)。
每个代币启动都有其自己的联合曲线帐户。 创建新代币时,参数会根据全局配置进行初始化

请注意虚拟流动性的使用,这区分了联合曲线Launchpad和传统的 AMM。
虚拟流动性有两个主要目的:
比率 virtual_token_liquidity / virtual_sol_liquidity 定义了初始价格(以每个 SOL 的代币计算),允许启动而无需预付 SOL。
这些值决定了联合曲线的形状。 例如:
你可以在此处尝试不同的值,并查看曲线如何变化:联合曲线可视化工具
主要的兴趣点是计算购买一定数量的代币所需的 SOL 数量以及将代币出售到曲线以接收一定数量的 SOL 所需的代币数量的函数。
你可以在此处找到代码中的买卖逻辑:Mini Pump 买卖计算函数

以下是代码中使用的公式的推导方式:
假设用户想用 1 SOL 购买一些代币,并且刚刚部署了代币的联合曲线。
virtual_sol_liquidity = 30
virtual_token_liquidity = 800,000,000
从 AMM 公式中,我们知道:
x⋅y=x′⋅y′
y′=x⋅yx+Δx
y′=30⋅800,000,00031=774,193,548
Δy=y−y′=800,000,000−774,193,548=25,806,452
其中:
x:交易前的虚拟 SOL 流动性
y:交易前的虚拟代币流动性
x′=x+Δx:交易后的虚拟 SOL 流动性
y′:交易后的虚拟代币流动性
Δx:用户发送的 SOL
Δy=y−y′:用户收到的代币
每次交易后,我们都会更新 virtual_sol_liquidity 和 virtual_token_liquidity。
初始值:
virtual_sol_liquidity = 30
virtual_token_liquidity = 800,000,000
用户用 1 SOL 购买:
交易后更新的值:
virtual_sol_liquidity = 30 + 1 = 31
virtual_token_liquidity = 800,000,000 - ~25,806,452 ≈ 774,193,548
代码参考:

当用户向联合曲线出售代币时,逻辑正好相反。
代币被添加回 virtual_token_liquidity
SOL 从 virtual_sol_liquidity 中扣除
总 tokens_sold 减少
代码参考:

与 SOL 相比,代币流动性越大,购买 8 亿个代币的成本就越低——反之亦然。
以 10 亿个代币和 30 SOL 作为初始虚拟流动性,购买 8 亿个代币的成本约为 120 SOL。

以 11 亿个代币和相同的 30 SOL 虚拟流动性计算,购买 8 亿个代币的成本降至约 80 SOL。

对于 9 亿个虚拟代币供应和 30 个虚拟 sol 而言,购买 8 亿个代币的价格将为 240 SOL

如果将虚拟代币流动性设置为 8 亿个代币,并且你尝试出售正好 8 亿个代币(实际上是将虚拟供应量减少到 0),则会遇到一个数学问题。
让我们看一下公式:
x:SOL 流动性 = 30 SOL
y:代币流动性 = 800,000,000 个代币
我们从 AMM 公式中知道该等式:
x⋅y=x′⋅y′
如果我们尝试出售 8 亿个代币,则我们有:
y′=0
代入公式:
x′=x⋅yy′
x′=x⋅y0=∞
除以零会导致无限值。 因此,我们永远无法出售正好 8 亿个代币,因为它会将虚拟代币流动性减少到零,从而导致价格飙升至无穷大,如图表所示。

在 AMM 中,需要配对中的两种代币的流动性才能进行交易。
例如,Alice 创建了一个名为 $ALICE 的代币,并想通过创建 ALICE/SOL 对来在 Raydium 上启用其交易。 问题是 Alice 需要 SOL 才能创建池。 有人可能会质疑她是否可以只在所需的比率中投入少量两种代币并期望一切正常。
在 AMM 中,流动性越少,交易的价格影响就越大。
例如,考虑一个拥有 100,000 个 ALICE 代币和 1,000 个 SOL 的池。 如果发生 1,000 个 ALICE 的交易——这意味着有人在池中出售 1,000 个 ALICE 代币——根据之前讨论的 CPAMM 公式,他们将获得 9.9 SOL。
x⋅y=k
100,000⋅1,000=100,000,000
(100,000−1,000)⋅y′=100,000⋅1,000
99,000⋅y′=100,000,000
y′=100,000,00099,000≈1,010.10SOL
收到的 SOL=1,010.10−1,000=10.1SOL
但是在拥有 10,000 个 ALICE 代币和 100 个 SOL 的池中,如果发生 1,000 个 ALICE 的交易——其中一个卖家在池中出售 1,000 个 ALICE 代币——他们将仅获得 9.09 SOL。
x⋅y=k
10,000⋅100=1,000,000
(10,000−1,000)⋅y′=10,000⋅100
9,000⋅y′=1,000,000
y′=1,000,0009,000≈111.11SOL
收到的 SOL=111.11−100=11.11SOL
请注意,在这两种情况下,ALICE 与 SOL 的比率是相同的,因此价格相似。 但是,用户会收到不同数量的 SOL。 流动性较小的池多给 1 SOL,按当前的 SOL 价格计算,约为 ~$125。
因此,代币创建者需要大量的 SOL 才能创建一个健康的池。
另一个问题是,在这种情况下,创建者在拥有大部分供应的同时,对起始价格拥有完全的控制权。 相比之下,使用联合曲线,价格从低开始,并随着大量 Solana 的收集而逐渐上涨。 这是一种更具包容性的方法,社区共同决定代币是否应该到达 DEX 并以特定价格开始交易,或者在联合曲线内消亡。
我在审核联合曲线Launchpad时遇到的一个普遍问题是,任何人都可以创建 DEX 上的流动性池,Launchpad稍后将迁移到该池。 例如,使用 Raydium,每个代币对只允许一个池。 如果流动性迁移是通过 Anchor 代码自动进行的,则可能会导致拒绝服务 (DoS) 情况,因为池已创建。
在这种情况下,你应该调用 DEX 上的 add_liquidity 函数,而不是尝试创建一个新池(这将失败)。 此函数将根据已经在 DEX 上运行的当前价格添加流动性。
如有任何后续问题,请随时通过 X 与 Nirlin 联系。
- 原文链接: accelaratedcurve.substac...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!