`BalancerOracle::update()` can return stale price
Opened this issue · 0 comments
Lines of code
Vulnerability details
Impact
Whenever block.timestamp - lastUpdate > updateWaitWindow and needs to update the price it will return a stale price because it will fetch the price from the lastUpdate not the currentUpdate.
Proof of Concept
In the update() function these are the lines we'll find
//@audit lets say price is out of date and its getting updated won't it get the pric from one hour ago?
//problem is it uses a current timestamp but with an hour old price
if (block.timestamp - lastUpdate < updateWaitWindow) revert BalancerOracle__update_InUpdateWaitWindow();
// update the safe price first
safePrice = safePrice_ = currentPrice;
lastUpdate = block.timestamp;
uint256[] memory weights = IWeightedPool(pool).getNormalizedWeights();
uint256 totalSupply = IWeightedPool(pool).totalSupply();
uint256 totalPi = WAD;
uint256[] memory prices = new uint256[](weights.length);
// update balances in 18 decimals
for (uint256 i = 0; i < weights.length; i++) {
// reverts if the price is invalid or stale
prices[i] = _getTokenPrice(i);
uint256 val = wdiv(prices[i], weights[i]);
uint256 indivPi = uint256(wpow(int256(val), int256(weights[i])));
totalPi = wmul(totalPi, indivPi);
}
currentPrice = wdiv(wmul(totalPi, IWeightedPool(pool).getInvariant()), totalSupply);
from the code we can see that the currentPrice is the last thing updated.
and whenever there updateWindow reaches or passes for us to fetch a new price the safePrice is updated first which is the value from the lastUpdate which is "stale".
it can be argued that its a design decision meaning the updateWindow is just time it needs to fetch a new price but it doesn't mean the price is old. However the updateWindow can be passed and not updated right after meaning the price is two times back because it wasn't updated right away.
Tools Used
manual review
Recommended Mitigation Steps
Revisit the logic to be able to fetch fresh price whenever there need to be a new price fetched
Assessed type
Oracle