"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 the GRACE_PERIOD_TIME to pass before accepting answers from the price data feed. Subtract startedAt from block.timestamp and revert the request if the result is less than the GRACE_PERIOD_TIME."
Recommendation
Check the startedAt returned of getSequencerStatus:
@@ -18,6 +18,8 @@ contract PriceOracleProxyETH is Exponential {
bool public constant isPriceOracle = true;
+ uint256 private constant GRACE_PERIOD_TIME = 3600;
+
/// @notice ChainLink aggregator base, currently support USD and ETH
enum AggregatorBase {
USD,
@@ -164,8 +166,9 @@ contract PriceOracleProxyETH is Exponential {
*/
function getSequencerStatus(address sequencer) internal view returns (bool) {
bool status;
- (, int256 answer, , , ) = AggregatorV3Interface(sequencer).latestRoundData();
- if (answer == 0) {
+ (, int256 answer, uint256 startedAt, , ) = AggregatorV3Interface(sequencer).latestRoundData();
+
+ if (answer == 0 && block.timestamp - startedAt > GRACE_PERIOD_TIME) {
status = true;
} else if (answer == 1) {
status = false;
Affected smart contract
Description
The function
getSequencerStatus
on contract PriceOracleProxyETH don't check the grace periodAttack scenario
If the
latestRoundData
returns 0 the round is invalidLook in Chainlink DOC
"
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 the GRACE_PERIOD_TIME to pass before accepting answers from the price data feed. Subtract startedAt from block.timestamp and revert the request if the result is less than the GRACE_PERIOD_TIME."Recommendation
Check the
startedAt
returned ofgetSequencerStatus
: