The ChainlinkUtil
contract has sequencerUptimeFeed checks in place to assert if the sequencer on the L2 is running but these checks are not implemented correctly. According to the chainlink docs the sequencerUptimeFeed can return a 0 value for startedAt
if it is called during an "invalid round".
Consider a scenario where a round begins with `startedAt` recorded as 0 and the answer is initially set to 0. According to the documentation, an `answer` of 0 indicates the sequencer is up, while an `answer` of 1 means the sequencer is down. However, in this situation, both `answer` and `startedAt` can initially be `0` until all data is received from oracles and the update is confirmed. After this, the values are adjusted to reflect the accurate status of the sequencer.
in such a scenario the checks in _validatePrice()
will not sufficiently check against an invalid sequencer as `answer` will be zero and so will `startedAt` passing the second check as `block.timestamp` minus o will still be block.timestamp which is greater than GRACE_PERIOD_TIME
.
It has been established that startedAt
is another important value that must be verified to ensure an active sequencer, with the current implementation of getPrice()
an invalid can still be passed active thus defeating the purpose of a sequencerFeed check
This will lead to getPrice()
not reverting in an invalid round, which goes against the intention of the developers.
Manual Review
A check should be added that reverts if `startedAt` is returned as 0.
startedAt is only 0 when contract is not initialized on Arbitrum, but it is already initialized on Arbitrum. startedAt is sufficient for the protocol, it does not need roundID. Current documentation of Chainlink does not have this sentence: “This timestamp returns `0` if a round is invalid.“
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.