|
| 1 | +# AMM Trading Guide |
| 2 | + |
| 3 | +Buy, sell, deposit, and withdraw on graduated PumpAMM pools. |
| 4 | + |
| 5 | +> **Program:** PumpAMM (`pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA`) |
| 6 | +
|
| 7 | +--- |
| 8 | + |
| 9 | +## Overview |
| 10 | + |
| 11 | +When a token's bonding curve reaches 100% and graduates, it migrates to the PumpAMM — a constant-product AMM pool. The SDK provides full instruction builders for trading and liquidity management on these pools. |
| 12 | + |
| 13 | +### Bonding Curve vs AMM |
| 14 | + |
| 15 | +| Phase | Program | Price Model | Liquidity | |
| 16 | +|-------|---------|-------------|-----------| |
| 17 | +| Pre-graduation | Pump | Bonding curve (virtual reserves) | Single-sided (SOL only) | |
| 18 | +| Post-graduation | PumpAMM | Constant product (x·y=k) | Two-sided (SOL + token) | |
| 19 | + |
| 20 | +Check graduation status: |
| 21 | + |
| 22 | +```typescript |
| 23 | +const bondingCurve = await onlineSdk.fetchBondingCurve(mint); |
| 24 | +if (bondingCurve.complete) { |
| 25 | + // Token has graduated — use AMM methods |
| 26 | +} |
| 27 | +``` |
| 28 | + |
| 29 | +--- |
| 30 | + |
| 31 | +## Trading |
| 32 | + |
| 33 | +### Buy (Specify Token Output) |
| 34 | + |
| 35 | +Buy a specific amount of tokens, with a maximum SOL you're willing to spend. |
| 36 | + |
| 37 | +```typescript |
| 38 | +import { PUMP_SDK } from "@nirholas/pump-sdk"; |
| 39 | +import BN from "bn.js"; |
| 40 | + |
| 41 | +const ix = await PUMP_SDK.ammBuyInstruction({ |
| 42 | + user: walletPublicKey, |
| 43 | + pool: poolAddress, // Pool PDA for this token |
| 44 | + mint: tokenMint, |
| 45 | + baseAmountOut: new BN(1_000_000), // Tokens to receive |
| 46 | + maxQuoteAmountIn: new BN(100_000), // Max SOL (lamports) to spend |
| 47 | + cashback: false, // Optional: earn cashback |
| 48 | +}); |
| 49 | +``` |
| 50 | + |
| 51 | +### Buy (Specify SOL Input) |
| 52 | + |
| 53 | +Spend an exact amount of SOL, with a minimum token output. |
| 54 | + |
| 55 | +```typescript |
| 56 | +const ix = await PUMP_SDK.ammBuyExactQuoteInInstruction({ |
| 57 | + user: walletPublicKey, |
| 58 | + pool: poolAddress, |
| 59 | + mint: tokenMint, |
| 60 | + quoteAmountIn: new BN(100_000), // Exact SOL (lamports) to spend |
| 61 | + minBaseAmountOut: new BN(900_000), // Minimum tokens to receive |
| 62 | + cashback: false, |
| 63 | +}); |
| 64 | +``` |
| 65 | + |
| 66 | +### Sell |
| 67 | + |
| 68 | +Sell tokens for SOL with a minimum output guarantee. |
| 69 | + |
| 70 | +```typescript |
| 71 | +const ix = await PUMP_SDK.ammSellInstruction({ |
| 72 | + user: walletPublicKey, |
| 73 | + pool: poolAddress, |
| 74 | + mint: tokenMint, |
| 75 | + baseAmountIn: new BN(1_000_000), // Tokens to sell |
| 76 | + minQuoteAmountOut: new BN(90_000), // Minimum SOL (lamports) to receive |
| 77 | + cashback: false, |
| 78 | +}); |
| 79 | +``` |
| 80 | + |
| 81 | +--- |
| 82 | + |
| 83 | +## Liquidity Provision |
| 84 | + |
| 85 | +### Deposit (Add Liquidity) |
| 86 | + |
| 87 | +Provide both tokens and SOL to earn LP tokens. |
| 88 | + |
| 89 | +```typescript |
| 90 | +const ix = await PUMP_SDK.ammDepositInstruction({ |
| 91 | + user: walletPublicKey, |
| 92 | + pool: poolAddress, |
| 93 | + mint: tokenMint, |
| 94 | + maxBaseAmountIn: new BN(1_000_000), // Max tokens to deposit |
| 95 | + maxQuoteAmountIn: new BN(100_000), // Max SOL to deposit |
| 96 | + minLpTokenAmountOut: new BN(50_000), // Minimum LP tokens to receive |
| 97 | +}); |
| 98 | +``` |
| 99 | + |
| 100 | +### Withdraw (Remove Liquidity) |
| 101 | + |
| 102 | +Burn LP tokens to receive tokens and SOL back. |
| 103 | + |
| 104 | +```typescript |
| 105 | +const ix = await PUMP_SDK.ammWithdrawInstruction({ |
| 106 | + user: walletPublicKey, |
| 107 | + pool: poolAddress, |
| 108 | + mint: tokenMint, |
| 109 | + lpTokenAmountIn: new BN(50_000), // LP tokens to burn |
| 110 | + minBaseAmountOut: new BN(900_000), // Minimum tokens to receive |
| 111 | + minQuoteAmountOut: new BN(80_000), // Minimum SOL to receive |
| 112 | +}); |
| 113 | +``` |
| 114 | + |
| 115 | +--- |
| 116 | + |
| 117 | +## Creator Fee Management |
| 118 | + |
| 119 | +### Collect Creator Fees |
| 120 | + |
| 121 | +Token creators collect accumulated trading fees from the AMM pool. |
| 122 | + |
| 123 | +```typescript |
| 124 | +const ix = await PUMP_SDK.ammCollectCoinCreatorFeeInstruction({ |
| 125 | + creator: creatorWallet, |
| 126 | +}); |
| 127 | +``` |
| 128 | + |
| 129 | +### Transfer Creator Fees to Pump |
| 130 | + |
| 131 | +Move creator fees from the AMM pool back to the Pump program for distribution. |
| 132 | + |
| 133 | +```typescript |
| 134 | +const ix = await PUMP_SDK.ammTransferCreatorFeesToPumpInstruction({ |
| 135 | + coinCreator: creatorWallet, |
| 136 | +}); |
| 137 | +``` |
| 138 | + |
| 139 | +### Set Coin Creator |
| 140 | + |
| 141 | +Set the creator for an AMM pool based on bonding curve metadata. |
| 142 | + |
| 143 | +```typescript |
| 144 | +const ix = await PUMP_SDK.ammSetCoinCreatorInstruction({ |
| 145 | + pool: poolAddress, |
| 146 | + mint: tokenMint, |
| 147 | +}); |
| 148 | +``` |
| 149 | + |
| 150 | +### Migrate Pool Coin Creator |
| 151 | + |
| 152 | +Update the pool's creator based on the fee sharing config. |
| 153 | + |
| 154 | +```typescript |
| 155 | +const ix = await PUMP_SDK.ammMigratePoolCoinCreatorInstruction({ |
| 156 | + pool: poolAddress, |
| 157 | + mint: tokenMint, |
| 158 | +}); |
| 159 | +``` |
| 160 | + |
| 161 | +--- |
| 162 | + |
| 163 | +## Volume Tracking |
| 164 | + |
| 165 | +### Sync User Volume Accumulator |
| 166 | + |
| 167 | +Sync a user's volume tracking data between the Pump and PumpAMM programs. |
| 168 | + |
| 169 | +```typescript |
| 170 | +const ix = await PUMP_SDK.ammSyncUserVolumeAccumulatorInstruction(userPublicKey); |
| 171 | +``` |
| 172 | + |
| 173 | +### Claim AMM Cashback |
| 174 | + |
| 175 | +Claim cashback earned from AMM trading volume. |
| 176 | + |
| 177 | +```typescript |
| 178 | +const ix = await PUMP_SDK.ammClaimCashbackInstruction({ |
| 179 | + user: walletPublicKey, |
| 180 | +}); |
| 181 | +``` |
| 182 | + |
| 183 | +--- |
| 184 | + |
| 185 | +## AMM Events |
| 186 | + |
| 187 | +All AMM events can be decoded from transaction logs: |
| 188 | + |
| 189 | +```typescript |
| 190 | +const buyEvent = PUMP_SDK.decodeAmmBuyEvent(eventData); |
| 191 | +const sellEvent = PUMP_SDK.decodeAmmSellEvent(eventData); |
| 192 | +const depositEvent = PUMP_SDK.decodeDepositEvent(eventData); |
| 193 | +const withdrawEvent = PUMP_SDK.decodeWithdrawEvent(eventData); |
| 194 | +const createPoolEvent = PUMP_SDK.decodeCreatePoolEvent(eventData); |
| 195 | +``` |
| 196 | + |
| 197 | +### AmmBuyEvent Fields |
| 198 | + |
| 199 | +| Field | Type | Description | |
| 200 | +|-------|------|-------------| |
| 201 | +| `baseAmountOut` | `BN` | Tokens received | |
| 202 | +| `quoteAmountIn` | `BN` | SOL spent (before fees) | |
| 203 | +| `userQuoteAmountIn` | `BN` | SOL spent (after fees) | |
| 204 | +| `lpFee` | `BN` | Fee to LP providers | |
| 205 | +| `protocolFee` | `BN` | Fee to protocol | |
| 206 | +| `coinCreatorFee` | `BN` | Fee to token creator | |
| 207 | +| `cashback` | `BN` | Cashback earned | |
| 208 | +| `pool` | `PublicKey` | Pool address | |
| 209 | +| `user` | `PublicKey` | Buyer address | |
| 210 | + |
| 211 | +### AmmSellEvent Fields |
| 212 | + |
| 213 | +| Field | Type | Description | |
| 214 | +|-------|------|-------------| |
| 215 | +| `baseAmountIn` | `BN` | Tokens sold | |
| 216 | +| `quoteAmountOut` | `BN` | SOL received (before fees) | |
| 217 | +| `userQuoteAmountOut` | `BN` | SOL received (after fees) | |
| 218 | +| `lpFee` | `BN` | Fee to LP providers | |
| 219 | +| `protocolFee` | `BN` | Fee to protocol | |
| 220 | +| `coinCreatorFee` | `BN` | Fee to token creator | |
| 221 | +| `cashback` | `BN` | Cashback earned | |
| 222 | + |
| 223 | +--- |
| 224 | + |
| 225 | +## Finding Pool Addresses |
| 226 | + |
| 227 | +Use the `OnlinePumpSdk` to look up pool addresses: |
| 228 | + |
| 229 | +```typescript |
| 230 | +import { OnlinePumpSdk } from "@nirholas/pump-sdk"; |
| 231 | + |
| 232 | +const onlineSdk = new OnlinePumpSdk(connection); |
| 233 | +const pool = await onlineSdk.fetchPool(mint); |
| 234 | +``` |
| 235 | + |
| 236 | +Or derive the pool PDA: |
| 237 | + |
| 238 | +```typescript |
| 239 | +import { poolPda } from "@nirholas/pump-sdk"; |
| 240 | + |
| 241 | +const [poolAddress] = poolPda(mint); |
| 242 | +``` |
| 243 | + |
| 244 | +--- |
| 245 | + |
| 246 | +## Slippage Protection |
| 247 | + |
| 248 | +All AMM methods include slippage parameters: |
| 249 | + |
| 250 | +- **Buy:** `maxQuoteAmountIn` caps the SOL spent |
| 251 | +- **Buy exact:** `minBaseAmountOut` guarantees minimum tokens |
| 252 | +- **Sell:** `minQuoteAmountOut` guarantees minimum SOL |
| 253 | +- **Deposit:** `minLpTokenAmountOut` guarantees minimum LP tokens |
| 254 | +- **Withdraw:** `minBaseAmountOut` + `minQuoteAmountOut` guarantee minimums |
| 255 | + |
| 256 | +Set these based on your slippage tolerance. For a 1% slippage: |
| 257 | + |
| 258 | +```typescript |
| 259 | +const slippageBps = 100; // 1% |
| 260 | +const minOutput = expectedOutput.mul(new BN(10000 - slippageBps)).div(new BN(10000)); |
| 261 | +``` |
| 262 | + |
| 263 | +--- |
| 264 | + |
| 265 | +## Related |
| 266 | + |
| 267 | +- [Bonding Curve Math](./guides/bonding-curve-math.md) — Pre-graduation pricing |
| 268 | +- [Fee Tiers](./fee-tiers.md) — Fee structure across tiers |
| 269 | +- [Cashback](./cashback.md) — Cashback system |
| 270 | +- [Events Reference](./events-reference.md) — Complete event catalog |
| 271 | +- [Tutorial 34](../tutorials/34-amm-liquidity-operations.md) — Step-by-step AMM guide |
0 commit comments