Collateral oracles
Every collateral branch prices its collateral in USD through its own PriceFeed — used for liquidations, redemptions, and ICR/TCR. These are dual-source feeds (a Chronicle/Chainlink primary with a Chainlink fallback), with composite logic for derivatives (LSTs, WBTC/tBTC, sUSDS, PAXG) and a state-machine fallback to a last-good price on failure.
This page is the mechanism. The per-branch feed addresses are in Collateral oracle addresses; the risk parameters are in Collateral parameters. The RD market price — a different oracle for a different job — is the RD Market Oracle.
PriceFeed stack
Each collateral branch has its own price feed. The base contract is PriceFeedBase (Solidity 0.8.24); concrete feeds extend it for the specific collateral.
Concrete feeds
| Feed | Asset | Composition |
|---|---|---|
WETHPriceFeed | WETH | ETH/USD directly. |
WSTETHPriceFeed | wstETH | Composite: ETH/USD × Lido canonical rate (with an stETH/USD deviation check). |
RETHPriceFeed | rETH | Composite: ETH/USD × rETH/ETH (rETH rate provider). |
WEETHPriceFeed | weETH | Composite: ETH/USD × weETH/ETH (weETH rate provider). |
WBTCPriceFeed | WBTC | Composite: BTC/USD × WBTC/BTC. |
TBTCPriceFeed | tBTC | Composite: BTC/USD × tBTC/USD. |
SUSDSPriceFeed | sUSDS | Composite: USDS/USD × sUSDS/USD (sUSDS rate provider). |
PAXGPriceFeed | PAXG | Composite: PAXG/USD × XAU/USD. |
Full source addresses per feed: Collateral oracle addresses.
Base feeds: ETH/USD and BTC/USD
Most branches don't price their collateral against USD directly — they build on a shared base feed. Two do the heavy lifting:
- ETH/USD backs every ETH derivative:
WSTETHPriceFeed,RETHPriceFeed, andWEETHPriceFeedeach multiply it by their canonical rate. - BTC/USD backs the BTC derivatives:
WBTCPriceFeedandTBTCPriceFeed.
Because so many collaterals share them, a fault in one base feed doesn't stay local — it moves every derivative built on it. To keep that foundation honest, each base feed is backed by two independent oracle providers, Chronicle (primary) and Chainlink (fallback), resolved on every fetchPrice:
- Both healthy → cross-checked and combined. The two provider prices are compared against
BASE_USD_DEVIATION_THRESHOLD = 2%. A normal (liquidation / ICR) read takes the lower of the two — the conservative value. A redemption read takes the higher, but only when the two agree within 2%; if they diverge by more, it drops back to the lower. This gives redeemers a fair price when the providers agree while resisting upward manipulation when they don't. - Primary unusable → failover. If Chronicle is stale (beyond its configured staleness window), reverts, or returns an invalid response, the pair switches to serving Chainlink alone.
- Both unusable → last good + shutdown. If neither provider is usable, the feed returns the last cached good price with
oracleFailure = true, which makes the branch'sshutdownFromOracleFailure()callable (see Collateral shutdown).
BASE_USD_DEVIATION_THRESHOLD = 2%; if the primary goes stale or reverts the feed serves the fallback alone, and if both fail it returns the last-good price and flags the branch for shutdown. Every ETH/BTC derivative multiplies one of these base prices by its rate.Primary → fallback → last good
There is no mode enum. fetchPrice resolves the price per call by composing two OracleResponses in PriceFeedBase:
- Primary — the configured primary source (Chronicle on most branches; Chainlink on PAXG — see Collateral oracle addresses).
- Fallback — the configured fallback source (Chainlink), used when the primary is stale (older than 25 hours), reverts, or fails a sanity / cross-source deviation check.
- Last good price — if neither source is usable, the feed returns the last cached good price with
oracleFailure = true.
When a read returns oracleFailure = true, the branch's BorrowerOperations.shutdownFromOracleFailure() becomes callable, triggering branch shutdown (see Shutdown).
Deviation checks for derivatives
WSTETHPriceFeed enforces STETH_USD_DEVIATION_THRESHOLD = 1% between the Chainlink stETH/USD and the Chainlink ETH/USD × Lido canonical rate. If they diverge by more than 1% on a redemption call, the feed uses the lower of the two, protecting the protocol from claiming over-priced collateral. RETHPriceFeed applies the same kind of guard at RETH_ETH_DEVIATION_THRESHOLD = 2%.
Key constants
| Constant | Value | Purpose |
|---|---|---|
TARGET_DIGITS | 18 | Output precision |
BASE_USD_DEVIATION_THRESHOLD | 2% | Max primary-vs-fallback divergence (cross-source guard) |
STETH_USD_DEVIATION_THRESHOLD | 1% | wstETH redemption guard |
RETH_ETH_DEVIATION_THRESHOLD | 2% | rETH redemption guard |
Read interface
fetchPrice(bool _isRedemption) returns (uint256 price, bool oracleFailure)
viewLatestPrice(bool _isRedemption) returns (uint256) // view-only
previewWillShutdown(bool _isRedemption) returns (bool)
fetchPrice is mutating — it resolves primary→fallback (and may cache the last-good price) on each call. View-only callers (off-chain dashboards, helper contracts) use viewLatestPrice. The _isRedemption flag selects a slightly different validation path for redemption (more conservative for derivatives).
Failure modes
| Failure | Affected component | Protocol response |
|---|---|---|
| Primary stale | One branch's PriceFeed | Falls back to the fallback source; previewWillShutdown = true triggers callable shutdown |
| Primary wildly off | One branch's PriceFeed | Deviation check rejects; same fallback path |
| LST canonical rate diverges | wstETH / rETH / weETH feed | Conservative-side selection on redemption |
| Both sources fail | Affected branch | Shutdown via shutdownFromOracleFailure(); redemption proceeds on the discount schedule |
The protocol prefers degraded operation over false confidence: if a branch's collateral price isn't trustworthy, the branch is wound down via redemption rather than continuing on bad data.