fix(api): stop fabricating markPrice/indexPrice in live WS price ticks [BUG-101] - #218
fix(api): stop fabricating markPrice/indexPrice in live WS price ticks [BUG-101]#218Morenikeoa wants to merge 1 commit into
Conversation
…s [BUG-101] OraclePriceBroadcaster hardcoded markPriceE6 and indexPriceE6 to the same value as the single oracle push price on every oracle_prices INSERT, because that table only carries one price per row — there's no genuine mark/index price in this event source to report. ws.ts's flushPriceUpdate forwarded these fabricated values unchanged to every live WS subscriber, so every live price tick reported markPrice === indexPrice === oracle price, directly contradicting the correct, distinct values the same channel sends from market_stats on initial subscribe. On markets where mark/index price legitimately diverges from the oracle price (basis, funding skew), this was a real-time data-integrity bug, not just staleness — a client's first message after subscribing could show markPrice != indexPrice, then the very next live tick collapses them. Stop publishing markPriceE6/indexPriceE6 from this source entirely. flushPriceUpdate already has a `markPriceE6 ? ... : undefined` check (ws.ts) specifically meant to omit these fields when not genuinely known — it was just never reachable because the broadcaster always supplied a (wrong) value. No change needed in ws.ts; live ticks now correctly omit markPrice/indexPrice rather than reporting a fabricated one. Added tests verifying the published payload never carries markPriceE6/indexPriceE6, and that non-positive/non-finite prices are still ignored. Verified the test fails against the pre-fix code (received markPriceE6: 1500000 where it should be absent) and passes against the fix. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
|
@Princessdada is attempting to deploy a commit to the Khubair Nasir's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughOracle price inserts now publish ChangesOracle price publish payload
Estimated review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Problem
OraclePriceBroadcasterhardcodedmarkPriceE6/indexPriceE6to the same value as the single oracle push price on everyoracle_pricesINSERT. Theoracle_pricestable genuinely carries only one price per row — there's no separate mark/index price in this event source.ws.ts'sflushPriceUpdateforwards these fabricated values unchanged to every live WS subscriber.Impact
Every live WS price tick reported
markPrice === indexPrice === oracle price, directly contradicting the correct, distinct values the same channel sends frommarket_statson initial subscribe. On markets where mark/index price legitimately diverges from the oracle price (basis, funding skew), this is a real-time data-integrity bug, not just staleness — a client's first message after subscribing can showmarkPrice != indexPrice, then the very next live tick silently collapses them to equal.Fix
Stop publishing
markPriceE6/indexPriceE6from this source entirely.flushPriceUpdate(src/routes/ws.ts) already has amarkPriceE6 ? ... : undefinedcheck specifically meant to omit these fields from the outgoing WS message when not genuinely known — it was just never reachable because the broadcaster always supplied a (wrong) value. No change needed inws.ts: live ticks now correctly omitmarkPrice/indexPricerather than reporting a fabricated one, while the initial-subscribe snapshot continues to send the correct, distinct values frommarket_stats.I considered the alternative of having the broadcaster also query
market_statsfor genuine mark/index price on every oracle push, but that adds a DB round-trip to a high-frequency event path for values that update on a much slower cadence (crank-driven, not oracle-push-driven) — omitting the fields when not known is the more honest and lower-risk fix.Proof of Fix
New tests assert the published payload never carries
markPriceE6/indexPriceE6, and that non-positive/non-finite prices are still correctly ignored.Verified this is a genuine regression test: reverted just the source change and reran — failed with
markPriceE6: 1500000present where it should be absent. Restored the fix and it passes.tsc --noEmitclean (no separate lint script in this repo).Test Output
Full suite: 296/297 passed (294 baseline + 2 new). The 1 failure (
tests/sdk-smoke.test.ts) is pre-existing and unrelated — it asserts on an exact@percolatorct/sdkerror-message string that has drifted from the locally-resolved SDK version in this environment.Related
Found during a broader API audit; no existing open issue/PR covers this.
Summary by CodeRabbit
Bug Fixes
Tests