A pump.fun launchpad on Solana. Every coin carries the same engine: buy fees become a zcash reserve held in the program, sell fees pay whoever still holds, any holder can burn for a share of the reserve, a quiet coin is liquidated to its last holders.
- overview
- the transactions, step by step
- worked example
- parameters
- payouts: sol and xmr
- program reference
- errors
- verify it yourself
- what the admin can and cannot do
- trust points
- risks
- audit
- faq
overview
creator fee ## .....>.....> every buy ..> (z) zec reserve held in the program
:.....>.....> every sell ..> (s|x) sol or xmr to holders pro rata
burn .....> (f) floor redeem x / circulating of the reserve
quiet window .....> liquidate the whole reserve to the last holders
- The coin's pump.fun creator is a program address (
["vault", mint]), not the dev. The dev earns nothing from fees, ever. - No trusted keeper decides which side paid a fee.
observederives buy and sell volume from the fee accrual and the curve's sol movement (see step 2). Anyone can call it. - The reserve is ZEC held by the program: the Solana SPL token of Zcash (mint
A7bdiYdS5GjqGFtxf17ppRHtDKPkkRqbKtR27dxvQXaS), bought on the deepest direct pool, Orca Whirlpool2TAgfogn8JRwwTnsGKUa6WUT5Xdv1iMEzfEDMor68X9C(WSOL / ZEC). It sits in the token account of the coin's market PDA. No wallet can move it. - The homepage ranks coins by backing ratio = reserve value (at the ZEC median) / market cap, both read on chain, not by market cap.
- One registration covers the whole pad. Register a SOL payout (trustless merkle claim) or a Monero subaddress (sealed to the payout key, never written on chain in the clear).
the transactions, step by step
- launch(name, symbol, uri, dev_buy, dead_window_secs, dead_volume_lamports, expected_launch_fee_bps) · the dev signs. Creates the pump.fun coin with the vault PDA as creator, the Market account, the reserve (ZEC) and WSOL accounts of the market, and runs the first buy. Launch fee = 2.50 % of the first buy, to the treasury. Must be alone in its transaction (no snipe bundling). The picture must be an IPFS link.
- observe(mint) · anyone, at most once per 20 s per coin. Reads the fee pot F (vault + pump creator vault + PumpSwap creator WSOL, everything already moved out added back) and the quote reserve Q (curve real SOL, or the canonical PumpSwap pool after migration). Between two observations: gross volume
V = dF x 10000 / fee_bps(the creator fee bps of the current pump fee tier, read from pump's on-chain fee config), net flowN = dQ(minus the LP fee on PumpSwap), buy volume(V + N) / 2, sell volumeV - buy. The fee dF is split between the two counters in that proportion. It is exact when only one side traded in the interval and exact in aggregate otherwise. Dust swaps pay dust fees, so they cannot fake volume. After the migration, liquidity deposits and withdrawals on the PumpSwap pool are not trades: when the pool's LP supply changed in an interval, the net flow is rescaled and volume comes from fees only. - sweep(mint) · anyone, alone in its transaction, when the buy counter is above 0.25 SOL. Collects pump fees into the vault, wraps up to 5 SOL and swaps it on the Orca Whirlpool into the reserve. Refused if the pool's spot price is more than 2 % off the median of the program's last 7 ZEC price observations; minimum out = median quote minus 3 %.
- release(mint) · anyone (pays the Release rent), after an observation armed the trigger. Moves the sell counter's SOL into
Release ["release", mint, n]with the trigger slot. - post_root (payout authority) · the table: for every wallet registered as of the trigger slot, the smallest balance it held over the window before the trigger (1500 slots, ~10 min, ending with the trigger slot, the seller counted after the sale), program accounts excluded; share = floor(amount x holding / sum). A wallet that buys right before the trigger and sells right after holds 0 over the window and gets nothing. Leaf 0 is a header bound to this Release, so a root can never be replayed on another release. The table is published as JSON; its sha256 and CID are on chain.
- veto_root (guardian) · during the 1 h challenge window. A vetoed release needs a new root; the payout service only re-posts after the operator has looked at the veto and acknowledged it.
- claim_release(index, amount, proof) · anyone can send it; the SOL always goes to the leaf's wallet. Open after the challenge window, for 30 d.
- pull_xmr then attest_payout(batch, first_leaf, count, monero txid, sha256 of the tx proofs, sol in, xmr out) (payout authority) · the XMR leaves' total goes to the payout hot wallet, is swapped to Monero, paid in batches of at most 15 outputs, and every batch is attested on chain with its Monero txid and the hash of its per-output tx proofs (also after the release expired, so a slow Monero leg still leaves its receipts).
- expire_release · anyone, after the claim window: whatever is left goes back to the coin's buy counter (or its SOL reserve if dead). Never to an admin.
- redeem(amount, min_zec_out) · a holder burns
amountand receivesfloor(amount x reserve / circ_ref)ZEC minus the redeem fee (1.00 %, rounded up, stays in the reserve; 0 % once dead), plus the same share of the SOL reserve of a dead coin.circ_ref= max(circulating now, every circulating sample of the last 15 min); circulating = supply - curve tokens - pool tokens. Refused if the transaction also trades. - liquidate(mint) · anyone. Runs an observation, then checks that the coin is older than its dead window and that its gross volume over the last window is below its dead volume. Then: dead for good, sweeps and releases stop, both counters become the SOL reserve, redeem fee 0.
- register(kind, dest_hash, sealed_dest) / unregister · the wallet itself.
Reg ["reg", wallet], one per wallet for the whole pad.
worked example (mainnet defaults)
Pump's curve creator fee is 0.30 % of the quote amount of every trade (read from its fee config; PumpSwap tiers differ).
- Buys: 2 SOL buy pays 0.006 SOL of creator fee, all of it to the buy counter. After about 84 SOL of buys the counter holds 0.25 SOL and anyone can sweep: 0.25 SOL at 13.09 SOL per ZEC, minus the pool's 0.16 %, is about 0.01907 ZEC into the reserve.
- Sells: after about 167 SOL of sells the sell counter crosses 0.5 SOL. The observation that crossed it is the trigger. Holders over the ~10 min before that slot: A held at least 600m tokens (registered SOL), B at least 300m (registered XMR), C 100m (not registered), D bought 2b tokens one slot before the trigger and sold one slot after (registered). The table pays A 0.5 x 600/900 = 0.3333 SOL and B 0.1667 SOL worth of XMR. C is not in it; nothing is set aside for C. D's smallest holding over the window is 0, so D gets nothing.
- Redeem: the reserve holds 0.1 ZEC, 800m tokens circulate. Burning 8m (1 %) gives 0.001 ZEC gross, 0.00001 ZEC fee stays in, you receive 0.00099 ZEC.
- Liquidation: window 3 h, dead volume 0.8 SOL (~$100). If only 0.5 SOL traded over the last 3 h, anyone can liquidate; every remaining holder can then redeem pro rata with no fee, the SOL counters included.
parameters
Copied into every coin at launch; the admin can only change them for future coins. Live values from the chain replace these defaults when the page loads.
| launch fee | 2.50 % of the first buy (cap 5 %) |
|---|---|
| redeem fee | 1.00 % (cap 5 %), 0 % once dead |
| sweep threshold | 0.25 SOL (bounds 0.01 .. 10) |
| release threshold | 0.5 SOL (bounds 0.05 .. 50) |
| max per sweep | 5 SOL (bounds 0.1 .. 50) |
| zec price band / slippage | 2 % / 3 % |
| dead window | chosen at launch: 1 h, 3 h (default), 6 h, 12 h, 24 h or 72 h |
| dead volume | chosen at launch: 0.4, 0.8 (default, ~$100 at $125 per SOL), 2, 4 or 8 SOL per window (bounds 0.1 .. 100) |
| root challenge window | 1 h (bounds 10 min .. 24 h) |
| claim window | 30 d (bounds 7 .. 90 d) |
| observation gap | 20 s per coin; zec price every 30 s, median of 7 within 30 min |
payouts: sol and xmr
SOL is fully trustless after the root: the proof is in the published table, claim_release pays the leaf's wallet, and the site's "mine" page claims everything in one go.
XMR goes through the operator. The payout service pulls the XMR leaves' total, swaps it to Monero, pays at most 15 outputs per Monero transaction with monero-wallet-rpc, and attests every batch on chain (txid + sha256 of the per-output tx proofs + SOL in + XMR out). Receipts carry each output's destination hash, never the address. A holder checks their own payout in any Monero wallet: check tx proof with the txid, their own address and the published proof, message empty.
Registering. One Reg ["reg", wallet] account per wallet covers every coin. For XMR the subaddress is sealed with crypto_box_seal to the payout X25519 key (147 bytes) and only its sha256 is stored in the clear. Legacy (zmr style): a memo sellside:xmr:<subaddress> or sellside:sol from the wallet also counts but writes the plain address on chain; a registration account always wins over a memo.
Where the Monero route stands. NEAR Intents 1Click, the planned SOL to XMR route, lists no Monero today (checked 2026-09-28, 198 assets). Until it does, the operator swaps each XMR release by hand from the pulled SOL into the payout wallet ("manual funding") and the batches, proofs and attestations run as usual; the attested SOL in / XMR out show the effective rate. The service refuses a route that does not exist. On this preview the 1Click and Monero wallet are mocks with the same interfaces, so you can see the whole pipeline end to end.
program reference
Program id SeL4eVcmhgmNbBKzf6oi9YRwx2dTgTwCkiaN8jabdkX · Anchor 0.31 · IDL.
| account | seeds | holds |
|---|---|---|
| Config | ["config"] | admin, treasury, guardian, payout authority + X25519 key, ZEC pool, params, counters |
| Market | ["market", mint] | params copy, dead window / volume, counters, reserve side, holder side, 13 volume buckets, circulating samples, homepage numbers |
| Vault | ["vault", mint] | system-owned; pump creator of the coin; the SOL of both counters and a dead coin's SOL reserve |
| reserve | ATA(market, ZEC, SPL Token) | the ZEC reserve |
| Release | ["release", mint, n u32 le] | trigger slot, amount, root, table hash + CID, claim bitmap, XMR pull and batches |
| Payout | ["payout", release, batch u16 le] | one attested Monero batch |
| Reg | ["reg", wallet] | kind (SOL / XMR), key id, destination hash, sealed destination (≤ 160 bytes) |
| ZecOracle | ["zec", whirlpool] | ring of 16 ZEC price observations (clamped to ±5 % of the median) |
errors
Rendered from the IDL this site was built with.
| code | name | what it means |
|---|---|---|
| idl | ||
verify it yourself
- Open a coin's mint on an explorer: its pump.fun creator is
["vault", mint]of the program, not a person. - The reserve is the ZEC token account of
["market", mint]; its owner is the program's PDA. The coin page links it. - Every release shows its table file; the site hashes the file in your browser and compares it with
table_hashon chain. Every XMR batch shows its proofs; the site hashes them and compares withtx_proof_hashon chain. - Recompute a table: for every wallet registered as of the trigger slot, its smallest balance over the window before it (
windowStartSlot.. trigger slot, both in the table). The table JSON lists every leaf with its holding and proof. - The redeem form simulates your transaction on chain before you sign and shows the exact ZEC it returns.
what the admin can and cannot do
| can | cannot |
|---|---|
| change params for future coins (inside hard bounds) | change a launched coin's params, window or dead volume |
| pause new launches | stop observe, sweep, release, redeem, claims or liquidation |
| set the treasury (launch fees only) | move any coin's SOL, ZEC, releases or fees |
| appoint the first guardian; replace or remove it only after 48 h, visible on chain | post roots or pay anyone |
| route sweeps into another pool: the ZEC/SOL Whirlpool and the ZEC mint are pinned in the program | |
| propose new payout keys (effective after 48 h, visible on chain) | swap the payout authority instantly |
trust points
- The release table. Holdings over a window cannot be read on chain, so the payout authority computes the table (smallest balance over the window before the trigger) and posts its root. Mitigations: the table is public and reproducible, its hash is on chain, a guardian can veto during the challenge window, a root can never pay more than the Release holds or be reused on another Release.
- The XMR leg. Between
pull_xmrand the Monero batches the operator holds that release's XMR share. Every batch is attested with a Monero txid and tx-proof hash, so skimming is visible, not impossible. The SOL leg never passes through the operator. - Privacy. The payout X25519 key can read registered subaddresses (they are not on chain and not in receipts). Legacy memo registrations are public.
- ZEC on Solana is a bridged token: the reserve is as good as the bridge that minted it.
risks
- Sending SOL to a coin's fee accounts books it as fees (it pays the holders) and as volume; keeping a dead coin alive this way costs the dead volume x the creator fee rate per window (0.0024 SOL per 3 h on the curve at the defaults, less at PumpSwap's lowest tier), paid to its holders.
- Volume is booked when an observation runs; trades since the last observation count as "now".
- Lowering the redeem denominator needs tokens kept off the market for more than 15 minutes; the program uses the maximum of the recent circulating samples.
- Sweeps can be sandwiched within the 2 % price band; each sweep is capped.
- Holders who register after a trigger are paid from the next release on. Holders who bought inside the window before a trigger count only what they held for the whole window.
- An LP move on the PumpSwap pool in the middle of an observation interval rescales the flow traded before it (bounded; it never creates volume).
- If the payout authority pulls XMR and never attests, it shows on chain (pulled without batches).
independent audit
An independent audit of the program and the payout service (2026-09-28) found two high, one medium and four low issues; all fixed except one documented residual (donation keep-alive above): PumpSwap LP moves booked as trades (fixed: LP-aware attribution), a flash holder at the trigger slot (fixed: smallest holding over the window), the admin choosing the sweep pool (fixed: route pinned in the program), instant guardian changes (fixed: 48 h timelock), no receipts after a release expired (fixed), automatic re-posting after a veto (fixed: operator acknowledgement), memo history (fixed).
faq
Do I have to register to redeem? No. Redeem is open to any holder. Registration is only for releases.
Why ZEC? A reserve outside the coin itself, held in the program, bought on the deepest direct SOL pool on Solana.
What happens after the coin graduates to PumpSwap? The engine keeps running: the pool's creator fees are routed to the same vault and observations read the pool.
Is there a timer or epoch? No. Sweeps and releases fire on thresholds; the only clock is the dead window a coin chose at launch.