Skip to content

Launch mechanism

Every launch seeds token-only liquidity, zero WETH consumed. This is the protocol’s core invariant. This page explains how that is possible, and the one detail a reviewer or integrator has to get right.

A single-sided Uniswap V3 position is a bonding curve. Providing liquidity over a price range with only the token, starting at the bottom of the range, produces exactly the pump-style price ascent, but the curve and the DEX pool are the same object, so nothing ever migrates.

This is the property that removes the worst exploit surface of curve-then-migrate launchpads: there is no migration window because there is no migration.

In Uniswap V3, when the pool’s current price sits on one side of a position’s range, that position is composed 100% of one asset:

  • current tick < tickLower → position is 100% token0
  • current tick >= tickUpper → position is 100% token1

So a launch deposits only the launch token and zero WETH:

  1. Deploy the token. The full fixed supply is minted to the factory.
  2. Create and initialize the pool. The factory creates the TOKEN/WETH V3 pool and initializes its price at the token-only side of the intended range.
  3. Mint the position. It mints a V3 position over the range, depositing only the token side.
  4. Lock it forever. The position NFT is transferred to the locker, which never releases it.

No ETH or WETH is required to bootstrap. The quote side is contributed by buyers as they trade: each buy walks price up the range, pulls token out, and leaves WETH inside the (locked) position, a permanent, growing liquidity floor.

Uniswap sorts pool tokens by address into token0 < token1. Which side the launch token lands on flips the single-sidedness condition, so the factory computes the deposit side from the ordering:

Launch token vs WETH Token is Need current tick Deposit side
token < weth token0 < tickLower amount0 only
token > weth token1 >= tickUpper amount1 only

The factory enforces on-chain that the WETH side consumed is exactly zero; it does not trust off-chain tick parameters. The SDK computes a sqrtPriceX96 / tickLower / tickUpper preset consistent with the ordering, but the on-chain check is the source of truth.

Both orderings, token < weth and token > weth, are covered by fuzz and fork tests against real Uniswap V3.

The failure mode that matters: an empty seed

Section titled “The failure mode that matters: an empty seed”

Because the factory sets the WETH-side desired amount to 0, Uniswap’s getLiquidityForAmounts returns min(L_token, L_weth = 0) = 0 for any preset whose current price is not on the token-only side of the range.

The consequence is subtle and important:

  • A mispriced preset does not leak WETH. The zero-WETH-consumed check can never fail via a normal launch; it is kept as a defensive assertion against a hostile position manager.
  • Instead, a mispriced preset would silently mint an empty locked position and strand the entire supply in the factory while the launch appears to succeed. That would leave a half-launched token.

To prevent this, the factory reverts EmptyLiquidity whenever the resulting position liquidity is 0. A mispriced launch reverts wholesale rather than half-completing. This is enforced on-chain and asserted in the invariant suite.

createToken either fully completes (token deployed, pool created and initialized, single-sided position minted and locked) or it reverts. There is no code path that leaves a token with unlocked or WETH-contaminated liquidity, and none that leaves the supply stranded. This is invariant L5 (launch atomicity); see Contract addresses and invariants.