Skip to main content
Every veto.fun token trades on the same constant-product bonding curve until it graduates. The curve is an automated market maker with no order book: price is purely a function of reserve state, so it’s fully deterministic and quotable in advance.

The formula

The curve maintains two virtual reserves and keeps their product constant:
  • Buys add ETH to virtualEth and remove tokens from virtualToken → price rises.
  • Sells do the opposite → price falls.
  • The spot price at any moment is virtualEth / virtualToken.
“Virtual” means the reserves start pre-seeded so the token has a sensible non-zero starting price with no initial liquidity deposit. The virtual ETH offset also guarantees the curve always holds enough real ETH to buy back every circulating token.

Curve parameters

With the current 1.6 ETH virtual reserve, that works out to:
The virtual ETH reserve is the protocol’s single economic knob and is fixed per deployment. It scales the ETH cost of the curve without changing its shape. All other constants are hard-coded in the contract.

Buys, sells, and rounding

For a buy of ethIn (after the 1% fee is skimmed):
Sells are the mirror image. All rounding is done in the pool’s favor (k can never decrease), which protects the curve’s solvency. This invariant is fuzz-tested in the contract suite. Quotes from the contract’s quoteBuy / quoteSell functions are exact. The SDK also ships a bit-exact client-side mirror of this math so UIs and bots can quote without an RPC round-trip.

Graduation trigger

The curve tracks how much of the 793.1M sale allocation remains. The buy that empties it:
  1. Fills exactly to the remaining supply (excess ETH is refunded in the same transaction),
  2. Marks the curve graduated, permanently frozen, and
  3. Makes the token eligible for migration to Uniswap v3.
The graduation threshold is supply-based, not market-cap-based. There’s no oracle and nothing to manipulate: sell out the curve and it graduates, every time.

Why sells can never break the curve

The invariant realEth = virtualEth − virtualEth₀ holds at all times: the real ETH held by the contract is exactly what buyers put in (net of fees), which is exactly what the curve would owe if every holder sold back down to the starting point. The curve is always solvent by construction.