fix(revenue): bucket fees by true UTC days and detect frozen feeds - #16
Merged
Conversation
…erEVM Comment-only. The client that feeds the revenue breakdown's `priority` field was documented as a "Daily HyperEVM priority-fees burn chart". It is neither HyperEVM nor the whole of priority fees. Per the protocol docs there are two priority mechanisms, both on HyperCore and both burning HYPE: order priority, charged from undelegated staking balance as up to 8 bps of filled notional (IOC) or resting notional (ALO); and gossip priority, two Dutch auctions on a three-minute cycle for faster market-data reads, charged from spot balance, resetting at 10x the last winning bid with a 0.1 HYPE floor. This endpoint returns the first only. Worth knowing for whoever picks this up: gossip priority is already served by /hip3/priority-fees/gossip/*, but that feed has been frozen since 2026-07-11 — 200 rows all stamped that day, 8 of them ever cleared — so the stream cannot be added to revenue until the ingestion is fixed. HyperEVM priority is a third and unrelated stream. Its sink, the EVM zero address, has been flat for at least a week (282,606.50 HYPE, moving by 0.03 over seven days), so nothing is being lost by leaving it out. No behaviour changes; every number the API returns is unchanged. https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/priority-fees Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013zGKQKm432ZKEw1GjVWPZG
The daily series was built by diffing consecutive points of Hypurrscan's cumulative counter and filing each diff under the newer point's date. That measures the interval between two timestamps, not a calendar day, so a point landing early turns its day into a partial one. Harmless mid-series, fatal at the tail: production was serving $59,286 for 2026-07-26 against a real ~$675K, and $48 for the running day, which reads as a collapse rather than as data we do not have yet. Interpolate the counters onto UTC midnight and diff midnight to midnight instead. Every emitted day is now a true UTC day, the running day is never emitted, and an outage is spread across the days it spans rather than dumped on one: 2024-12-18 was showing a fabricated $24.1M record day for what was actually a sixteen-day gap. Lifetime moves by 0.06%, all of it the running day we now correctly withhold. The same blindness applied to source health. A frozen upstream keeps answering 200 with a stale payload, which bucketing turns into zeros indistinguishable from a quiet day, and priorityStatus only checked that the promise settled. It reported ok through sixteen consecutive days of silent zeros while HypeDexer's priority aggregation sat frozen at 2026-07-11. Both perp/spot and priority are now judged on the newest day they actually populate, and meta.coverage carries those dates so the client can stop a series at its real end. The computation moves to revenue.daily.ts as a pure function so it is testable without a singleton, Redis or upstream clients. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013zGKQKm432ZKEw1GjVWPZG
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The bug on production right now
/market/revenue/historyis serving $59,286 for 2026-07-26 and $48 for the running day, against a real ~$675K. On the charts that reads as the protocol collapsing.The daily series was built by diffing consecutive points of Hypurrscan's cumulative counter and filing each diff under the newer point's date. That measures the interval between two timestamps, not a calendar day. Harmless mid-series where points land every ~24h; fatal at the tail, where a cached snapshot whose newest point is intraday emits a day worth an hour of fees.
The same blindness applied to source health. A frozen upstream keeps answering 200 with a stale payload, which bucketing turns into zeros indistinguishable from a quiet day, and
priorityStatusonly checked that the promise settled. It has reportedokthrough sixteen consecutive days of silent zeros while HypeDexer's priority aggregation sits frozen at 2026-07-11 (its gossip auction endpoint is frozen at 2026-07-11T17:55:26 too).The fix
Interpolate the cumulative counters onto UTC midnight and diff midnight to midnight:
2024-12-18was showing a fabricated $24.1M record day for what was actually a sixteen-day gapBoth
perpSpotandpriorityare now judged on the newest day they actually populate, andmeta.coveragecarries those dates so the client can stop a series at its real end instead of drawing it to the floor.The computation moves to
revenue.daily.tsas a pure function, testable without a singleton, Redis or upstream clients.Impact on the numbers
Replayed against the full 587-point production series:
Lifetime moves 0.057%, almost all of it the running day we now correctly withhold. 29 days change materially, every one of them a poller hiccup the old diff had mis-attributed (2026-02-21
$110,734 → $503,665, 2026-02-22$966,679 → $583,126, and so on).Verification
111 passed,tsc --noEmitand eslint cleancoverage: {perpSpot: '2026-07-25', priority: '2026-07-11'},priority: 'stale'(wasok), no junk tail dayFront counterpart, which surfaces
coverageon the cards: Yaugourt/liquidterminal_front#12Follow-up, not in this PR
The priority feed itself is still frozen upstream. This PR stops us reporting zeros as fact; it cannot restore the data.
🤖 Generated with Claude Code
https://claude.ai/code/session_013zGKQKm432ZKEw1GjVWPZG