Oracles
Overview
Curvance routes protocol price reads through OracleManager. Markets and cTokens use this manager to price supported assets, Curvance cToken shares, collateral, and debt through a single integration surface.
The oracle layer has three jobs:
Map each supported asset to its configured pricing adaptor.
Normalize adaptor responses into 18-decimal price values.
Return an error code that tells calling contracts whether the price can be used for the requested operation.
Live market configuration is single-source per asset. The codebase contains dual-adaptor support, but external integrations should treat the active path as one approved adaptor per asset with heartbeat checks, positive-price checks, and optional price guards for pegged or reference-priced assets.
Architecture
OracleManager
OracleManagerOracleManager is the protocol-facing price hub. It stores approved adaptors, per-asset pricing configuration, and cToken-to-underlying mappings.
The manager exposes:
getPrice(asset, inUSD, getLower)for direct price reads.getPriceIsolatedPair(collateralToken, debtToken, errorCodeBreakpoint)for isolated-market collateral and debt pricing.getPricesForMarket(account, assets, errorCodeBreakpoint)for account-level market checks.getPricingAdaptors(asset)andisSupportedAsset(asset)for integration discovery.
When an input asset is a registered Curvance cToken, getPrice() resolves its underlying asset first, reads the underlying price, then multiplies by the stored cToken exchange rate. Lower-bound reads round down, and upper-bound reads round up.
Adaptors
Adaptors implement IOracleAdaptor. They are responsible for source-specific validation and return an IOracleAdaptor.PricingResult with:
price: the reported price.inUSD: whether the returned price is denominated in USD or the chain's native token.hadError: whether the adaptor found an invalid, stale, unsupported, or guarded price.
BaseOracleAdaptor provides the shared adaptor model: supported-asset tracking, per-asset price guards, price normalization to WAD scale, heartbeat-style data validation, and permission checks for configuration.
The current oracle source map includes three high-level categories:
Direct push-feed adaptors for externally reported prices.
Wrapped aggregator helpers that adjust an underlying feed by an exchange rate.
Pendle-specific adaptors that compose a quote-asset price with a TWAP-derived rate.
Direct feed and Pendle adaptor paths converge at IOracleAdaptor.getPrice() before OracleManager evaluates the result. Wrapped aggregator helpers sit behind compatible feed adaptors and adjust the value those adaptors read.
Price Guards
Price guards live on adaptors, not on OracleManager. A guard can set a minimum price and a maximum price for an asset in a specific denomination. If a guarded price falls below the configured minimum, the adaptor returns a zero price that bubbles up as an oracle error. If the price is above the configured maximum, the adaptor clamps the returned price to the maximum.
Price guards are configured for pegged or reference-priced assets where bounded movement is part of the market design. Volatile assets should not be documented as having guards by default.
See Price Guard for the guard configuration model.
Pricing Flow

A market, cToken, or integrator calls
OracleManager.If the input is a registered cToken, the manager resolves the underlying asset from
cTokens.The manager loads the asset's configured adaptor from
assetPricingConfig.The manager calls
IOracleAdaptor.getPrice(asset, inUSD, getLower).The adaptor validates source data, normalizes the price, applies any configured guard, and returns
PricingResult.If the adaptor returned the opposite denomination, the manager converts between USD and the chain's native token by pricing the native token through the same manager.
If the original input was a cToken, the manager multiplies the underlying price by the stored cToken exchange rate.
The manager returns
(price, errorCode)or reverts in market-specific helpers when the returned error code reaches the caller'serrorCodeBreakpoint.
The getLower flag controls conservative pricing direction. Collateral-side reads use the lower price, while debt-side reads use the higher price. This keeps solvency checks pessimistic for both sides of a position.
getPriceIsolatedPair() prices collateral cToken shares with the lower underlying price and a fresh exchange rate, then prices debt underlying with the higher underlying price. getPricesForMarket() follows the same direction per account asset: collateral snapshots use lower share prices, and debt snapshots use higher underlying prices.
Error Code Model
Oracle reads use numeric error codes:
0
NO_ERROR
The price read completed without an oracle error.
1
CAUTION
A dual-adaptor path found a partial failure or configured deviation. This path exists in source but is not the live single-adaptor model.
2
BAD_SOURCE
The price source failed, returned zero, returned stale or invalid data, or could not be trusted for the requested read.
getPrice() returns the error code with the price. It can still revert when the asset has no configured pricing path or an adaptor is not approved.
Market-facing helpers enforce the caller's breakpoint:
getPriceIsolatedPair(..., errorCodeBreakpoint)reverts withOracleManager__ErrorCodeFlagged()when either side reaches the breakpoint.getPricesForMarket(..., errorCodeBreakpoint)reverts withOracleManager__ErrorCodeFlagged()when any account asset reaches the breakpoint.
Liquidation and solvency paths choose their breakpoint based on the operation. Integrators should not assume every nonzero error code has the same effect across all callers.
Integration Considerations
Discover support through
isSupportedAsset(asset)orgetPricingAdaptors(asset)before relying on a price read.Read real manager and adaptor addresses from the deployment registry for the chain you are integrating. Do not hardcode sample addresses.
Treat prices as WAD-scaled values unless a downstream contract explicitly documents a different unit.
Pass
inUSD = truewhen matching Curvance market solvency paths, which price collateral and debt in USD.Use
getLower = truefor collateral-side previews andgetLower = falsefor debt-side previews.Do not treat price guards as global protection for every asset. Check adaptor guard configuration when a pegged or reference-priced asset depends on bounded pricing.
Do not continue a user flow after
BAD_SOURCE. The manager and market helpers use that condition to block unsafe operations.When reading cToken prices, remember that the manager prices cToken shares by combining underlying price with the cToken exchange rate.
Related Pages
Oracle Manager
Price Guard
Adaptors
Last updated
Was this helpful?