aave-v3-core
aave-v3-core copied to clipboard
Bug: PriceOracleSentinel incorrectly reading L2 sequencer Chainlink feed state
PriceOracleSentinel disables Borrowing and Liquidations because it believes the L2 sequencer has failed the Chainlink health check. The lastUpdateTimestamp
is updated roughly every 24 hours by Chainlink even if the answer is unchanged, this causes borrowing and liquidations to be disabled for an hour roughly once per day even though the sequencer is healthy. I believe the startedAt
timestamp would reflect the timestamp of a new round (when the status has changed).
Existing code:
/**
* @notice Checks the sequencer oracle is healthy: is up and grace period passed.
* @return True if the SequencerOracle is up and the grace period passed, false otherwise
*/
function _isUpAndGracePeriodPassed() internal view returns (bool) {
(, int256 answer, , uint256 lastUpdateTimestamp, ) = _sequencerOracle.latestRoundData();
return answer == 0 && block.timestamp - lastUpdateTimestamp > _gracePeriod;
}
Proposed fix:
/**
* @notice Checks the sequencer oracle is healthy: is up and grace period passed.
* @return True if the SequencerOracle is up and the grace period passed, false otherwise
*/
function _isUpAndGracePeriodPassed() internal view returns (bool) {
(, int256 answer, uint256 startedAt, , ) = _sequencerOracle.latestRoundData();
return answer == 0 && block.timestamp - startedAt > _gracePeriod;
}
Chainlink docs sample code: https://docs.chain.link/data-feeds/l2-sequencer-feeds#example-code