Skip to content

grade each oracle feed against its own published promise, not a uniform bar - #2924

Merged
Flotapponnier merged 1 commit into
mainfrom
release/oracle-per-feed
Oct 9, 2026
Merged

Flotapponnier merged 1 commit into
mainfrom
release/oracle-per-feed

Conversation

@Flotapponnier

Copy link
Copy Markdown
Collaborator

Cherry-pick of #2923.

stale_but_moved graded every Chainlink feed against one uniform 0.5%/300s bar, while the feeds themselves run 0.5%/1h, 1%/24h and 2%/24h. AVAX/USD and BNB/USD were both flagged as late while behaving exactly as configured. Thresholds now come from Chainlink's own published directory, hardcoded and auditable in the diff.

Also pauses the RedStone poller: dead 64 days, and not restorable by a URL change. Its only live endpoint is an unfiltered 1.98 MB payload taking 12.7 s.

Nothing here is published today (bench 082's page is retired), so no reader was shown a false flag.

go build, go vet, pnpm validate clean.

…rm bar (#2923)

stale_but_moved claimed to fire when a feed is "late by its own standard".
It did not. Both thresholds were uniform constants, and the comment
justifying one of them was false: 0.5% was described as matching "the widest
deviation trigger configured on the measured Chainlink feeds" when per
Chainlink's own published directory the widest is 2%, four times that.

Measured, not theoretical: AVAX/USD at 7.6h and BNB/USD at 8.3h both read
stale_but_moved=1 at the time of writing while behaving exactly as
configured, because a 2%/24h feed was being graded against a 0.5%/300s bar.
SOL/USD was flagged the same way at 457s.

The real configuration, from
reference-data-directory.vercel.app/feeds-mainnet.json (fields threshold and
heartbeat), checked 2026-10-09 and hardcoded in config.go so every value is
auditable in the diff:

  BTC, ETH, LINK      0.5%   3600s
  BNB, MATIC          1%    86400s
  SOL, AVAX           2%    86400s

Each feed is now judged against its own promise. stale_but_moved fires when
the CEX reference crosses THAT feed's trigger and it still has not written
after a 300s grace, which is the time an oracle legitimately needs to observe,
aggregate and land a transaction. The new ocb_oracle_heartbeat_breach covers
the other half of the promise, and is published only for feeds that state a
heartbeat so an absent series cannot be read as "never breached".

Also pauses the RedStone poller, dead 64 days and invisible because bench
082's page is retired. Not a paywall and not a URL fix: its per-symbol API now
returns an empty array, and every documented replacement was probed. The only
live source is an unfiltered 1.98 MB payload taking 12.7 s, so ~237 MB/hour at
this cadence to learn an age that reads 15-25 s whenever you look.

go build and go vet clean, pnpm validate clean.
@Flotapponnier
Flotapponnier merged commit 66c46ed into main Oct 9, 2026
2 checks passed
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