Create
Documentation
Guides

Trading the curve

Before graduation the only venue is the launch's own bonding curve. It has no fixed address — read it from factory.getLaunchedToken(token).curve.

Approve the curve for both legs: the quote asset to buy, the memecoin to sell.

The two slippage bounds are not the same kind of bound#

This surprises people, and it is deliberate.

On a buy, minTokensOut is a price bound. A buy that would take more than the remaining allocation is clamped rather than reverted — you get the remaining tokens and the unspent quote is refunded to msg.sender in the same transaction. The bound is then enforced as an implied price rather than a quantity, so a partial fill at an acceptable price succeeds.

That means you can safely overshoot the graduation threshold. Sending more than the curve can absorb is normal and costs nothing.

On a sell, minQuoteOut is a strict quantity bound. You get at least that much or the call reverts.

The sell side closes early#

A sell reverts with CurveGraduated as soon as readyToGraduate() becomes true — which is before the graduated flag is set and before anyone has called graduate.

So there is a window where the curve looks live, graduated is still false, and every sell reverts. If your UI reads graduated to decide whether selling is possible, it will offer a button that cannot work. Read readyToGraduate() too.

Referrals#

The four-argument buy overload takes a referrer:

solidity
function buy(uint256 quoteIn, uint256 minTokensOut, address recipient, address referrer)

Three things to know:

  • The binding is written for recipient, not msg.sender.
  • It is consulted only on that address's first referred trade, and is permanent after that. Passing a fresh referrer later cannot poach an existing relationship.
  • A bad referrer reverts the whole buy. SelfReferral and ReciprocalReferral are not swallowed. Validate before you put an address in the call — particularly if it came from a URL parameter.

sell has no referrer argument; only an existing binding applies.

Users can also bind themselves ahead of any trade with referralRegistry.setReferrer(address).

Quoting#

Off-chain, the curve is constant product against a virtual reserve:

code
netIn     = quoteIn - fee - creatorTax          // fees come off the QUOTE leg
tokensOut = netIn * tokenReserve / (quoteReserve + netIn)

where quoteReserve = phantomQuote + trackedQuote - quoteFeeBalance - creatorTaxBalance, available together from getReserves().

Note getReserves() returns the virtual quote reserve, which includes the phantom reserve. For the amount actually raised — what a progress bar should show against the threshold — use realQuoteReserve().

Once a launch graduates the curve is closed and estimates must come from the Uniswap V4 Quoter instead. See Trading the pool.