pump-bonding-curve について
Pumpのトークン価格やAMMを扱う開発者向けに、ボンディングカーブ計算の実装と保守を支援するスキルです。手数料込みの売買見積もり、市場価値、リザーブ管理、境界ケースを扱います。
主な機能
- 01定積積型の売買見積もり
- 02手数料計算と段階別手数料
- 03時価総額の計算
- 04仮想リザーブと実リザーブの管理
- 05卒業済みカーブの境界処理
活用シーン
- 01SOL購入時のトークン出力量を計算
- 02トークン売却時のSOL受取量を推定
- 03カーブ卒業後の見積もりを処理
- 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)で取引しようとすると、オンチェーンで失敗します - 手数料ティアは逆順に反復処理します。順方向ではありません
- 時価総額の計算には
tokenTotalSupplyではなくmintSupplyを使用します - 手数料控除の計算では、最初に金額から 1 を引きます。これは意図的な処理です
getBuySolAmountFromTokenAmountQuoteは、十分な SOL を確保するために結果に+ 1を加えます