The ChainlinkUtil.sol
contract has sequencerUptimeFeed
checks in place to assert if the sequencer on Arbitrum
is running, but these checks are not implemented correctly. Since the protocol implements some checks for the sequencerUptimeFeed
status, it should implement all of the checks.
The chainlink docs say that sequencerUptimeFeed
can return a 0 value for startedAt
if it is called during an "invalid round".
startedAt: This timestamp indicates when the sequencer changed status. This timestamp returns
0
if a round is invalid. When the sequencer comes back up after an outage, wait for theGRACE_PERIOD_TIME
to pass before accepting answers from the data feed. SubtractstartedAt
fromblock.timestamp
and revert the request if the result is less than theGRACE_PERIOD_TIME
.
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 and answer
is 0. Further explanation can be seen as given by an official chainlink engineer as seen here in the chainlink public discord:
Chainlink Discord Message (must be a member of the Chainlink Discord Channel to view)
Bharath | Chainlink Labs — 03/03/2024 3:55 PM:
Hello, @EricTee An "invalid round" means 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. Normally, when a round starts,startedAt
is recorded, and the initial status (answer
) is set to0
. 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 from0
when there's a confirmed update different from the start time. This process helps avoid mistakes in judging if the sequencer is available, which could cause security issues. Making surestartedAt
isn't0
is crucial for keeping the system secure and properly informed about the sequencer's status.
Quoting Chainlink's developer final statement:
"Making sure startedAt
isn't 0
is crucial for keeping the system secure and properly informed about the sequencer's status."
This also makes the implemented check below in the ChainlinkUtil::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 SEQUENCER_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, and answer
, the initial status is set to be 0
. Note that docs say that if answer = 0
, sequencer is up, if equals to 1
, sequencer is down. But in this case here, answer
and startedAt
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 ChainlinkUtil::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 assert 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.
There was also recently a pull request to update the chainlink docs sample code with this information, because this check should clearly be displayed there as well.
Inadequate checks to confirm the correct status of the sequencerUptimeFeed
in ChainlinkUtil::getPrice
contract will cause getPrice()
to not revert even when the sequencer uptime feed is not updated or is called in an invalid round.
Manual Review
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.