Skip to content

the perp open-interest column reads the venues, shows every row, and Ondo has a seed - #2718

Merged
Flotapponnier merged 2 commits into
devfrom
fix/capital-perp-oi-source
Sep 29, 2026
Merged

Flotapponnier merged 2 commits into
devfrom
fix/capital-perp-oi-source

Conversation

@Flotapponnier

@Flotapponnier Flotapponnier commented Sep 29, 2026 •

Copy link
Copy Markdown
Collaborator

Follow-up to #2717. Florent said venues are missing from the perp open-interest table and named Ondo. The missing venues were a symptom; the cause is the headline.

The column was mislabelled, and the 49% gap is what that looks like

The header promises each venue's open interest. The column was reading bench 265's oi panel, which is DefiLlama's open-interest overview keyed by protocol. That is a mislabel, not a discrepancy, and it had two consequences:

  • The values disagreed with the venues. Hyperliquid read $8.57B against the venue's own $12.77B, a 49% gap on the largest row on the table. EdgeX $225M vs $452M, Pacifica $57M vs $112M, Extended $92M vs $185M, all roughly half; Aster $1.43B vs $1.22B, the other way. Two different measurements, not one with noise.
  • The cohort is token-gated, so a venue without a ranked token had no row at all: trade.xyz $3.76B, GRVT $472M, Lighter RH $228M.

The column now reads the perp cohort harness (perp_venue_oi_usd, perp_venue_volume_24h_usd), each venue's own API, through fetchPerpCohort() — the worker-written snapshot /perps uses, so still no Prometheus call at render time. Open interest, volume and turnover now share one source. The page states whose figure it is, says the column changed on 29 September and why, and the reading lines say DeFiLlama's overview reads differently and is not what these columns show. No averaging of the two, no silent switch.

The one seam left, and it is written down in four places so nobody rediscovers it: turnover is bench 271's published ratio, which divides the 24-hour averages of those two gauges, while the columns beside it show the latest read. Same gauges, same harness, different window, so volume / OI as displayed does not equal the turnover column, and the gap is widest on a venue whose book moves during the day. Recorded in bench 271's methodology, the table's note, CAPITAL_READING.openInterest, and the comment above perpOiRows. The ratio is read from the bench rather than recomputed per page so one named ratio has one value across the site.

No 7d column on the perp table: nothing publishes a 7-day series of the venue gauge, and pairing a venue level with a DeFiLlama move would be the same seam one column over.

Truncation

.slice(0, 10) is gone from both OI tables and each heading carries its count ("Prediction market open interest, all 13"). A venue the harness gets no open interest from (Orderly, Backpack, SynFutures, Vest, KiloEx) keeps its row, ranked last, with the reason on the cell instead of dropping off a table a reader is counting.

The prediction-market 7d column is hidden by the coverage floor from #2717 (1 of 13). Twelve markers next to one value is the noise that made the page read as empty; the per-row reasons stay in /api/capital for a machine consumer, and the column returns on its own once the eleven warm-up windows fill.

Venue classification

From harnesses/perp-cohort-stats/cmd/script/registry.go, the per-venue source files, and the provider registry:

venue verdict evidence
trade.xyz DEX seeded onchain, Hyperliquid HIP-3 dex, native source srcHLXyzNative
GRVT DEX seeded onchain, zkSync, native source + DeFiLlama fallback
Lighter RH DEX seeded onchain, Robinhood on Lighter L2, native source
Ondo Perps DEX, hybrid off-chain matching in Intel SGX enclaves with on-chain custody on Ethereum and Arbitrum, USDC and Ondo tokenised stocks as collateral; read from api.ondoperps.xyz, already ranked on bench 041 and bench 271
Variational DEX, not added api.variational.io is NXDOMAIN; open interest comes from DeFiLlama alone and it publishes no volume, market count or top market

The first three appear automatically once the column moved. Ondo was never in PERP_VENUES, so /perps was dropping it too — a registry gap found through a hub audit, costing that page a $89M row. Now seeded. The "SGX" in Ondo's description is Intel SGX, not Singapore Exchange, so regulated would have been wrong; onchain matches what benches 041 and 271 already call it. Variational stays out deliberately, with the reason written next to Ondo's seed.

The Gains outlier

There is no outlier guard on the turnover column anywhere, and a comment now says not to add one, citing the sub-half-hour holding period. Bench 271 publishes it unclipped too.

