Docs menu: Single-sided liquidity

Single-sided liquidity

A bonding curve program holds tokens and sells them along a formula. Latch instead uses an ordinary AMM pool and gives it a price range, so there is no separate curve program and no migration step. The pool is a real market from the first block.

The idea

A concentrated-liquidity pool only provides liquidity between two prices, Pa (lower) and Pb (upper). If the pool's current price starts at Pa, it can hold only the base token. There is no quote token yet, because nothing has been bought. When someone buys, they add quote tokens (SOL) and take out base tokens, and the price rises along the range. When they sell back, it moves down. At Pb the pool is out of base tokens and no further buying is possible. If Pb is far above Pa, the ceiling is far away, but it is real: buying out the supply is capped at Pb.

Verified. Meteora documents that projects can programmatically create single-sided DAMM v2 pools, and that a bounded price range is expressed as sqrt_min_price and sqrt_max_price on the pool config. DAMM v2 describes itself as a constant-product AMM with a minimal form of concentrated liquidity. Its program id is cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG.

Resolved on a local validator. Meteora's SDK (@meteora-ag/cp-amm-sdk) exposes createCustomPool, which takes sqrtMinPrice, sqrtMaxPrice, the fee schedule and an isLockLiquidity flag directly, with no config key from Meteora, and a preparePoolCreationSingleSide helper for one-sided deposits. Latch's launch builder uses exactly that path. A local test validator running the real DAMM v2 binary, dumped from mainnet, accepted a single-sided pool created with a quote amount of zero, with the production fee schedule and a 5 SOL to 50,000 SOL range. The SDK quietly wraps 1 lamport of SOL in that case, so the quote side is never exactly empty. This has not been tried on mainnet itself.

The math

These are the standard concentrated-liquidity formulas. DAMM v2 stores square-root prices as fixed-point numbers, so check the program's exact rounding before relying on the last digits.

Let x be the base token amount, Pa and Pb the bounds (quote per base), and L the liquidity.

L = x / (1/√Pa − 1/√Pb)                 deposit only base, price starts at Pa

Buy with dy of quote from price √P:
  √P' = √P + dy / L                      new sqrt price
  dx  = L · (1/√P − 1/√P')               base tokens received

Total quote needed to buy out the whole supply:
  y_total = x · √(Pa · Pb)

Worked example

Supply x = 1,000,000,000. Start market cap 5 SOL, so Pa = 5e-9 SOL per token. Ceiling 10,000x, so Pb = 5e-5, which is a 50,000 SOL market cap.

Quantity Value
√Pa 7.071e-5
√Pb 7.071e-3
L about 71,424
Quote needed to buy out all supply 1e9 · √(5e-9 · 5e-5) = 500 SOL
First 1 SOL buy: new price about 7.18e-9 SOL (+43.5%)
First 1 SOL buy: tokens out about 166.9 million (16.7% of supply)

This example uses an older, lower setting. The launch page's default, the Community preset, is a 20 SOL start and a 1,000x ceiling. There L is about 146,040, buying out the supply takes about 632 SOL, a first 1 SOL buy takes about 4.8 percent of supply and a first 10 SOL buy about 33.7 percent, all before fees.

These figures ignore trading fees. With the 15 percent starting fee, the same 1 SOL buy on a local validator took about 14 percent of supply, not 16.7, because part of the SOL goes to fees.

Two things to notice. First, the market cap at the ceiling is 50,000 SOL, but only 500 SOL ever enters the pool, because most of the supply sells at low prices. Second, a 5 SOL start market cap makes the first buyers very powerful. Start price is the most important launch parameter, and the launch form shows the numbers before you commit.

Floor and exits

Liquidity exists only inside [Pa, Pb]. Holders can sell back down to Pa and no lower, and what they receive is capped by the quote tokens buyers put in. The pool is not a promise of a minimum price. Holders can never sell for more SOL than buyers deposited, and they get less after fees.

Anti-sniper fees

DAMM v2 has a base fee scheduler (linear or exponential decay) that is enabled for pools created on the customizable-pool path, plus an optional volatility-based dynamic fee. Latch uses the exponential time scheduler: the fee starts at 15 percent and eases to 1 percent over the first 10 minutes, then stays at 1 percent. That taxes outside buyers in the first minutes. Meteora keeps 20 percent of every trading fee as its protocol fee (per its current source code; check the pool on the first mainnet launch). The rest goes to whoever holds the position. Without the vault, that is the creator's wallet. With the vault, the creator keeps their chosen share of it, at most 95 percent, and Latch's treasury keeps the remainder, so at least 5 percent. Fees are collected in both tokens, so part of it is paid in the launched token, which the receiver can sell. It does not stop the creator buying first from another wallet, because most of the fee comes back to them. Verified feature; parameters to be checked on the first mainnet launch.

What this does not give you

It does not give an initial price discovery curve beyond the formula above, and it does not hide the fact that the first buyer sets the price. Nothing here prevents a creator from buying first with a second wallet. The launch page lets a creator buy up to 10 percent in the open instead, inside the pool transaction, and the token page flags early buyers the creator funded. See Security.