Pump.fun Graduation Sniping: Buying the Move to PumpSwap
How Pump.fun graduation works: the curve's numbers, the move to PumpSwap, how fast the pool opens, why sniping it is hard, and a script to check a token.
Only some Pump.fun tokens sell out their bonding curve. Those that do graduate: their SOL and the tokens held back move into a PumpSwap pool, and trading carries on there. Graduation sniping means buying at that moment, in the new pool.
This guide covers the numbers behind a graduation, worked out from Pump.fun's own on-chain settings, what happens on-chain, how fast the pool opens and what prices did next in the graduations we pulled, why sniping it is hard, and a script that shows how close any token is to graduating. No promises: a graduated token can still go to zero.
Disclosure: AllenHark sells the Solana Graduation Sniper described here. Nothing in this guide is financial advice.
The short answer
- A token graduates when its curve sells out: about 85 SOL of buying with today's settings, before fees.
- The PumpSwap pool opens at the curve's last price, a market cap of about 411 SOL. Its dollar value moves with the SOL price.
- It opens fast. In the 19 graduations we pulled on October 31, 2026, the pool opened 0 to 5 slots after the curve completed.
- It's crowded. In half the ordinary graduations, a buy landed in the very next transaction after the pool was created.
- Many fall soon after. Of 12 ordinary pools we re-read within the hour, 9 were below their opening price.
What graduation means on Pump.fun
Pump.fun prices a new token on a bonding curve: Pump's program docs describe Uniswap V2 maths on a virtual pile of SOL and a virtual pile of tokens. Every buy adds SOL and takes tokens out, so the price climbs.
Only part of the supply is for sale. When a buy takes the last of it, the curve is marked complete, and every trade on it fails with BondingCurveComplete until the token is migrated (Pump's docs). The migration moves the curve's SOL, minus a small fee, and the tokens never offered for sale into a new PumpSwap pool. Pump's docs say the pool's LP tokens are burnt.
The numbers behind a graduation
Every new curve starts from values in Pump.fun's Global account. We read it on mainnet on October 31, 2026 (slot 463,778,596):
| Global field | Value |
|---|---|
initial_virtual_token_reserves | 1,073,000,000 tokens |
initial_virtual_sol_reserves | 30 SOL |
initial_real_token_reserves (for sale on the curve) | 793,100,000 tokens |
token_total_supply | 1,000,000,000 tokens |
pool_migration_fee (Pump's docs: pays for the accounts the migration creates) | 0.015000001 SOL |
The constant-product maths on those values, before fees:
| Curve tokens sold | SOL in the curve | Price vs launch | Market cap |
|---|---|---|---|
| 0 % (launch) | 0 | 1x | 28 SOL |
| 25 % | 6.8 | 1.5x | 42 SOL |
| 50 % | 17.6 | 2.5x | 70 SOL |
| 75 % | 37.3 | 5x | 141 SOL |
| 90 % | 59.6 | 8.9x | 249 SOL |
| 100 % (complete) | 85.005 | 14.7x | 411 SOL |
Market cap here is price times the 1 billion supply, in SOL.
- The pool gets 84.99 SOL and 206.9 million tokens: the curve's 85.005 SOL minus the migration fee, and the 20.69 % of the supply never offered for sale. 9 of the 12 ordinary pools we pulled opened with 206.9 million tokens and 84.990 SOL.
- The price carries straight on. The curve's last price is 4.1088e-7 SOL per token; the pool opens at 4.1078e-7, 0.02 % lower.
- "50 %" is a long way off. Half the tokens sell for about 17.6 SOL; the second half takes about 67.4 SOL more.
- Fees come on top, so buyers spend somewhat more than 85 SOL in total.
Pump.fun can change these values, so the script below reads them live. Mayhem Mode coins start from other values, and coins paired with USDC or another coin use other amounts. The first buyer's side of the same curve is in Pump.fun bonding curve sniping explained.
What happens on-chain
1. The completing buy
The buy that empties the curve emits a CompleteEvent after its TradeEvent (Pump.fun IDL). It's the earliest on-chain sign of a graduation.
With Pump's newer v3 buys, that buy can ask for more than the curve has left. In this synthetic migration it buys the rest from the tokens bound for the pool, at the pool's price, and emits PostCompleteBuyEvent with the reserves the pool will open with. 3 of our 12 ordinary graduations went this way, opening up to 2.3 % higher.
2. The gap
Until the migration, the token can't be traded anywhere, and buys aimed at the curve fail. In one graduation we pulled, 40 transactions that touched the curve failed between the completing buy and the migration two slots later. A failed transaction still pays its fee (Solana docs).
3. migrate or migrate_v2
| Instruction | Discriminator | Handles |
|---|---|---|
migrate | [155, 234, 231, 146, 236, 158, 162, 30] | SOL-paired coins (wrapped SOL is fixed in its accounts) |
migrate_v2 | [187, 203, 18, 31, 206, 237, 254, 41] | Any quote mint |
Anyone can call them. Pump's docs call migrate permissionless and idempotent. In the IDL the only signer is user, and the withdraw_authority account just has to match Global's. On a curve that has already migrated, it does nothing.
On chain, 16 of our 19 graduations used migrate_v2. One account migrated 10 of them and 8 other wallets the rest, and 21 of the 40 migrate transactions we pulled created no pool: repeats on curves just migrated, or failures.
4. The pool
Inside the migrate, Pump.fun calls PumpSwap's create_pool by CPI and logs a CompletePumpAmmMigrationEvent with the mint, pool, tokens, SOL and fee. Yesterday's guide to detecting new tokens and pools has the account positions and gRPC code.
The pool's address is fixed in advance: a PumpSwap PDA of "pool", index 0 as two bytes, the token's pool authority (a Pump.fun PDA of "pool-authority" and the mint), the mint and the quote mint. That derivation matched all 19 pools we pulled. So when a CompleteEvent lands, you already know the pool's address and, for an ordinary graduation, its opening reserves.
If you read pool sizes, know this: in all 13 non-Mayhem migrations we pulled, the transaction also emitted PumpSwap's InitBoostEvent. In the 12 SOL-paired ones, it shows the pool's vault holding about 67.4 SOL and the other 17.6 SOL booked as virtual_quote_reserves, the extra amount Pump's docs say a boosted pool carries; in the transactions we checked, that 17.6 SOL sat in a separate account. The price is unchanged, because Pump's docs price a pool on the vault plus virtual_quote_reserves. But the vault holds less real SOL than the price implies.
How fast the pool opens
We pulled the 19 most recent graduations on October 31, 2026, about 26 minutes' worth, and compared each completing buy's slot with the migration's:
| Slots from completing buy to migration | Graduations |
|---|---|
| 0 (same slot) | 7 |
| 1 | 3 |
| 2 | 7 |
| 4 | 1 |
| 5 | 1 |
A slot is about 200 ms, so every pool opened within about a second. Twice, a program ran the migrate and then its own buy on the new pool in one transaction.
12 of the 19 were ordinary SOL-paired coins. Six were Mayhem Mode coins: the five paired with SOL opened pools holding just 0.09 to 0.44 SOL, and one was paired with USDC. One was paired with another Pump.fun coin.
What prices did next
We re-read the 12 ordinary pools 20 to 43 minutes after each opened. All had opened at a market cap of 411 to 420 SOL:
- 9 were below their opening price, 8 of them by more than half.
- 6 had lost about 95 %, to a market cap of 18 to 21 SOL, with 0.3 to 2.1 SOL of real SOL left in their vaults.
- 3 were above it.
One half hour isn't a statistic, but it matches our Graduation Sniper guide: many graduated tokens fall right after.
Why snipe graduations, and why it's hard
The appeal: you skip the curve phase, where most tokens die; every ordinary graduation had about 85 SOL of buying behind it; and the opening price and pool address are known in advance.
The catch:
- Everyone sees the same moment. In 6 of the 12 ordinary graduations, the next transaction after the migration, in the same block, was a buy on the new pool from another wallet. In the migration's block and the next, 172 transactions touched those 12 pools, and 84 failed.
- Early holders can sell into you. The creator and the curve's buyers can sell the moment the pool opens.
- Pools can be thin, or drained fast. Mayhem Mode pools opened with under 0.5 SOL, and half our ordinary pools lost about 95 % within the hour.
- Speed doesn't fix the token. Landing first only pays if buyers keep coming after you.
Filters that matter
| Filter | Why |
|---|---|
| Pool size | Thin pools swing on every trade; a floor also skips Mayhem Mode pools |
| How late you'd be | A graduation seen several slots late is already crowded |
| Your buy vs the pool | A big buy in a small pool moves the price against your entry and your exit |
| Creator's share | A big creator bag is a big seller at the open |
| Time on the curve | A very fast fill can be coordinated; a very slow one can mean few buyers left |
| Holders | A handful of wallets can mean a coordinated launch |
| Quote and mode | USDC-paired, coin-paired and Mayhem Mode coins don't follow the usual numbers |
| Your limits | A budget, a daily loss limit and the most positions at once |
Other launchpads' graduations
From each launchpad's own docs:
| Launchpad | Graduates when | Moves to | Who migrates |
|---|---|---|---|
| Pump.fun | Real token reserves hit zero | PumpSwap | Anyone |
| Raydium LaunchLab | The quote vault reaches the threshold set at launch | CPMM for every new launch; AMM v4 only for older ones set up that way | Only the migration wallet in LaunchLab's GlobalConfig |
| Meteora DBC | The quote reserve reaches its config's migration_quote_threshold | DAMM v2 for new configs and pools; DAMM v1 only for pools already set up for it | Meteora runs a migration keeper on mainnet |
LaunchLab and DBC thresholds are set per launch or per config, so there's no single "85 SOL" to watch. And on LaunchLab only Raydium's wallet can migrate, so no bot can migrate and buy in one transaction, as one program did twice on Pump.fun in our sample. Sources: Raydium's LaunchLab overview, GlobalConfig and instructions; Meteora's DBC migration docs.
Check a token's curve: a Node.js script
Give it a token's mint address (its CA) and it shows the share of the curve's tokens sold, the SOL in the curve and still needed, the price and the market cap in SOL. Once the curve is complete, it finds the PumpSwap pool. It only reads public data.
You need Node.js (we tested on version 24) and web3.js version 1 (we tested 1.99.0):
mkdir curve-check && cd curve-check
npm init -y
npm install @solana/web3.js@1
# save the script below as curve-progress.mjs, then:
node curve-progress.mjs <MINT>// curve-progress.mjs: how close a Pump.fun token is to graduating, and its PumpSwap pool once it has.
// Usage: node curve-progress.mjs <MINT>
// Env: RPC_URL (default: Solana's public mainnet endpoint). Read-only: it sends nothing.
import { Connection, PublicKey } from "@solana/web3.js";
const RPC_URL = process.env.RPC_URL ?? "https://api.mainnet.solana.com";
const PUMP = new PublicKey("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P");
const PUMPSWAP = new PublicKey("pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA");
const WSOL = new PublicKey("So11111111111111111111111111111111111111112");
// Anchor account discriminators, from Pump's IDLs
const CURVE_DISC = Buffer.from([23, 183, 248, 55, 96, 216, 172, 96]); // pump: BondingCurve
const POOL_DISC = Buffer.from([241, 154, 109, 4, 17, 177, 109, 188]); // pump_amm: Pool
let mint;
try {
mint = new PublicKey(process.argv[2]);
} catch {
console.error("Usage: node curve-progress.mjs <MINT>");
process.exit(1);
}
const rpc = new Connection(RPC_URL, "confirmed");
const pda = (seeds, program) => PublicKey.findProgramAddressSync(seeds, program)[0];
const u64 = (buf, o) => (o + 8 <= buf.length ? buf.readBigUInt64LE(o) : 0n); // older, shorter accounts read as 0
const key = (buf, o) => (o + 32 <= buf.length ? new PublicKey(buf.subarray(o, o + 32)) : PublicKey.default);
const fmt = (n, d = 4) => n.toLocaleString("en-US", { maximumFractionDigits: d });
// PDAs, with the seeds in Pump's IDL
const curveKey = pda([Buffer.from("bonding-curve"), mint.toBuffer()], PUMP);
const globalKey = pda([Buffer.from("global")], PUMP);
// One call for the bonding curve, Pump's Global account and the mint
const [curveAcc, globalAcc, mintAcc] = await rpc.getMultipleAccountsInfo([curveKey, globalKey, mint]);
if (!curveAcc?.owner.equals(PUMP) || !curveAcc.data.subarray(0, 8).equals(CURVE_DISC)) {
console.error(`No Pump.fun bonding curve for ${mint.toBase58()} (looked at ${curveKey.toBase58()})`);
process.exit(1);
}
// BondingCurve fields, in the IDL's order (after the 8-byte discriminator)
const c = curveAcc.data;
const curve = {
virtualTokens: u64(c, 8),
virtualQuote: u64(c, 16),
realTokens: u64(c, 24),
realQuote: u64(c, 32),
complete: c[48] === 1,
mayhem: c[81] === 1,
quoteMint: key(c, 83), // Pubkey::default() means paired with SOL
};
// Global: initial_real_token_reserves comes after a bool, two pubkeys and two u64s
const initialRealTokens = u64(globalAcc.data, 8 + 1 + 32 + 32 + 8 + 8);
const solPaired = curve.quoteMint.equals(PublicKey.default);
const quoteMint = solPaired ? WSOL : curve.quoteMint;
const tokenDecimals = mintAcc.data[44]; // a mint's decimals byte (SPL Token and Token-2022)
const supply = mintAcc.data.readBigUInt64LE(36); // the mint's current supply
let quoteDecimals = 9;
let unit = "SOL";
if (!solPaired) {
quoteDecimals = (await rpc.getAccountInfo(quoteMint)).data[44];
unit = `${quoteMint.toBase58().slice(0, 4)}…`;
}
const tok = (raw) => Number(raw) / 10 ** tokenDecimals;
const qt = (raw) => Number(raw) / 10 ** quoteDecimals;
const mcap = (price) => `${fmt(price * tok(supply), 2)} ${unit}`;
console.log(`Mint ${mint.toBase58()}`);
console.log(`Bonding curve ${curveKey.toBase58()}${curve.mayhem ? " (Mayhem Mode)" : ""}`);
console.log(`Paired with ${solPaired ? "SOL" : quoteMint.toBase58()}`);
console.log(`Complete ${curve.complete}`);
if (curve.virtualTokens > 0n) {
// Still on the curve, or complete and waiting for migrate. Constant product on the virtual reserves.
const price = qt(curve.virtualQuote) / tok(curve.virtualTokens);
const progress = (Number(initialRealTokens - curve.realTokens) / Number(initialRealTokens)) * 100;
// What buying every real token left costs, before fees: k / (virtual tokens - real tokens) - virtual quote
const k = curve.virtualQuote * curve.virtualTokens;
const toGo = curve.realTokens > 0n ? k / (curve.virtualTokens - curve.realTokens) - curve.virtualQuote : 0n;
// Mayhem Mode coins start from other values than Global's, so a percentage would be wrong for them
if (!curve.mayhem) console.log(`Progress ${fmt(progress, 2)} % of the curve's tokens sold`);
console.log(`Tokens left ${fmt(tok(curve.realTokens), 0)}`);
console.log(`In the curve ${fmt(qt(curve.realQuote))} ${unit}`);
console.log(`To graduate about ${fmt(qt(toGo))} ${unit} more buying, before fees`);
console.log(`Price ${price.toExponential(4)} ${unit} per token`);
console.log(`Market cap ${mcap(price)}`);
}
if (!curve.complete) process.exit(0);
// Complete: find the canonical PumpSwap pool. Seeds from the IDL's migrate accounts:
// pool_authority = ["pool-authority", mint] on Pump; pool = ["pool", index 0 as u16, pool_authority, mint, quote mint] on PumpSwap
const poolAuthority = pda([Buffer.from("pool-authority"), mint.toBuffer()], PUMP);
const poolKey = pda([Buffer.from("pool"), Buffer.alloc(2), poolAuthority.toBuffer(), mint.toBuffer(), quoteMint.toBuffer()], PUMPSWAP);
const poolAcc = await rpc.getAccountInfo(poolKey);
if (!poolAcc?.data.subarray(0, 8).equals(POOL_DISC)) {
console.log(`PumpSwap pool not created yet; it will be ${poolKey.toBase58()}`);
process.exit(0);
}
// Pool fields, in the IDL's order: the two vaults, then virtual_quote_reserves (i128) at byte 245
const p = poolAcc.data;
const [baseAcc, quoteAcc] = await rpc.getMultipleAccountsInfo([key(p, 139), key(p, 171)]);
const baseReserve = baseAcc.data.readBigUInt64LE(64); // token account amount
const vqr = p.length >= 261 ? (p.readBigInt64LE(253) << 64n) + p.readBigUInt64LE(245) : 0n;
// Pump's docs: price on the effective quote reserves, the vault balance plus virtual_quote_reserves (signed)
const vault = quoteAcc.data.readBigUInt64LE(64);
const quoteReserve = vault + vqr;
const poolPrice = qt(quoteReserve) / tok(baseReserve);
console.log(`PumpSwap pool ${poolKey.toBase58()}`);
console.log(`Pool tokens ${fmt(tok(baseReserve), 0)}`);
console.log(`Pool ${unit.padEnd(9)} ${fmt(qt(quoteReserve))} for pricing: ${fmt(qt(vault))} in the vault, ${fmt(qt(vqr))} virtual`);
console.log(`Pool price ${poolPrice.toExponential(4)} ${unit} per token`);
console.log(`Market cap ${mcap(poolPrice)}`);Its output on October 31 for a token near the end of its curve, and for one that had graduated about 25 minutes earlier (addresses left out):
Mint <MINT>
Bonding curve <BONDING_CURVE>
Paired with SOL
Complete false
Progress 93.39 % of the curve's tokens sold
Tokens left 52,440,730
In the curve 66.8584 SOL
To graduate about 18.1469 SOL more buying, before fees
Price 2.9144e-7 SOL per token
Market cap 291.44 SOLMint <MINT>
Bonding curve <BONDING_CURVE>
Paired with SOL
Complete true
PumpSwap pool <POOL>
Pool tokens 979,415,471
Pool SOL 18.2705 for pricing: 0.686 in the vault, 17.5845 virtual
Pool price 1.8655e-8 SOL per token
Market cap 18.42 SOLIn the first, 66.86 SOL in the curve plus 18.15 to go is the table's 85.005. The second is one of the pools that lost about 95 %.
- "Progress" counts tokens, so the last half costs far more SOL than the first. Mayhem Mode coins get no percentage.
- "Market cap" uses the mint's current supply, so burnt tokens don't count.
- "Complete true" with no pool means the migration hasn't landed yet, a second at most in our sample.
- "Pool SOL" splits what the pool prices on into real SOL in the vault and the virtual part.
How we tested it. We ran it read-only on Solana's public endpoint on October 31, 2026, on curves still trading (SOL-paired, Mayhem Mode, and paired with another token) and on seven graduated tokens (ordinary, synthetic migration, Mayhem Mode with SOL and with USDC, and coin-paired). Every pool it derived was the pool in the real migration, and on one curve "Tokens left" matched its latest trade event exactly. Run again later, the near-complete token above had graduated, and the script found its pool. The "pool not created yet" branch lasts too briefly to catch live.
The public endpoint is rate-limited and not meant for bots; the script makes one to four calls a run. For more, set RPC_URL to your own endpoint, such as AllenHark RPC.
Watching for graduations
To see every graduation as it lands, watch the account every migrate must pass, Global's withdraw_authority, over an RPC WebSocket:
// graduation-watch.mjs: print each Pump.fun graduation (a new PumpSwap pool) as it happens.
// Usage: node graduation-watch.mjs Env: RPC_URL (its WebSocket is used too). Read-only.
import { Connection, PublicKey } from "@solana/web3.js";
const RPC_URL = process.env.RPC_URL ?? "https://api.mainnet.solana.com";
const PUMP = new PublicKey("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P");
// CompletePumpAmmMigrationEvent's discriminator, from Pump's IDL
const MIGRATED = Buffer.from([189, 233, 93, 185, 92, 148, 234, 148]);
const rpc = new Connection(RPC_URL, "processed");
// Every migrate and migrate_v2 must pass Global's withdraw_authority, so watch that account
const [globalKey] = PublicKey.findProgramAddressSync([Buffer.from("global")], PUMP);
const global = (await rpc.getAccountInfo(globalKey)).data;
const withdrawAuthority = new PublicKey(global.subarray(113, 145));
console.log(`Watching migrations through ${withdrawAuthority.toBase58()}`);
const seen = new Set(); // a processed transaction can be delivered more than once
rpc.onLogs(withdrawAuthority, ({ err, logs, signature }, { slot }) => {
if (err) return; // a failed migrate
for (const line of logs) {
if (!line.startsWith("Program data: ")) continue;
const d = Buffer.from(line.slice(14), "base64");
if (!d.subarray(0, 8).equals(MIGRATED)) continue; // a repeat migrate on a done curve logs no event
// Event fields, in the IDL's order
const key = (o) => new PublicKey(d.subarray(o, o + 32)).toBase58();
const mint = key(40);
if (seen.has(mint)) continue;
seen.add(mint);
const tokens = Number(d.readBigUInt64LE(72)) / 1e6; // Pump.fun coins have 6 decimals
const quoteIn = d.readBigUInt64LE(80); // lamports for SOL-paired coins
const pool = key(136);
const quote = d.length >= 200 ? key(168) : PublicKey.default.toBase58();
const paired = quote === PublicKey.default.toBase58() ? `${(Number(quoteIn) / 1e9).toFixed(3)} SOL` : `${quoteIn} base units of ${quote}`;
console.log(`slot ${slot} graduated mint=${mint} pool=${pool} with ${tokens.toLocaleString("en-US")} tokens and ${paired} tx=${signature}`);
}
}, "processed");Its decoder read the logs of all 19 migrations we pulled with every mint and pool right, and live on the public endpoint it printed graduations as they landed; the de-duplication is there because one transaction arrived twice. It's a demo: the WebSocket reports the migration once it has executed, while the earlier CompleteEvent needs every Pump.fun trade, a job for Yellowstone gRPC or shreds. See Detect new Pump.fun tokens and pools in real time.
The AllenHark Solana Graduation Sniper
The Solana Graduation Sniper buys tokens as they graduate, in their new pool, if the pool and the launch pass your checks, then sells by your rules. It suits traders who would rather skip the first minutes of a launch.
- Launchpads: Pump.fun to PumpSwap; Raydium LaunchLab, with Bonk.fun, StonkFun and Surge, to CPMM or AMM v4; Meteora DBC, with Bags, Moonshot, Jupiter Studio and Believe, to DAMM v2. DAMM v1 graduations are skipped for now.
- Seeing graduations: your server's connection to the AllenHark market feed, over QUIC, carries every graduation with the new pool's first state. Like every AllenHark bot, it detects in 0.2 ms.
- Checks: pool size, how late the graduation reached it, the creator's share, time on the launchpad, holders (Advanced), your blocklist and your limits. Every skip shows its reason.
- Buying: your buy size, capped at the share of the pool you allow. It re-reads the pool right before buying and sets slippage from that read; if the price moves further, the buy doesn't go through and you pay only the network fee.
- Sending: through AllenHark Relay by default, same block at 0.1 ms over QUIC. You can add your own fast senders in Advanced.
- Selling: your TP/SL, gains protected on the way down, a time limit, and a sell if the creator sells while it holds the token.
Style sets the guards:
| Setting | Safer | Balanced | Riskier |
|---|---|---|---|
| New pool holds at least | 40 SOL | 20 SOL | 10 SOL |
| Buy at most this share of the pool | 1 % | 2 % | 3 % |
| Graduation seen within | 2 slots | 4 slots | 8 slots |
| Tokens held at once | 2 | 5 | 8 |
| Sells what's left after | 30 min | 1 hour | 2 hours |
Every Style's floor skips the Mayhem Mode pools we saw. The Balanced starter, which a new bot starts with: "Pools with 20 SOL or more. Sells half at 2x and lets the rest ride, out after an hour." The guide explains every setting, and the settings reference lists each range.
It's non-custodial: it runs on your own server and your key stays there. Plans are monthly: see the bot's page for the price, and all AllenHark bots.
Practice mode first
A new Graduation Sniper starts in practice: it buys real graduations with virtual SOL (10 SOL to start), sends nothing, and counts the pool's fee, slippage and the network fee. Watch which graduations your filters skip, how your exits handle the ones that fall, and your practice PnL, then go live small, with SOL in your bot wallet and your PIN. You can switch back at any time. See the quick start, or try the demo in your browser.
Practice is a guide, not a forecast: it can't know how other bots would react to your live buys.
The risks, plainly
- Many graduated tokens fall right after. 9 of our 12 ordinary pools were below their open within the hour.
- Early holders can sell into you, and a token can pass every filter and still drop sharply.
- Your buy can land late or fail, and a failed transaction still pays its fee.
- A small pool moves a lot, on your buy and your sell.
- A stop loss limits most losses, not all. Prices can gap between two checks.
- The numbers can change. Pump.fun can change its settings; other launchpads set theirs per launch.
Only trade SOL you can afford to lose. Read the risk disclosure and Limits and safety, and see Troubleshooting if the bot isn't buying.
FAQ
How much SOL does a Pump.fun token need to graduate?
With the settings we read on October 31, 2026, about 85 SOL of buying, before fees. The pool opens with 84.99 SOL and 206.9 million tokens, at a market cap of about 411 SOL. Mayhem Mode and non-SOL pairs differ.
How fast does the PumpSwap pool open?
In the 19 graduations we pulled, 0 to 5 slots after the completing buy, about a second at most.
Who migrates a Pump.fun token to PumpSwap?
Anyone: migrate and migrate_v2 are permissionless, and a second call does nothing.
Do graduated tokens go up?
Some do; most in our sample didn't. Nobody can promise a profit, and AllenHark doesn't.
How can I see a token's bonding curve progress?
Run the script above with its mint address.
Related reading
- Solana Graduation Sniper guide
- Detect new Pump.fun tokens and pools in real time
- Pump.fun bonding curve sniper bot: block 0 and real trading
Sources
Checked October 31, 2026.
- Pump: program docs, PumpSwap docs, synthetic migration, virtual quote reserves, and the current pump.json and pump_amm.json IDLs
- Raydium: LaunchLab overview, GlobalConfig, instructions
- Meteora: DBC migration and liquidity, DBC instructions
- Solana: fee structure
- Mainnet: our read-only pulls on October 31, 2026: Pump.fun's
Globalaccount; the 40 latest migrate transactions (19 graduations), each completing buy and the failures before the migration; the first two blocks of the 12 ordinary pools; and those pools 20 to 43 minutes later - AllenHark: the Graduation Sniper guide and settings, the risk disclosure
