It is not possible to reprove a withdrawal hash if CHALLENGER_WINS
Summary
If CHALLENGER_WINS, user cannot reprove a withdrawal.
Vulnerability Detail
When proving a withdrawal, the user can reprove a withdrawal if either of these 4 conditions exist:
require(
provenWithdrawal.timestamp == 0 || oldGame.status() == GameStatus.CHALLENGER_WINS
|| disputeGameBlacklist[oldGame] || oldGame.gameType().raw() != respectedGameType.raw(),
"OptimismPortal: withdrawal hash has already been proven, and the old dispute game is not invalid"
);
The withdrawal is not proven yet
The status resolves to CHALLENGER_WINS
The disputeGame is in blacklist
The gameType has changed.
However, oldGame.status() == GameStatus.CHALLENGER_WINS cannot be possible because of the above check that the status cannot be CHALLENGER_WINS.
// We do not allow for proving withdrawals against dispute games that have resolved against the favor
// of the root claim.
require(
> gameProxy.status() != GameStatus.CHALLENGER_WINS,
"OptimismPortal: cannot prove against invalid dispute games"
);
IDisputeGame oldGame = provenWithdrawal.disputeGameProxy;
require(
provenWithdrawal.timestamp == 0 || oldGame.status() == GameStatus.CHALLENGER_WINS
|| disputeGameBlacklist[oldGame] || oldGame.gameType().raw() != respectedGameType.raw(),
"OptimismPortal: withdrawal hash has already been proven, and the old dispute game is not invalid"
);
When users prove a transaction, the oldGame can never be CHALLENGER_WINS because the status of the gameProxy cannot be CHALLENGER_WINS.
Remove this require status that checks whether the game is not CHALLENGER_WINS (It does not really matter because in finalize withdrawal, the game must resolve to DEFENDER_WINS).
peanuts
medium
It is not possible to reprove a withdrawal hash if CHALLENGER_WINS
Summary
If CHALLENGER_WINS, user cannot reprove a withdrawal.
Vulnerability Detail
When proving a withdrawal, the user can reprove a withdrawal if either of these 4 conditions exist:
However,
oldGame.status() == GameStatus.CHALLENGER_WINS
cannot be possible because of the above check that the status cannot be CHALLENGER_WINS.When users prove a transaction, the
oldGame
can never be CHALLENGER_WINS because the status of the gameProxy cannot be CHALLENGER_WINS.Impact
Users cannot reprove their withdrawal has if CHALLENGER_WINS.
Code Snippet
https://github.com/sherlock-audit/2024-02-optimism-2024/blob/main/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol#L275-L291
Tool used
Manual Review
Recommendation
Remove this require status that checks whether the game is not CHALLENGER_WINS (It does not really matter because in finalize withdrawal, the game must resolve to DEFENDER_WINS).