Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fibonacci - DisputeGameFactory DoS due to incorrect extra data #124

Closed
sherlock-admin4 opened this issue Apr 4, 2024 · 0 comments
Closed
Labels
Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label Medium A valid Medium severity issue Reward A payout will be made for this issue Sponsor Confirmed The sponsor acknowledged this issue is valid Won't Fix The sponsor confirmed this issue will not be fixed

Comments

@sherlock-admin4
Copy link

sherlock-admin4 commented Apr 4, 2024

fibonacci

medium

DisputeGameFactory DoS due to incorrect extra data

Summary

Extra data is utilized to pass the block number during the creation of a dispute game. If a game is instantiated with a block number that is lower than a previously resolved one, the game creation process will revert. Сreating a game with an intentionally inflated block number could potentially prevent the creation of new games in the future.

Vulnerability Detail

Extra data passed to the dispute game is abi.encode(uint256(l2BlockNumber)), which is the L2 block number that the proposer claims that the submitted output root (the rootClaim) corresponds to.

function l2BlockNumber() public pure returns (uint256 l2BlockNumber_) {
    l2BlockNumber_ = _getArgUint256(0x40);
}
...
function extraData() public pure returns (bytes memory extraData_) {
    // The extra data starts at the second word within the cwia calldata and
    // is 32 bytes long.
    extraData_ = _getArgDynBytes(0x40, 0x20);
}

Upon game resolution, the ANCHOR_STATE_REGISTRY is updated. If the game is resolved with the DEFENDER_WINS status, the block number is stored in the anchor registry state.

During the initialization of a new game, there is a check to ensure that the provided block number is greater than the one stored in the anchor registry state. If this condition is not met, the creation of a new game reverts.

function initialize() public payable virtual {
    ...
    // Grab the latest anchor root.
    (Hash root, uint256 rootBlockNumber) = ANCHOR_STATE_REGISTRY.anchors(GAME_TYPE);
    ...
    // Do not allow the game to be initialized if the root claim corresponds to a block at or before the
    // configured starting block number.
    if (l2BlockNumber() <= rootBlockNumber) revert UnexpectedRootClaim(rootClaim());
    ...
}

Therefore, if an attacker successfully resolves a game with a block number value, for example, type(uint256).max, no new games will be able to be created.

Let's examine several scenarios that illustrate how this can be achieved:

  1. There are several types of games, but only one type is currently active (respected) and can be used for the finalization of transactions. Users can create and participate in any of these games. Off-chain challenge agents do not monitor games of inactive types. Therefore, in the OptimismPortal2::finalizeWithdrawalTransaction process, there is a check to prevent users from creating invalid disputes.
function checkWithdrawal(bytes32 _withdrawalHash, address _proofSubmitter) public view {
    ...
    // The game must have been created after `respectedGameTypeUpdatedAt`. This is to prevent users from creating
    // invalid disputes against a deployed game type while the off-chain challenge agents are not watching.
    require(
        createdAt >= respectedGameTypeUpdatedAt,
        "OptimismPortal: dispute game created before respected game type was updated"
    );
   ...
}
  • Assume that respectedGameType is set to any type other than the dispute game.
  • An attacker creates a dispute game with extra data containing type(uint256).max.
  • Since no one is watching this game, it finishes with the DEFENDER_WINS status. The attacker may not even resolve the game at this moment.
  • When respectedGameType is changed to the dispute game, the attacker resolves the previously created game.
  • Transactions cannot be finalized using this game because its creation time is earlier than respectedGameTypeUpdatedAt. However, type(uint256).max as the block number still ends up in the anchor registry state.
  • As a result, no further dispute games can be created.
  1. Since the block number is not subject to validation during the game, an attacker can provide a valid rootClaim but extra data with an invalid block number and defend it.

  2. Additionally, according to the rules for this contest, there is an assumption that FaultDisputeGame can resolve incorrectly (e.g., can resolve to DEFENDER_WINS when it should resolve to CHALLENGER_WINS or vice versa). There is a protection mechanism, and such a game should be blacklisted afterwards. However, an invalid block number will be set in the anchor registry state anyway.

Impact

This issue prevents the creation of new dispute games.

Code Snippet

https://github.com/sherlock-audit/2024-02-optimism-2024/blob/main/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol#L372-L374
https://github.com/sherlock-audit/2024-02-optimism-2024/blob/main/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol#L401
https://github.com/sherlock-audit/2024-02-optimism-2024/blob/main/optimism/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol#L80-L86
https://github.com/sherlock-audit/2024-02-optimism-2024/blob/main/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol#L528-L539

Tool used

Manual Review

Recommendation

I do not have an exact solution. It seems like the design of storing the last resolved block number should be reviewed.

Duplicate of #90

@github-actions github-actions bot added High A valid High severity issue Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label labels Apr 11, 2024
@sherlock-admin2 sherlock-admin2 added Sponsor Confirmed The sponsor acknowledged this issue is valid Won't Fix The sponsor confirmed this issue will not be fixed labels Apr 11, 2024
@sherlock-admin3 sherlock-admin3 changed the title Bitter Ivory Baboon - DisputeGameFactory DoS due to incorrect extra data fibonacci - DisputeGameFactory DoS due to incorrect extra data Apr 23, 2024
@sherlock-admin3 sherlock-admin3 added the Reward A payout will be made for this issue label Apr 23, 2024
@Evert0x Evert0x added Medium A valid Medium severity issue and removed High A valid High severity issue labels May 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label Medium A valid Medium severity issue Reward A payout will be made for this issue Sponsor Confirmed The sponsor acknowledged this issue is valid Won't Fix The sponsor confirmed this issue will not be fixed
Projects
None yet
Development

No branches or pull requests

4 participants