mcpField
P
pump-bonding-curve

pump-bonding-curve

github.com/nirholas其他140113 次安装3 周前更新
代码仓库

关于 pump-bonding-curve

面向 Pump 代币定价与 AMM 开发者的技能,用于实现和维护 bonding curve 计算。涵盖含手续费的买卖报价、市值、储备管理及曲线边界情况。

主要功能

  1. 01恒定乘积买卖报价
  2. 02手续费计算与费率分层
  3. 03市值计算
  4. 04虚拟与实际储备管理
  5. 05毕业曲线边界处理

适用场景

  1. 01计算 SOL 买入可得代币数量
  2. 02估算卖出代币所得 SOL
  3. 03处理曲线毕业后的报价
  4. 04按实际储备限制买入数量

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/nirholas/pump-fun-sdk --skill pump-bonding-curve

安装后在 Claude Code 中输入/pump-bonding-curve确认已加载。

详细介绍

债券曲线 — 定价、报价与 AMM 数学

实现并维护为 Pump 代币定价提供支持的恒定乘积 AMM 债券曲线数学逻辑,包括买入/卖出报价、考虑手续费的计算、市值计算、储备管理,以及新建、活跃和已迁移曲线的边界情况处理。

背景

Pump 代币使用恒定乘积债券曲线($x \times y = k$)定价,其中 $x$ = 虚拟 SOL 储备,$y$ = 虚拟代币储备。债券曲线决定代币在毕业前阶段的价格。当市值达到阈值后,代币会“毕业”并迁移到 PumpAMM 池。

关键文件

  • src/bondingCurve.ts — 所有债券曲线数学函数(买入/卖出报价、市值)
  • src/fees.ts — 手续费计算(基点、分级手续费、向上取整除法)
  • src/state.ts — BondingCurve、Global、FeeConfig、FeeTier 接口

恒定乘积公式

$$x \times y = k$$

买入(投入 SOL,获得代币): $$\text{tokensOut} = \frac{dx \times Y}{X + dx}$$

其中 $dx$ = SOL 输入量(扣除手续费后),$X$ = 虚拟 SOL 储备,$Y$ = 虚拟代币储备。

卖出(投入代币,获得 SOL): $$\text{solOut} = \frac{dy \times X}{Y + dy}$$

其中 $dy$ = 卖出的代币数量,$X$ = 虚拟 SOL 储备,$Y$ = 虚拟代币储备。

扣除手续费

在应用债券曲线公式之前,先从 SOL 数量中扣除手续费:

inputAmount = (amount - 1) * 10000 / (totalFeeBps + 10000)

扣除手续费之前的 - 1 是有意为之,用于处理舍入边界情况。

市值计算

$$\text{marketCap} = \frac{\text{virtualSolReserves} \times \text{mintSupply}}{\text{virtualTokenReserves}}$$

其中 mintSupply 默认为 ONE_BILLION_SUPPLY($1 \times 10^{15}$ — 6 位小数的 10 亿枚代币)。

手续费等级

存在 FeeConfig 时,手续费取决于市值。手续费等级按逆序遍历——从末尾开始,第一个满足 marketCapLamportsThreshold ≤ currentMarketCap 的等级即为选中等级。

interface FeeTier {
    marketCapLamportsThreshold: BN;
    fees: { lpFeeBps: BN; protocolFeeBps: BN; creatorFeeBps: BN };
}

向上取整除法

$$\text{ceilDiv}(a, b) = \frac{a + b - 1}{b}$$

function ceilDiv(a: BN, b: BN): BN {
    return a.add(b).sub(new BN(1)).div(b);
}

虚拟储备与实际储备

储备类型包含内容用途
virtualSolReserves实际 SOL + 协议添加的虚拟偏移量AMM 公式计算
virtualTokenReserves实际代币 + 虚拟偏移量AMM 公式计算
realTokenReserves实际可用代币买入输出上限
realSolReserves实际存入的 SOL提取限额

边界情况

情况行为
数量为零返回 BN(0)
已迁移的曲线(complete === true,储备为零)返回 BN(0)
债券曲线为 null通过 newBondingCurve(global) 创建一条新曲线
代币数量超过实际储备限制为 realTokenReserves
创建者手续费仅当 bondingCurve.creator != PublicKey.default 或者这是新曲线时才收取

BondingCurve 状态

interface BondingCurve {
    virtualTokenReserves: BN;
    virtualSolReserves: BN;
    realTokenReserves: BN;
    realSolReserves: BN;
    tokenTotalSupply: BN;
    complete: boolean;        // true = graduated to AMM
    creator: PublicKey;
    isMayhemMode: boolean;
}

应遵循的模式

  • 所有数量都使用 BN(bn.js)进行任意精度整数运算——绝不使用 JavaScript number
  • 手续费以基点为单位(1 bps = 0.01%,10,000 bps = 100%)
  • 始终在应用 AMM 公式之前扣除手续费,而不是之后
  • 使用向上取整除法(ceilDiv)计算手续费,确保协议不会损失零头
  • 报价函数是纯函数——不进行网络调用,没有副作用,不使用可变状态
  • 构建交易指令之前,始终检查 bondingCurve.complete

常见问题

  • 混淆虚拟储备(包含虚拟偏移量)与实际储备(实际数量)
  • 报价时未考虑手续费——原始报价函数与考虑手续费的报价函数结果不同
  • 尝试在已毕业的曲线(complete === true)上交易会导致链上失败
  • 手续费等级按逆序遍历——不是正序
  • 市值计算使用 mintSupply,而不是 tokenTotalSupply
  • 手续费扣除公式会先从数量中减去 1——这是有意为之
  • getBuySolAmountFromTokenAmountQuote 会在结果上加 + 1,以确保 SOL 数量充足

评论

支持 Markdown