Paboxo

Oracles

Chainlink feeds behind an adapter that knows when the market is shut.

Every price comes from a Chainlink Data Feed, read through a ChainlinkFeedAdapter that adds one thing the raw feed does not have: an opinion about whether the market is open.

How many assets can have a market

Counted from Chainlink's reference data directory on 2026-09-17: 35 feeds carry US equity market hours, against roughly 194 Stock Tokens in existence. A market cannot exist without a feed, so that is the ceiling on which assets Paboxo can list — about 18% of them.

Every one of those 35 shares the same configuration: an 86,400-second heartbeat, a 0.5% deviation threshold, and 8 decimals.

You may see it stated that every Stock Token has a live price feed. The directory does not support that, and these docs follow the directory.

Why an adapter

A raw feed reports a price and a timestamp. For an asset that trades continuously, a stale timestamp means something is broken. For a Stock Token it usually means it is Saturday.

Treating those two identically produces one of two failures — freeze the protocol every weekend, or price positions on a number that has been frozen for 60 hours while pretending it is live. The adapter separates them.

Status

Every read returns a status, and the contracts act on it rather than on the raw price alone:

StatusMeaning
0FreshUpdated within the in-session window. Everything allowed
1MarketClosedThe exchange is shut. Last price stands; borrowing and liquidations pause, withdrawals stay open
2StaleInSessionThe market should be open but the feed has not updated. Treated as a fault
3HardStalePast the hard cap. The price is not usable at all
4OraclePausedThe feed's own issuer has paused it
5InvalidAnswerThe feed returned something that cannot be a price

MarketClosed is the only one of these that is a normal condition rather than a problem.

Freshness windows

Two limits per adapter:

  • In-session max age — how stale a price may be while the market is open before it counts as StaleInSession.
  • Hard max age — the absolute ceiling. Past it the price is HardStale and unusable, open or closed.

On testnet these are set to 30 days in-session and 60 days hard, read from the deployed adapters on 2026-09-17. Those are deliberately loose because the testnet feeds are mocks that nobody updates on a schedule. They are not the values a mainnet deployment should carry, and tightening them is an outstanding task rather than a decision already made.

oraclePaused

The feed's issuer can pause it. When that happens the adapter reports OraclePaused and the protocol stops pricing on it, rather than continuing with the last number.

This is a real dependency worth naming: the party that can pause the feed is not the protocol and not you. See risks.

Market calendar

Whether the market is open is decided by a MarketCalendar contract, not by guessing from feed timestamps. It holds:

  • a weekly close window, stored as seconds since Monday 00:00 UTC — so it expresses "Saturday 01:00 UTC until Monday 01:00 UTC", not a time of day;
  • automatic daylight saving, computed on-chain from the US rule, so the window shifts without anyone sending a transaction on the switch dates;
  • a list of holiday closures as absolute ranges.

The NVDA and SPY adapters point at the calendar. The WETH and USDG adapters deliberately do not — those assets have no market hours.

Why not a TWAP or a pull oracle

A TWAP needs a liquid on-chain market in the asset to average over; Stock Tokens do not have one. A pull-based oracle would let whoever submits the price choose when to submit it, which for an asset with a scheduled close is an invitation rather than a risk. A push feed with a published schedule is the honest fit for an asset with published market hours.

On this page