The OracleLib.sol
has a hardcoded TIMEOUT value, 3 hours, which is used in the staleCheckLatestRoundData()
function to know if the returned price is stale or not.
This is probably implemented since the primary tokens would be BTC, ETH, but from the public discord chat Patrick has stated the below as reply to a question on what type of tokens would be used:
weth & wbtc are the intended tokens, but any token with a USD chainlink price feed can work
Do note that since the heartbeats of both BTC and ETH feeds are 1 hr, this does not affect them but for different tokens this would be a big issue see Vulnerability Details
As previously stated in Summary, we can see from this line that TIMEOUT has been hardcoded to three hours.
Additionally it's been used here:
Now the issue is that 3 hours is actually too short for some feeds, take a very popular token as an example, USDC, note that USDC/USD has a 24 hour heartbeat, i.e 86400s .
Since timeout has been set to 10800 seconds, querying USDC/USD price will be constantly failing after 10800 seconds have passed since the USDC/USD feed has been updated and until it's updated again (in this case, the DoS will continue for 75600 seconds (21 hours) after every 10800 seconds (3 hours)).
Which means that all instances of querying prices would be affected, use the getUsdValue() as an example
Would be important to note that this function is also used while checking the health factor of an account, or while gettiing it's information, and multiple other instances within DSCEngine.sol:
This easily means that all the calculation of user's current state and their collateral value can't be accessed for those 21 hours, putting this in percentage, this means that critical functionalities for some users can't be processed 87.5% of the whole lifetime of DSC.
Criticial functionalities that use querying of prices could be blocked for 21 out of 24 hours everyday for the DSCEngine, to even worsen the case imagine user has two tokens with pricefeeds of 24 hours that get updated at different times, there is a high chance that the loop through all collateral tokens in the getAccountCollateralValue()
function would almost always fail, as there is a chance that the 10800 seconds window of one of these tokens would not coincide with the 10800 seconds of the other, essentially meaning that while one of the tokens is available the other would DOS, and when the latter is available the former causes a DOS.
Now imagine if the tokens with lengthy heartbeats are more than two in the array.
Manual Audit
Consider the heartbeat of feeds that are going to be integrated before setting TIMEOUT, if they have a very lengthy heartbeat, their stale timeout check should also be lengthy so as to curb the DOS.
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.