Ponsfamily V2 does not price on a Uniswap pool first. The full supply mints to a constant-product bonding curve that already trades in the same quote asset the future V4 pool will use (native ETH or pairToken). Graduation later seeds that pool from the curve’s real reserves — no router, no oracle.
There is no quote() on the curve. You rebuild the price from getReserves(), feeBps, creatorTaxBps, sellableTokens(), and currentSnipeTaxBps(recipient).
Invariant
The curve is Uniswap-v2-style:
$$x \cdot y = k$$
x is the quote reserve (phantom + real). y is the token reserve. A phantom quote reserve sets the opening price so the first buy is not free. realQuoteReserve() is what actually arrived from traders; graduation watches that against the launch’s threshold.
Core output (from PonsV2BondingCurveMath):
$$
\Delta y = \frac{\Delta x_{\text{net}} \cdot y}{x + \Delta x_{\text{net}}}
$$
On-chain they pass feeBps = 0 into the AMM helper because fees are applied on the quote leg first, not inside the product.
Buy: fees come off the input
Order of operations on buy(quoteIn, minTokensOut, recipient):
- Read snipe tax for this recipient (decays from 99% toward 0 over ~5s; exempt addresses skip it).
- Take protocol
feeBpsand optionalcreatorTaxBpsfrom the quote spent. - Feed what remains into
getAmountOut. - If the buy would eat the reserved graduation slice, fill only
sellableTokens()and refund the rest.
Sketch:
spent = quoteIn // may clamp to sellable
snipe = spent * snipeTaxBps / 10_000 // buys only
fee = spent * feeBps / 10_000
tax = spent * creatorTaxBps / 10_000
netIn = spent - snipe - fee - tax
tokensOut = getAmountOut(netIn, quoteReserve, tokenReserve, 0)
Caps: curve fee ≤ 10%, creator tax ≤ 10%, total trade fee ≤ 20%, snipe start ≤ 99%. A taxed buy still nets something.
Sell: fees come off the output
Sells never pay snipe tax.
gross = getAmountOut(tokensIn, tokenReserve, quoteReserve, 0)
fee = gross * feeBps / 10_000
tax = gross * creatorTaxBps / 10_000
quoteOut = gross - fee - tax
When readyToGraduate() is true, sells revert (CurveGraduated) even before graduate() runs. The curve is already holding pool seed; selling would move the price the pool is supposed to inherit.
Graduation price
After drain, PonsV2GraduationMath seeds V4 with
$$\texttt{sqrtPriceX96} = \sqrt{\frac{\text{amount1}}{\text{amount0}}} \cdot 2^{96}$$
from the curve’s final token and quote amounts. Full-range position. Same quote asset the curve already collected.
What a bot gets wrong
- Quoting like V3 / V4 before
phase == 0(still on curve). - Putting fee inside
getAmountOutand subtracting it from quote (double fee). - Ignoring phantom vs real quote when estimating “how close to graduate.”
- Buying at t=0: ~99% snipe tax vs ~1–3% a couple of seconds later. Price impact rarely outruns that decay unless the curve is already graduating.
Read reserves, subtract quote-leg haircuts, then run the product. That is the whole market until the pool exists.
Telegram: https://t.me/C00LBB
Site: https://coolbb.site
Top comments (0)