Verification

fetchPerpCohort() is unreachable from a local dev env, so the perp table is absent locally and the page degrades to the prediction-market table alone (verified, no error). Production /api/md/perps confirms the snapshot and the 26-row venue cohort. The row build is extracted as a pure perpOiRows with 5 tests covering the CEX filter, the prediction-market overlap, the no-OI rows, the product-slug turnover join and the hidden 7d column.

pnpm validate 240 specs, pnpm typecheck, eslint clean, 367 tests pass.

…Ondo has a seed

Three things Florent's "venues are missing" turned out to be.

The column header claims each venue's open interest and the column was
reading bench 265's panel, which is DefiLlama's open-interest overview
keyed by protocol. Two consequences. The numbers disagreed with the
venues: Hyperliquid read $8.57B against the venue's own $12.77B, a 49%
gap on the largest row, and EdgeX, Pacifica and Extended were out by
about half in the other direction. And the cohort is token-gated, so
venues without a ranked token had no row: trade.xyz at $3.76B, GRVT at
$472M, Lighter RH at $228M.

So open interest and 24h volume now come from the perp cohort harness,
each venue's own API, the cohort /perps shows and the one bench 271's
turnover divides. The page says whose figure it is and says the column
changed and why. Turnover stays bench 271's published ratio: it divides
24-hour averages of the same two gauges while the table shows the latest
read, so it still does not divide exactly into the columns beside it, but
the seam is now one average against one spot read of one gauge rather
than two different providers. No 7d column on the perp table: nothing
publishes a 7-day series of the venue gauge, and pairing a venue level
with a DefiLlama move would be the same seam one column over.

Rows are no longer cut to ten, and each heading carries its count. A
reader who counts ten rows on a table of nineteen concludes the rest is
missing, which is what happened. A venue the harness gets no open
interest from (Orderly, Backpack, SynFutures, Vest, KiloEx) keeps its
row, ranked last, with the reason on the cell.

Ondo Perps was in perp_venue_oi_usd all along and missing from
PERP_VENUES, which is why /perps dropped it too. It is read from its own
API, already ranks on bench 041 and bench 271, and its matching runs
off-chain in Intel SGX enclaves with on-chain custody on Ethereum and
Arbitrum, so it belongs in the DEX cohort those boards already count it
in. Seeded. Variational is the other venue in the gauge and stays out
deliberately: api.variational.io is NXDOMAIN, its open interest comes
from DefiLlama alone and it publishes no volume or market count.

The turnover column has no outlier guard and the code says not to add
one: Gains reads far above every other row because its positions turn
over in under half an hour, and that is the most informative cell there.
The remaining seam after the source swap, written where someone checking
the turnover number lands: the /capital open-interest table reads the
latest value of perp_venue_volume_24h_usd and perp_venue_oi_usd, and this
bench divides their 24-hour averages. Same gauges, same harness,
different window, so a venue whose book moved during the day disagrees,
by a lot on one that turns over in under an hour. Pages read the ratio
from the bench rather than recomputing it, so one named ratio has one
value across the site.
@Flotapponnier
Flotapponnier merged commit 166fc52 into dev Sep 29, 2026
2 checks passed
@Flotapponnier
Flotapponnier deleted the fix/capital-perp-oi-source branch September 29, 2026 19:51
Flotapponnier added a commit that referenced this pull request Sep 29, 2026
Found by checking the deployed page after #2718 rather than the JSON:
/api/capital served all 25 perp venues while the rendered /capital had
the prediction-market table and no perp table at all. The API route is
per-request and the page is ISR on a one hour window, so one render that
missed the perp venue cohort snapshot cached a page with the table
silently gone, for an hour, with nothing saying why.

That is the defect this page spent the week removing, one level up: a
missing table reads the same way a missing cell did. The section now
keeps its heading and says which source did not answer, where the last
measurements are (the perps hub and bench 271) and that /api/capital is
read per request rather than cached with the page.

It still substitutes nothing. The only other open-interest reading
available here is DefiLlama's overview, which is a different measurement
and is what #2718 moved off; filling the gap with it would undo that
work and hide the outage behind plausible numbers.

`perpVenueCohortLive` on the hub carries the state so the Markdown view
and /api/capital say the same thing as the HTML.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant