Docs·Metrics reference

Metrics reference

Valuation and price

Curve FDV until graduation, the seven-day pool floor afterwards, and the coverage test that decides whether the floor may be published at all.

Version
1.0
Updated
2026-08-29
Source
Metric definitions v1.2

Which figure is official#

Curve FDV until graduation, the seven-day pool floor after. That is what the settlement oracle reads, so the number quoted about a launch is the number a market settles on.

curveFdvWei — before graduation#

curveFdvWei
unitwei
derivationspotPriceWad(virtualEthReserve, virtualTokenReserve) × 1_000_000_000e18 / 1e18
sourceBondingCurve.fdvWei() — contracts/src/launchpad/BondingCurve.sol. Price from CurveMath.spotPriceWad(ethReserve, tokenReserve), exposed as BondingCurve.spotPriceWad()
freshnessLive chain read, exact at a block.
coverageFULL
Three things that surprise a first reader
CaveatDetail
The function is fdvWei()curveFdvWei is the metric key and the predicate id. No contract declares a function by that name.
It multiplies by the genesis constant, not by totalSupply()TOTAL_SUPPLY = 1_000_000_000e18. The two diverge permanently after the first burn. This is deliberate and matches the settlement oracle — do not “fix” it against live supply.
It is computed on the virtual reservesWhich is what makes it a price rather than a reserve ratio.

poolFdvUsdFloor7d — after graduation#

poolFdvUsdFloor7d
unitUSD, 18 decimals
derivationThe lowest fdvUsd sampled in the trailing WINDOW (604,800 s on production)
sourcePoolMetrics.minFdvUsdOverWindow(address token) returns (uint256 minFdvUsd, bool covered)
freshnessSampled by a permissionless poke(token). Read at a block.
coveragePublish only when covered == true; otherwise return null with a scope.

The coverage test#

What covered == true requires
ConditionMeaning
AnchoredA sample at or before the window start.
PopulatedAt least one sample inside the window.
Every in-window sample pricedNo sample recorded fdvUsd == 0, the “unpriced” sentinel.
No excessive gapNo gap larger than MAX_SAMPLE_GAP (MIN_POKE_INTERVAL × 4), including the trailing gap to now.

PoolMetrics.coverageOf(token) returns the whole WindowScan — anchorAt, newestAt, largestGap, inWindowSamples, everyInWindowPriced — and is what a scope string should be built from rather than a bare “not covered”.

A sample is left unpriced rather than the poke failing when the Chainlink round is older than MAX_PRICE_AGE = 30 hours. Thirty because the ETH/USD feed on this chain publishes on an 86,400 s heartbeat; a tighter bound would make ordinary feed behaviour look like an outage. A display-side staleness bound is a different judgement and is deliberately tighter — refusing to show a rate is not the same as refusing to record one.

spotPriceWad#

// before graduation
BondingCurve.spotPriceWad()            // wei per whole token

// after graduation
derive from the V4 pool's sqrtPriceX96
// the graduation opening price is on V4GraduationAdapter.GraduatedToV4.sqrtPriceX96

A price and a valuation are different claims and this reference keeps them apart. See value locked for the same distinction applied to a locked position, and figures we do not publish for why an uncovered floor is refused outright rather than published with a caveat.