The ChainlinkUtil contract has sequencerUptimeFeed checks to verify if the sequencer on an L2 is running but unfortunately these checks are not implemented properly.
The chainlink documentation states that the sequencerUptimeFeed may return a 0 value for startedAt if it is queried during an "invalid round."
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 and answer is 0.
This makes check below in ChainlinkUtil::getPrice
to be useless if its called in an invalid round:
Chainlink secuencer feed when a round start set startedAt
= 0 and answer
= 0. Later, both the answer and the time it was updated (updatedAt) are set at the same time after getting enough data from oracles, making sure that answer only changes from 0 when there’s a confirmed update different from the start time, So for an invalid round startedAt
= 0 and answer
= 0 and note that answer=0
means that the secuencer is up but startedAt=0
is saying was an invalid round so the answer can't be trusted. Making sure startedAt
isn’t 0 is crucial for keeping the system secure and properly informed about the sequencer’s status.
In the Case of Zaros protocol in an invalid round startedAt
= 0 and answer
= 0:
Won't revert with OracleSequencerUptimeFeedIsDown because answer is 0
Won't revert GracePeriodNotOver because timeSinceUp = block.timestamp - 0
-> timeSinceUp == block.timestamp
-> timeSinceUp will always be greater than SEQUENCER_GRACE_PERIOD_TIME
But the secuencer could be down
Missing checks to confirm the correct status of the SequencerUptimeFeed in ChainlinkUtil::getPrice
will cause getPrice() to not revert when the SequencerUptimeFeed is down in an invalid round.
VS Code
Add a check that reverts if startedAt is returned as 0.
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.