The QUANTAMM protocol implements a single oracle staleness threshold per pool rather than per oracle. This design choice fails to account for the varying update frequencies (heartbeats) of different oracles across different chains and assets, potentially leading to either premature staleness flags for frequently updated oracles or delayed staleness detection for infrequently updated ones.
The issue stems from the protocol's implementation of oracle staleness threshold at the pool level rather than the oracle level:
The threshold is used uniformly for all oracles in UpdateWeightRunner._getData():
UpdateWeightRunner.sol#L360-L361
Pprotocol supports different EVM chains(OP Mainnet, Arbitrum, Ethereum Mainnet and Base), let's consider the ETH/USD oracles on different chains:
Ethereum Mainnet:
ETH/USD: ~1 hour heartbeat
Optimism:
ETH/USD: ~20 minutes heartbeat
Arbitrum:
ETH/USD: ~24 hours heartbeat
Even on the same chain, different tokens have varying heartbeats—the intervals at which their price data is updated on-chain. For example:
The DAI/USD oracle on Ethereum updates approximately every 1 hour.
The USDT/USD oracle on Ethereum has a significantly longer heartbeat, around 24 hours.
This variation in heartbeat frequencies creates a significant challenge:
If the pool's staleness threshold is set too low (e.g., 1 hour), oracles with longer heartbeats (like USDT/USD) may frequently and erroneously be marked as stale.
Conversely, if the threshold is set too high (e.g., 24 hours), it undermines the value of more frequent updates for oracles with shorter heartbeats (like DAI/USD).
This discrepancy highlights the need for staleness thresholds tailored to each oracle rather than a uniform value across the pool.
Inconsistent Price Validation: The uniform threshold may incorrectly flag prices as stale or valid, leading to:
False positives: Marking valid prices as stale for oracles with longer heartbeats
False negatives: Accepting outdated prices for oracles with shorter heartbeats
Manual Review
Implement per-oracle staleness thresholds:
Update the staleness check logic:
This is by design, staleness is a strategy aspect: it requires all data to have been updated within n minutes. No more precision needed.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.