Inadequate checks to confirm the correct status of the sequecnce/sequecncerUptimeFeed in PriceFeed.getPrice()
contract.
#209
Labels
2 (Med Risk)
Assets not at direct risk, but function/availability of the protocol could be impacted or leak value
bug
Something isn't working
edited-by-warden
M-04
primary issue
Highest quality submission among a set of duplicates
🤖_primary
AI based primary recommendation
satisfactory
satisfies C4 submission criteria; eligible for awards
selected for report
This submission will be included/highlighted in the audit report
sponsor confirmed
Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")
sufficient quality report
This report is of sufficient quality
Lines of code
https://github.com/code-423n4/2024-06-size/blob/8850e25fb088898e9cf86f9be1c401ad155bea86/src/oracle/PriceFeed.sol#L63-L77
Vulnerability details
Bug Description
The
PriceFeed
contract has sequencerUptimeFeed checks in place to assert if the sequencer on an L2 is running but these checks are not implemented correctly. The chainlink docs say thatsequencerUptimeFeed
can return a 0 value forstartedAt
if it is called during an "invalid round".Please note that an "invalid round" is described to mean there was a problem updating the sequencer's status, possibly due to network issues or problems with data from oracles, and is shown by a
startedAt
time of 0 andanswer
is 0. Further explanation can be seen as given by an official chainlink engineer as seen here in the chainlink public discordhttps://discord.com/channels/592041321326182401/605768708266131456/1213847312141525002
This makes the implemented check below in the PriceFeed.getPrice() to be useless if its called in an invalid round.
as startedAt will be 0, the arithmetic operation block.timestamp - startedAt will result in a value greater than GRACE_PERIOD_TIME (which is hardcoded to be 3600) i.e block.timestamp = 1719739032, so 1719739032 - 0 = 1719739032 which is bigger than 3600. The code won't revert.
Imagine a case where a round starts, at the beginning
startedAt
is recorded to be 0, andanswer
, the initial status is set to be 0. Note that docs say that ifanswer
= 0, sequencer is up, if equals to 1, sequencer is down. But in this case here,answer
andstartedAt
can be 0 initially, till after all data is gotten from oracles and update is confirmed then the values are reset to the correct values that show the correct status of the sequencer.From these explanations and information, it can be seen that
startedAt
value is a second value that should be used in the check for if a sequencer is down/up or correctly updated. The checks in PriceFeed.getPrice() will allow for sucessfull calls in an invalid round because reverts dont happen if answer == 0 and startedAt == 0 thus defeating the purpose of having a sequencerFeed check to assertain the status of the sequencerFeed on L2 i.e if it is up/down/active or if its status is actually confirmed to be either.https://github.com/code-423n4/2024-06-size/blob/8850e25fb088898e9cf86f9be1c401ad155bea86/src/oracle/PriceFeed.sol#L68C1-L76C14
Impact
inadequate checks to confirm the correct status of the sequecncer/sequecncerUptimeFeed in
PriceFeed.getPrice()
contract will causegetPrice()
to not revert even when the sequcncer uptime feed is not updated or is called in an invalid round.Tools Used
manual review
Recommended Mitigation Steps
add a check that reverts if
startedAt
is returned as 0.Assessed type
Oracle
The text was updated successfully, but these errors were encountered: