You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Inability to Challenge Malicious Batches After Protocol Pause Exceeds ChallengeWindow
Summary
There is a vulnerability in the optimistic rollup contract that prevents sequencers from challenging malicious batches when the protocol pause time exceeds the ChallengeWindow.
Consider the following scenarios:
A sequencer submits a batch, and before it can be challenged, the protocol is paused.
A challenger initiates a challenge, but before calling proveState, the protocol is paused.
In both cases, the protocol pause leads to the deletion of challenges[batchChallenged]. Since there is no limit on how long the protocol can remain paused, if the pause duration exceeds the ChallengeWindow, the sequencers are no longer able to challenge the batch after unpausing. Worse, anyone can call the public finalizeBatch function to finalize the malicious batch, allowing invalid state transitions to be confirmed.
Proof of Concept (PoC)
Assume the previous batches have been finalized, and a sequencer submits a new batch. Challengers have until finalizationPeriodSeconds after the batch submission to challenge the batch. The finalizationPeriodSeconds is set during the batch submission as shown below through commitBatchfunction:
If the protocol is paused due to governance decisions, network issues, or any other reason before a challenge is completed or even initiated, the following code is executed within the setPause function:
functionsetPause(bool_status)externalonlyOwner{if(_status){_pause();// if challenge exist and not finished yet, return challenge deposit to challengerif(inChallenge){batchChallengeReward[challenges[batchChallenged].challenger]+=challenges[batchChallenged].challengeDeposit;
@>deletechallenges[batchChallenged];
@>inChallenge=false;}}else{_unpause();}}
In this code:
Pausing the protocol deletes the entire challenges[batchChallenged] data.
The inChallenge flag is set to false.
If the pause exceeds the finalizationPeriodSeconds, unpausing the protocol would make it impossible for anyone to challenge the batch. This happens because the challengeState function checks whether the batch is still within the ChallengeWindow:
functionchallengeState(uint64batchIndex)externalpayableonlyChallengernonReqRevertwhenNotPaused{require(!inChallenge,"already in challenge");require(lastFinalizedBatchIndex<batchIndex,"batch already finalized");require(committedBatches[batchIndex]!=0,"batch not exist");require(challenges[batchIndex].challenger==address(0),"batch already challenged");// check challenge window
@>require(batchInsideChallengeWindow(batchIndex),"cannot challenge batch outside the challenge window");
...
}
After unpausing, because the batch is no longer within the ChallengeWindow, this check fails and prevents anyone from challenging the batch.
Additionally, since the finalizeBatch function is public, anyone can call it to finalize the batch without restriction, allowing the malicious batch to be confirmed:
functionfinalizeBatch(bytescalldata_batchHeader)publicnonReqRevertwhenNotPaused{(uint256memPtr,bytes32_batchHash)=_loadBatchHeader(_batchHeader);uint256_batchIndex=BatchHeaderCodecV0.getBatchIndex(memPtr);require(committedBatches[_batchIndex]==_batchHash,"incorrect batch hash");require(batchExist(_batchIndex),"batch not exist");require(!batchInChallenge(_batchIndex),"batch in challenge");require(!batchChallengedSuccess(_batchIndex),"batch should be reverted");require(!batchInsideChallengeWindow(_batchIndex),"batch in challenge window");// Check and update last finalized batchrequire(finalizedStateRoots[_batchIndex-1]==BatchHeaderCodecV0.getPrevStateHash(memPtr),"incorrect previous state root");unchecked{require(lastFinalizedBatchIndex+1==_batchIndex,"incorrect batch index");lastFinalizedBatchIndex=_batchIndex;}
...
}
Important Note: If, before pausing the protocol, another sequencer has already challenged a batch and there is an active challenge, this bug remains valid because the setPause function deletes the entire challenges[batchChallenged]. As a result, the challenge is lost even though it was active before the pause. Therefore, additional time should be provided to challengers when the protocol is paused to ensure fair continuation of the challenge process.
Tool used
Manual Review
Recommendation:
To address the issue, the pause mechanism should be implemented more carefully. The key improvement is to account for the time the protocol spends in a paused state and extend the ChallengeWindow accordingly.
this bug poses a significant risk to the integrity of the optimistic rollup protocol. If not addressed, malicious actors could bypass the challenge process during protocol pauses, leading to the finalization of invalid batches. By implementing the proposed solution, we can ensure that challengers still have a fair opportunity to dispute batches even after long pauses, safeguarding the protocol's security.
The text was updated successfully, but these errors were encountered:
sherlock-admin3
changed the title
Gentle Gauze Chipmunk - Inability to Challenge Malicious Batches After Protocol Pause Exceeds ChallengeWindow
0xcoinymous - Inability to Challenge Malicious Batches After Protocol Pause Exceeds ChallengeWindow
Oct 16, 2024
0xcoinymous
High
Inability to Challenge Malicious Batches After Protocol Pause Exceeds ChallengeWindow
Summary
There is a vulnerability in the optimistic rollup contract that prevents sequencers from challenging malicious batches when the protocol pause time exceeds the
ChallengeWindow
.Consider the following scenarios:
proveState
, the protocol is paused.In both cases, the protocol pause leads to the deletion of
challenges[batchChallenged]
. Since there is no limit on how long the protocol can remain paused, if the pause duration exceeds theChallengeWindow
, the sequencers are no longer able to challenge the batch after unpausing. Worse, anyone can call the publicfinalizeBatch
function to finalize the malicious batch, allowing invalid state transitions to be confirmed.Proof of Concept (PoC)
Assume the previous batches have been finalized, and a sequencer submits a new batch. Challengers have until
finalizationPeriodSeconds
after the batch submission to challenge the batch. ThefinalizationPeriodSeconds
is set during the batch submission as shown below throughcommitBatch
function:If the protocol is paused due to governance decisions, network issues, or any other reason before a challenge is completed or even initiated, the following code is executed within the
setPause
function:In this code:
challenges[batchChallenged]
data.inChallenge
flag is set tofalse
.If the pause exceeds the
finalizationPeriodSeconds
, unpausing the protocol would make it impossible for anyone to challenge the batch. This happens because thechallengeState
function checks whether the batch is still within theChallengeWindow
:After unpausing, because the batch is no longer within the
ChallengeWindow
, this check fails and prevents anyone from challenging the batch.Additionally, since the
finalizeBatch
function is public, anyone can call it to finalize the batch without restriction, allowing the malicious batch to be confirmed:Important Note: If, before pausing the protocol, another sequencer has already challenged a batch and there is an active challenge, this bug remains valid because the
setPause
function deletes the entirechallenges[batchChallenged]
. As a result, the challenge is lost even though it was active before the pause. Therefore, additional time should be provided to challengers when the protocol is paused to ensure fair continuation of the challenge process.Tool used
Manual Review
Recommendation:
To address the issue, the pause mechanism should be implemented more carefully. The key improvement is to account for the time the protocol spends in a paused state and extend the
ChallengeWindow
accordingly.this bug poses a significant risk to the integrity of the optimistic rollup protocol. If not addressed, malicious actors could bypass the challenge process during protocol pauses, leading to the finalization of invalid batches. By implementing the proposed solution, we can ensure that challengers still have a fair opportunity to dispute batches even after long pauses, safeguarding the protocol's security.
The text was updated successfully, but these errors were encountered: