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.
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#
| unit | wei |
|---|---|
| derivation | spotPriceWad(virtualEthReserve, virtualTokenReserve) × 1_000_000_000e18 / 1e18 |
| source | BondingCurve.fdvWei() — contracts/src/launchpad/BondingCurve.sol. Price from CurveMath.spotPriceWad(ethReserve, tokenReserve), exposed as BondingCurve.spotPriceWad() |
| freshness | Live chain read, exact at a block. |
| coverage | FULL |
| Caveat | Detail |
|---|---|
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 reserves | Which is what makes it a price rather than a reserve ratio. |
poolFdvUsdFloor7d — after graduation#
| unit | USD, 18 decimals |
|---|---|
| derivation | The lowest fdvUsd sampled in the trailing WINDOW (604,800 s on production) |
| source | PoolMetrics.minFdvUsdOverWindow(address token) returns (uint256 minFdvUsd, bool covered) |
| freshness | Sampled by a permissionless poke(token). Read at a block. |
| coverage | Publish only when covered == true; otherwise return null with a scope. |
The coverage test#
| Condition | Meaning |
|---|---|
| Anchored | A sample at or before the window start. |
| Populated | At least one sample inside the window. |
| Every in-window sample priced | No sample recorded fdvUsd == 0, the “unpriced” sentinel. |
| No excessive gap | No 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.sqrtPriceX96A 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.