When fetching prices from different oracles in a pool, the protocol uses a single threshold timeout to check for oracle staleness. This can lead to unintended behavior, as Chainlink oracles have different refresh intervals.
The WeightedPool can contain different assets, so we need to set a separate oracle for each asset, as illustrated below.
Here, we set all the oracles for assets in the pool. Let’s take a look at where we define the oracleStalenessThreshold to check for oracle timeouts or stale prices.
At line 712, a single threshold timeout is set for all oracles to check for staleness when fetching price data.
If Oracle A has a refresh time of 1 day and Oracle B has a refresh time of 1 hour, it becomes unclear which threshold to set.
Setting the timeout to 1 day risks treating stale prices from Oracle B as the latest prices.
Conversely, setting the timeout to 1 hour could lead to unnecessary reverts for Oracle A, even when its price is still valid.
Code snippet where we check this timeout:
In a pool with multiple assets, using a single threshold to check oracle staleness poses challenges. If the timeout is set too high, stale prices might be wrongly accepted as the latest values. On the other hand, setting the timeout too low could result in valid prices being incorrectly rejected.
Manual Review
This issue can be resolved by setting a specific threshold for each oracle based on the staleness period defined by the Chainlink oracle.
This is by design, staleness is a strategy aspect: it requires all data to have been updated within n minutes. No more precision needed.
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.