The two-position launch
Since the 2026-09-12 amendment there is no bonding curve. The entire supply goes into
locked Uniswap v4 liquidity, from the creation transaction itself. In the code since
2026-09-28: LiquidityLock.launchMarket does all of it inside the market's creation
transaction, and the tests pin the opening price the Lens reads, 3,401,582,525 wei per
token.
Why the curve went away
The old curve was a constant product over virtual reserves:
x = VIRTUAL_ETH + netReserve (3.75 ETH + what came in)
y = TOKEN_RESERVE - tokensSold (1.1 B − what went out)
That is exactly what a concentrated liquidity position is: v3/v4's virtual reserves are that offset. The correspondence is not an approximation, it is the same equation written differently.
What removing it buys: no migration — the protocol's riskiest moment — no graduation fee to extract, one fee path instead of two, and markets routable by aggregators from their first block.
The two bands
tick 195000
opening"] -->|band 1 · 700M tokens · 7.535 ETH| B["FDV 34.091 ETH
tick 171960
10x"] B -->|band 2 · 300M tokens · unbounded| C["tick −887220
price ceiling"]
| Band 1 | Band 2 | |
|---|---|---|
| Tokens | 700,000,000 | 300,000,000 |
| Ticks | [171960, 195000] |
[−887220, 171960] |
| Depth | 7.535 ETH to traverse | 14.5 ETH at 2× · 45.7 ETH at 20× · 144.6 ETH at 200× |
tickSpacing 60, and no LP fee.
These are the default launch settings. Since 2026-10-05 the supply, the tokens in band 1
(band 2 takes the rest), the launch tick, the bottom ticks of both bands, the tick spacing
and the LP fee form one setting of StockFun's owner, setLaunchConfig on the factory,
which applies to the markets created afterwards. It refuses a shape no pool could hold: an
empty band, ticks off the spacing or out of order, a tick spacing or an LP fee out of
range, bands whose liquidity one tick cannot carry. Each pool keeps the shape, the LP fee
and the tick spacing it was created with: the lock records its ticks, and the Lens gives
each market's LP fee and tick spacing.
The delicate part: the opening price
Both positions hold tokens only at launch. That is what lets the protocol advance no ETH: every ETH the pool will ever hold comes from buyers.
For a position to be token-only, the current price must be at or above the top of its range. Hence:
sqrtStartX96 = TickMath.getSqrtPriceAtTick(BAND1_UPPER); // not sqrt(raw FDV)
The exact tick of the launch FDV is 194,977.95, and the nearest usable tick above it is
195,000. Deriving sqrtStart from the raw FDV would put the price inside band 1, and
LiquidityLock's NotSingleSided check would reject the deposit.
Quantisation leaves an effective FDV of 3.4016 ETH instead of 3.409, a −0.22 % drift.
What it looks like in practice
Successive 2 ETH buys from launch, with the default settings:
| Spent | FDV | Supply held |
|---|---|---|
| 2 ETH | ~$27,600 | 36.1 % |
| 4 ETH | ~$50,400 | 53.3 % |
| 10 ETH | ~$164,000 | 74.8 % |
| 50 ETH | ~$2.78 M | 93.9 % |
The first ticket takes 36.1 % of supply — against 36.99 % on the old curve. The launch behaves as before, to within a point, which was the criterion the parameters were chosen against.
A band's structural ceiling
The ETH a band can absorb, if 100 % of supply sat in it, is exactly the geometric mean of its two FDVs:
$$ E{\max} = \sqrt{\text{FDV}{\text{start}} \times \text{FDV}_{\text{end}}}
$$
That is what constrains the parameters: you cannot freely pick the launch price, the band top and the depth — the token count closes the system.
The end mode
Like the tokens, the lock cannot be upgraded: its code is what keeps the liquidity in the pools. Since 2026-10-02 it has one exit, the end mode, for the case where the project shuts down.
- The announcement. StockFun's owner calls
end(), and the lock records, publicly, the date 30 days later. From then on no new market can launch, nor can the$STOCKFUNposition be created, so no market gets less than the full notice. Trading and fee collection go on - The notice. For 30 days every pool keeps trading. The owner can cancel at any time
with
cancelEnd(), and launches resume - The recovery. Once the 30 days have run, the owner can take every position of a
pool out — both bands of a market, the single
$STOCKFUNposition — and send its ETH and tokens, uncollected donations included, to any address (recoverLiquidity). A recovered pool collects nothing more and no longer counts as locked; a later cancellation leaves it empty
The 30 days are the holders' notice. They are a constant of the lock, END_DELAY, not a
setting: the one fixed delay of the protocol.
Outside the end mode, nothing reaches the positions. Since 2026-10-05 the lock keeps a share
of a fee collection whose recipient refused it, for that recipient, until anyone pays it
(payOwed); and StockFun's owner can move out what was sent to the lock by mistake
(rescue, rescueClaims, rescueNft): any token, ETH beyond the shares it keeps, v4
claims, an NFT. The lock has no generic call: through the PoolManager, one could reach the
end mode's recovery without its 30 days.