Skip to main content
Stale price data is one of the most common — and most underestimated — risks in oracle-dependent protocols. A price feed that hasn’t updated recently may no longer reflect market reality. For stablecoins, even a small undetected depeg can trigger cascading liquidations, enable arbitrage at protocol expense, or silently under-collateralize positions. This page covers why staleness happens, how to detect it reliably, and how to build protocols that respond correctly when it occurs.

Why Staleness Happens

IFÁ Labs uses a hybrid deviation + time trigger model. A price update is pushed on-chain when either:
  • The aggregated price deviates beyond the configured threshold from the last on-chain value, or
  • A maximum time interval has elapsed since the last update
This means during periods of market stability — when a stablecoin is sitting tightly at its peg — updates are intentionally infrequent. The oracle is working correctly; it simply has nothing meaningful to report. Staleness is a problem in two scenarios:
  1. Your staleness threshold is too tight for the asset’s natural update cadence. You’re rejecting valid, accurate prices because your protocol expects more frequent updates than the oracle provides.
  2. A genuine delay has occurred — a relayer issue, source outage, or network congestion has prevented a timely update. The price may be stale and potentially inaccurate.
Handling both scenarios correctly requires different responses.

Detecting Staleness

The lastUpdateTime field returned by getAssetInfo is your signal. Compare it against block.timestamp to determine price age.
Always use block.timestamp for this comparison — never an off-chain timestamp passed as a parameter, which can be manipulated.

Staleness Check Patterns

Pattern 1: Hard Revert

The simplest and safest approach. If the price is stale, revert. The transaction fails cleanly and no logic executes against potentially outdated data.
Best for: Lending protocols, liquidation engines, minting functions — any high-stakes operation where proceeding with stale data is worse than failing.

Pattern 2: Fallback to Secondary Oracle

If the primary feed is stale, attempt a secondary oracle before reverting. This maximises uptime without compromising safety.
Best for: Protocols that need high availability and have a secondary oracle integration available. See Building Fallback Strategies for a complete implementation.

Pattern 3: Protocol Pause on Staleness

For critical protocols, stale data should trigger an automatic pause on sensitive operations — borrowing, liquidations, minting — while allowing safe operations like withdrawals to continue.
Best for: Lending and borrowing protocols where a stale price during liquidation could cause significant user harm.

Pattern 4: Cached Price with Extended Tolerance

For lower-stakes operations — dashboards, analytics views, non-critical displays — cache the last known good price and serve it with a wider tolerance window.
Never use cached prices for liquidation logic, collateral valuation, or any operation where an inaccurate price causes direct financial harm to users. Caching is appropriate only for read-only or display contexts.

Per-Asset Staleness Thresholds

Different assets have different update cadences. A single global threshold applied across all feeds will either be too tight for some assets or too loose for others. Use a mapping to manage per-asset configuration:

Diagnosing Staleness in Production

If your protocol is hitting staleness reverts unexpectedly, work through this checklist before adjusting thresholds:
1

Check the last update time on-chain

Go to the contract on Basescan → Read ContractgetAssetInfo → enter the asset ID. Check lastUpdateTime against the current block timestamp. Calculate the actual age in seconds.
2

Check the PriceUpdated event log

On Basescan → Events tab → filter by PriceUpdated and your asset ID. Look at the timestamp of the most recent event. This tells you the real update cadence for that asset.
3

Compare against your threshold

If the actual update interval is consistently longer than your MAX_PRICE_AGE, your threshold is too tight for this asset’s natural cadence. Widen it to match observed behaviour.
4

Check if all assets are affected

If every feed is stale simultaneously, the issue is likely a relayer delay rather than a per-asset problem. Monitor the IFÁ Labs Telegram or X for any announced incidents.
5

Report prolonged staleness

If a feed remains stale for more than 12 hours with no announcement, report it via support@ifalabs.com or the Telegram.

Best Practices Summary

  • Fail closed. Revert on stale data in critical paths. Never proceed with a potentially inaccurate price because it’s convenient.
  • Use per-asset thresholds. A single global MAX_PRICE_AGE doesn’t reflect the different update cadences of different assets.
  • Start wide, tighten with data. Deploy with a 2-hour threshold, observe real update patterns in production, and tighten from there.
  • Never adjust thresholds under pressure. If your protocol is hitting staleness reverts during a market event, that’s the system working correctly — not a bug to patch around.
  • Monitor off-chain. On-chain checks protect your contracts. Off-chain monitoring alerts your team before users are affected. See Running Price Monitoring.

Next Steps

Working with Asset IDs

Understand how asset IDs are generated and managed.

Building Fallback Strategies

Implement multi-oracle fallback for maximum protocol resilience.