Venus Price Validation With ResilientOracle
Venus uses ResilientOracle to select asset prices for lending calculations through configurable main, pivot and fallback sources. A pivot can validate another source within asset-specific bounds, while a fallback offers an alternative when the preferred path fails. Those protections depend on the sources actually configured and enabled for the asset. Some configurations return a main price without cross-validation, so the component's name alone doesn't establish how a particular collateral market validates its valuation.
Last updated -
An enabled fallback provides a usable backup only when its price satisfies the asset's configured validation path.
Main, Pivot and Fallback Roles
ResilientOracle gives the main source priority, uses the pivot as a comparison anchor and considers the fallback when the preferred validation path can't return a price. Configuration belongs to an underlying asset address. A provider's name doesn't establish its role or whether its source participates in a read. Chainlink and RedStone integrations can occupy different roles across asset configurations.
Price selection returns a source's value through an ordered set of comparisons. With an enabled pivot, an uncached read tries main against pivot, then fallback against pivot. If neither succeeds, it can compare main against fallback and return main when that comparison passes. A missing, disabled or invalid source limits the available paths.
Does Every Venus Asset Receive Cross-Validation?
Cross-validation isn't universal: when an asset has no configured or enabled pivot, a successful nonzero main response can return without a bounds comparison. An enabled pivot that fails to provide a valid price creates a different situation. That failure doesn't automatically authorize an unchecked main response. The remaining main-to-fallback comparison must succeed for a price to return. If an asset's only enabled source fails, the oracle has no backup value to return.
Validation Bounds and Feed Freshness
BoundValidator tests agreement between candidate and anchor prices using lower and upper ratios configured for the underlying asset.
The comparison ratio divides the anchor price by the reported price.
Acceptance requires that ratio to remain within the configured bounds, including their endpoints. Reversing the numerator and denominator changes the test. Wider bounds admit larger differences between sources; narrower bounds reject more divergent responses. The asset's
validateConfigs
entry holds these parameters, and authorized governance can change them. A tolerance from another market doesn't establish this market's rules.
Feed freshness comes from the source adapter's own checks. When ChainlinkOracle reads its live feed, it rejects nonpositive answers, future timestamps and observations older than the asset's
maxStalePeriod. ResilientOracle doesn't impose one common expiry period on every adapter. Source agreement and source freshness address different failure conditions.
Sources can update on different schedules, so passing the bounds test doesn't establish that their observations share a timestamp.
A Compatible Price Read Through a Feed Failure
Hypothetical case: an integration requires a protocol-compatible USD price for a configured underlying asset. Assume the oracle is unpaused, its cache is empty and its main, pivot and fallback sources are enabled. Any required source snapshot updates have already occurred. Their responses use the same asset and price scale. The two possible outputs are the main price,
M, and fallback price,
F. The integration needs a valid configured path, so it requests the price through
getPrice(asset). Both candidate outputs face the same asset-specific pivot bounds.
In the normal case, the main source returns
M
and passes comparison with the pivot. The price read returns
M, giving the integration a value in the required format.
In the edge case, the main source reverts while the fallback returns
F
and validates against the pivot. The read returns
F, preserving compatibility through the configured backup. If the fallback also fails, the price read reverts in this assumed configuration. Recovery requires restored source responses or an authorized configuration repair. A successful retry establishes price availability for that execution, without completing a lending action.
Underlying Asset Units and Adapter Compatibility
Price compatibility requires the correct underlying asset, USD denomination and decimal scale, because similar integers can encode different values.
getUnderlyingPrice(vToken)
resolves a market's underlying asset before selecting its price.
getPrice(asset)
accepts that asset directly. Neither call calculates the redeemable value of one vToken receipt. That calculation also needs the market's exchange rate. Passing a receipt address to an interface that expects its underlying asset can therefore address the wrong configuration.
The ChainlinkOracle implementation scales a whole-token USD price by
10^(36 - d), where
d
is the underlying token's decimal count. The adapter read reverts if that count exceeds 18. For a live feed, it first normalizes the answer to 18 decimals. A feed with more than 18 decimals makes that read revert. The provider's raw answer and the adapter's returned integer consequently need different interpretations. Compatible source outputs must share the scale that the lending calculation expects.
Spot Prices and Protected Borrow Power
DeviationBoundedOracle can apply conservative borrow-power valuations to enabled assets while taking the selected spot price from ResilientOracle. During Protection Mode, collateral uses the lower of spot and the recent window low. Debt uses the higher of spot and the recent window high. Liquidation calculations continue to use the spot price. This layer requires the deployed Comptroller to route the relevant borrow-power reads through the wrapper and the asset's bounded-pricing flag to be enabled. Its constraints can reduce capacity for additional borrowing or collateral withdrawals while spot-based liquidation assessment remains separate.
Market Feeds, Correlated Prices and Source Independence
Adapter design determines whether a valuation follows a reported market price or a conversion relationship with another asset. CorrelatedTokenOracle families combine an on-chain exchange rate with a related underlying asset's USD price. That adds dependence on the conversion mechanism as well as the underlying price source. Earlier uncapped implementations and later implementations with optional exchange-rate growth caps have different behavior. The deployed adapter determines which rules apply. An exchange-rate-derived valuation also doesn't establish an executable market sale or redemption at that value.
Multiple enabled source roles offer useful alternatives only when their inputs and failure behavior suit the asset. Different provider labels don't establish complete independence if adapters share underlying prices or conversion assumptions. The live source addresses, enable flags and validator bounds determine the configured protection. Changes to those settings can alter future reads without changing the collateral token's identity. An installed adapter supplies a backup only when its role is enabled and its output satisfies the required validation path.
What to know about Venus
Can a Venus Oracle Use a Fixed Price Instead of a Live Feed?
ChainlinkOracle supports an authorized direct-price override for an asset. A nonzero override supplies the adapter's value without reading its normal live feed or applying that feed's timestamp checks. A fixed override remains subject to any source comparisons that the selection path performs. The override belongs to the source adapter, so other enabled sources can still supply different prices.
When Can a Sequencer-Aware Price Feed Resume After an Outage?
The v2.16.0 SequencerChainlinkOracle implementation rejects price reads while its sequencer feed reports an outage and during its one-hour recovery grace period. That rule applies to paths that use this adapter. Whether ResilientOracle can still return another price depends on its remaining enabled sources and the applicable validation path.
Does updatePrice Force the Provider to Publish a New Observation?
Calling updatePrice doesn't force an external provider to publish a new observation. The function attempts to update a supported capped main-source snapshot and can populate the transaction-local price cache when enabled. It catches snapshot-update errors, including calls to adapters that don't implement that interface. Integrations using capped sources need the expected update-before-read flow.
Are Cached ResilientOracle Prices Carried Into Later Transactions?
The implementation's transient price cache lasts only for the transaction that populates it. When an asset's cache is enabled and populated, subsequent reads in that transaction can reuse the selected price. The cache doesn't preserve that observation across later transactions.
Why Would a Price Comparison Fail Before Testing the Boundaries?
BoundValidator can reject a comparison because the asset lacks validation configuration or the anchor price is invalid. Missing bounds don't grant permission to accept arbitrary differences. This differs from an intentionally absent or disabled pivot, where the successful main-only path doesn't require that comparison.
Can I Give My Venus Position a Different Pivot Feed?
An ordinary borrower can't assign a private pivot feed to their position. ResilientOracle stores source roles by underlying asset, and changing them requires the applicable AccessControlManager permission. A token approval or wallet signature for a lending action doesn't grant that configuration authority. Authorized changes affect the asset's configured source path.
How Can an Integration Identify Which Feed Supplied a Returned Price?
The standard price read returns an integer without identifying the selected source role. Establishing the branch requires the enabled source configuration and relevant source responses for the same execution state, including any transaction-local cached price.