Oracle health
developerThe eight health states, staleness rules, and the uiMultiplier trap.
Address identity
Pricing starts where the asset registry starts: the token address is the identity. A feed is only ever attached to a verified canonical address — never looked up by ticker, because tickers can collide and the docs ticker can even differ from the on-chain symbol (see CUSO/USO).
The eight health states
Every price evaluation resolves to exactly one state. Order matters: pause and sequencer problems mask price data entirely, because a "fresh" price during an outage is still untrustworthy.
| State | Meaning | Priced? |
|---|---|---|
| OK | Fresh, positive price from a configured feed; sequencer healthy. | yes |
| STALE | The feed's last update is older than the staleness limit (default 3600s). | no |
| INVALID_PRICE | The feed answered zero/negative, or the round is incomplete (updatedAt ≤ 0). | no |
| MISSING_FEED | No Chainlink feed proxy is configured for this asset — the current state for most assets. | no |
| SEQUENCER_DOWN | The L2 sequencer uptime feed reports down; feed values may be frozen. | no |
| GRACE_PERIOD | The sequencer just recovered; prices stay untrusted for a grace window (default 1800s). | no |
| ORACLE_PAUSED | The oracle reports paused — often a corporate action. Price data is masked entirely. | no |
| UNKNOWN | A feed is configured but no reading was supplied to the evaluator. | no |
Staleness
A reading is stale when now − updatedAt exceeds the staleness limit (default 3600 seconds; each manifest can tighten it via risk.oracleStalenessSeconds). Stock feeds update 24/5 — weekends carry Friday's close, identically for everyone, which is why Basket Wars flags rather than reprices degraded oracles.
uiMultiplier: never double-apply
Robinhood Chain Stock Tokens expose a uiMultiplier() that reflects corporate actions (splits, etc.). The critical rule: the Chainlink feed price is the token price and already includes the multiplier. The multiplier exists only to display share-equivalent units. Applying it to the feed price double-counts corporate actions.
// USD value of a raw token amount — the ONLY valuation formula:
value = rawTokenAmount * feedPrice;
// Share-equivalent units, for DISPLAY only:
shareEquivalent = rawTokenAmount * uiMultiplier;
// WRONG — double-counts corporate actions:
value = rawTokenAmount * uiMultiplier * feedPrice; // never do thisCorporate actions can change uiMultiplier() at any time, so never cache share-equivalent math.
Why live pricing is off
Chainlink feed proxy addresses for Robinhood Chain are not listed on the official contracts page and have not been independently pinned, so every registry entry currently has an undefined priceFeedAddress — which means MISSING_FEED and no live valuation, by design. Until each proxy is pinned from the official Chainlink directory, all pricing comes from the deterministic mock oracle.