Stock Oracle
Contract Overview
StockOracle stores one latest price payload per supported bytes32 priceId. The same oracle proxy can serve all stock symbols on a chain; it does not deploy one feed contract per symbol.
The oracle supports:
single and batch price reads
freshness-checked reads
session-aware payloads
bid and ask values alongside the main oracle price
All price fields use 8 decimals.
Deployment and Backend Enablement
The integration draft records the intended mainnet proxy address as the same deterministic address on Ethereum, Monad, and Base:
Ethereum
1
0x037848af338c38e1e0ab722be80bf4c2e612a1f7
Monad
143
0x037848af338c38e1e0ab722be80bf4c2e612a1f7
Base
8453
0x037848af338c38e1e0ab722be80bf4c2e612a1f7
The draft also records implementation address 0x8745912828473e9bef9d843ce8629bee3dcb9fec for reference only. Consumers should integrate with the proxy address, not the implementation address.
Price IDs
Each supported asset is identified by bytes32 priceId.
The standard derived ID is:
For example, the backend derives AAPL from the uppercase symbol bytes. Deployment scripts may also accept an explicit bytes32 priceId; if omitted, they use the same uppercase-symbol derivation.
Before reading a price, consumers can check:
isSupportedPriceId=true means the ID is registered. hasPrice=true means at least one price has been published.
Price Payload
Oracle reads return:
price
Main oracle price, 8 decimals. Backend currently uses bid/ask midpoint.
bestBid
Best bid price, 8 decimals.
bestAsk
Best ask price, 8 decimals.
feedUpdateTimestamp
Source quote timestamp, in Unix seconds. Use this for freshness.
publishedAt
On-chain publish timestamp for this oracle round, in Unix seconds.
roundId
Monotonic oracle update round for this priceId.
session
Market session associated with the source quote.
Consumers should use feedUpdateTimestamp for staleness checks. publishedAt only says when the payload was written on-chain.
Read APIs
Single-asset reads:
Batch reads:
Prefer latestPriceNoOlderThan or latestPricesNoOlderThan when the consuming contract must fail closed on stale source data. maxAge is denominated in seconds.
Current backend feeder comments note that the source quote can be about 15 minutes delayed. With the default 10-minute heartbeat, a consumer using latestPriceNoOlderThan(maxAge) should choose a maxAge that accounts for feed delay plus heartbeat and integration-specific risk tolerance; 25 minutes / 1500 seconds is a practical lower-bound example before adding any product-specific buffer.
Read-Side Reverts
PriceIdNotFound
The priceId is not registered.
PriceNotAvailable
The priceId is registered but no price has been published.
PriceTooOld
block.timestamp - feedUpdateTimestamp > maxAge.
Write-Side Constraints
The backend feeder and deployment scripts are expected to satisfy these constraints before publishing:
Registering IDs
registerPriceId and batchRegisterPriceIds require DEFAULT_ADMIN_ROLE.
Updating prices
updatePrice and batchUpdatePrice require OPERATOR_ROLE.
Price validity
price, bestBid, and bestAsk must be positive and fit into int128.
Spread validity
bestBid cannot exceed bestAsk.
Source timestamp
feedUpdateTimestamp cannot be in the future and cannot roll back below the current on-chain value.
Same timestamp
If feedUpdateTimestamp equals the current on-chain timestamp, the update is allowed only for a CLOSED carried-forward update with unchanged price, bid, and ask.
These details are mainly useful for debugging feeder reverts and operational incidents. Normal readers do not need write permissions.
Session Handling
Consumers should treat session as part of the risk model, not just display metadata.
Regular-session prices are generally the most liquid. Pre-market, post-market, and overnight prices may have wider spreads or lower coverage. CLOSED means the oracle carried forward the latest on-chain price into a closed-market state; it should not be treated the same as an active quote unless the integration explicitly supports that behavior.
For lending or risk-sensitive integrations, define per-asset and per-session controls for:
maximum accepted age
accepted spread or spread-derived haircut
whether
CLOSEDprices are allowedfallback behavior when
PriceIdNotFound,PriceNotAvailable, orPriceTooOldoccurs
Last updated