Docs·Metrics reference

Metrics reference

Volume

Bonding-curve volume, post-graduation pool volume and refunds — what each is summed from and why one of them is always partial.

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

curveVolumeWei — bonding-curve volume#

curveVolumeWei
unitwei
derivationΣ Bought.grossEthUsed + Σ Sold.grossCurveQuote over every launch curve of every factory in priorFactories[] and the current one
sourceBondingCurve.Bought, BondingCurve.Sold — contracts/src/launchpad/BondingCurve.sol
freshnessIndexed. Carries asOfBlock.
coverageFULL from indexFromBlock
event Bought(address indexed buyer, address indexed recipient, uint256 grossEthUsed,
             uint256 curveQuote, uint256 tokenAmount, uint256 tradeFee);

event Sold(address indexed seller, uint256 tokenAmount, uint256 grossCurveQuote,
           uint256 ethReceived, uint256 tradeFee);

Both sides are measured gross — fee included, on the same basis. That is the whole reason the field choice matters, and picking the wrong field on one side produces a figure that is net on buys and gross on sells.

Which field, and what the alternative would mean
SideUseRelationship
BuygrossEthUsedgrossEthUsed = curveQuote + tradeFee. It is the ETH actually consumed, excluding any refund. curveQuote is the net that reached the reserve.
SellgrossCurveQuotegrossCurveQuote = ethReceived + tradeFee. It is what the curve gave up before the fee; ethReceived is what the seller got.
Completing buygrossEthUsedAlready the capped amount: the curve sizes the trade to land exactly on the graduation target and refunds the excess. The refund is not in the event, correctly — it was never spent.

Caveats#

CaveatDetail
Redeemed is not volumeIt is the refund hatch for a curve that completed and never graduated. Fee-free, and a reserve outflow rather than a trade. Published separately as refundedWei; never added to volume.
tradeFeeBps is on no trade eventIt is immutable on the curve, bounded by MAX_TRADE_FEE_BPS = 500. To reconstruct a historical fee rate, read the curve, or replay LaunchFactory.ConfigSet to the launch’s block.
A launch’s own opening buy is volumeThe factory routes it through the same curve at the launch timestamp, so it emits an ordinary Bought. It is not excluded.

poolVolumeWei — post-graduation volume#

poolVolumeWei
unitwei
derivationPer token, PoolMetrics.metricsOf(token).buyVolumeWei — equivalently Σ Poked.buyAddedWei. Protocol-wide, the sum over graduated tokens.
sourcePoolMetrics.Poked, PoolMetrics.metricsOf(address) — contracts/src/predict/PoolMetrics.sol
freshnessOn-chain accumulator, advanced by a permissionless poke(token) no more often than MIN_POKE_INTERVAL (300 s on production).
coveragePARTIAL, always. See below.
fees   = (feeGrowth0X128_now − feeGrowth0X128_last) × min(liquidity_now, liquidity_last) / 2^128
volume = fees × FEE_DENOMINATOR / lpFee
What the derivation cannot see
ConsequenceDetail
Buy side onlyFee growth is read on currency0 (ETH), so sells contribute nothing.
Liquidity added mid-interval books less than tradedThe interval is priced at the lower of the two liquidity readings.
An interval can be skipped entirelyWhen liquidity moved by more than MAX_LIQUIDITY_DRIFT (2×), the interval is dropped and says so: PoolMetrics.VolumeIntervalSkipped(address indexed token, uint128 previousLiquidity, uint128 currentLiquidity, uint256 feeGrowthDeltaX128).

The exact alternative, when an exact figure is needed: index Uniswap V4 PoolManager Swap events filtered to the launch’s poolId (PoolMetrics.poolIdOf(token)). That is complete in both directions. It is not the platform’s published figure because the poke series is what settlement reads, and a published number that disagrees with the settlement oracle is worse than a conservative one. Publish whichever you used, and say which.

refundedWei — refunds from ungraduated completions#

refundedWei
unitwei
derivationΣ Redeemed.ethReceived
sourceBondingCurve.Redeemed(address indexed holder, uint256 tokenAmount, uint256 ethReceived) · gate BondingCurve.refundOpen()
freshnessIndexed. Carries asOfBlock.
coverageFULL

Only possible on a curve that reached complete() and did not graduate before completedAt + GRADUATION_GRACE_PERIOD (3 days). No fee is ever taken on this path. It belongs beside volume, never inside it — see launches and graduation for how a refunding launch is counted in the graduation rate.