DeFiFoundry
50,000 USDC
View results
Submission Details
Severity: high
Invalid

Inverted Sequencer Status Check Leading to Unsafe Transaction Processing

Summary

The KeeperProxy contract contains a critical logic error in the sequencer status validation that inverts the intended behavior, allowing transactions to proceed when the L2 sequencer is down and blocking them when it's operational.

Vulnerability Details

The problem is in the _validatePrice function:

(
/*uint80 roundID*/,
int256 answer,
uint256 startedAt,
/*uint256 updatedAt*/,
/*uint80 answeredInRound*/
) = AggregatorV2V3Interface(sequencerUptimeFeed).latestRoundData();
bool isSequencerUp = answer == 0; // Critical error here
require(isSequencerUp, "sequencer is down");

The root cause is the incorrect interpretation of the sequencer feed's answer:

  • When answer = 0: Indicates sequencer is DOWN (isSequencerUp akan true)

  • When answer = 1: Indicates sequencer is UP (isSequencerUp akan false)

However, the code incorrectly sets isSequencerUp to true when answer is 0, completely inverting the security check. Akibatnya, transaksi akan lolos ketika sequencer sebenarnya DOWN dan gagal ketika sequencer UP.

This issue can result in transactions being processed while the L2 sequencer is down. On Arbitrum L2 network, the sequencer plays a critical role in sequencing transactions, ensuring consistency, and maintaining synchronization with the L1.

Impact

The transaction will pass when the actual sequencer is DOWN and fail when the sequencer is UP

Tools Used

  • Manual review

Recommendations

Fix the sequencer status check logic.

function _validatePrice(address perpVault, MarketPrices memory prices) internal view {
(
/*uint80 roundID*/,
int256 answer,
uint256 startedAt,
/*uint256 updatedAt*/,
/*uint80 answeredInRound*/
) = AggregatorV2V3Interface(sequencerUptimeFeed).latestRoundData();
// Fix: Sequencer is up when answer is 1
bool isSequencerUp = answer == 1;
require(isSequencerUp, "sequencer is down");
// Additional safety check
require(answer >= 0, "invalid sequencer status");
// Rest of the validation logic...
uint256 timeSinceUp = block.timestamp - startedAt;
require(timeSinceUp > GRACE_PERIOD_TIME, "Grace period is not over");
...
}
Updates

Lead Judging Commences

n0kto Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.