code-423n4 / 2024-07-optimism-findings

3 stars 0 forks source link

Attacker can continuously create games for not yet safe l2 blocks to prevent the update of anchor state #6

Open c4-bot-9 opened 4 months ago

c4-bot-9 commented 4 months ago

Lines of code

https://github.com/code-423n4/2024-07-optimism/blob/70556044e5e080930f686c4e5acde420104bb2c4/packages/contracts-bedrock/src/dispute/DisputeGameFactory.sol#L119-L123

Vulnerability details

Brief

When creating a dispute game, the output root should be one of the safe l2 block's. However, attacker can continuously create games for not yet safe l2 blocks. Honest party can no longer propose the root after it becomes safe, since UUID must be unique. As a result, no root can be sucessfully defended, the anchor state can no longer be updated and the fund on L2 will be frozen.

Proof of Concept

When creating a dispute game, the output root should be one of the safe l2 block's. Otherwise, the claim can be attacked.

However, function create needs uuid to be unique.

    // Compute the unique identifier for the dispute game.
    Hash uuid = getGameUUID(_gameType, _rootClaim, _extraData);

    // If a dispute game with the same UUID already exists, revert.
    if (GameId.unwrap(_disputeGames[uuid]) != bytes32(0)) revert GameAlreadyExists(uuid);

If an attacker has already made the claim of this block earlier, when the block is still unsafe, the correct claim can no longer be made.

Cost and Impact

Attacker can avoid losing the bond by making a attack move in the same transaction, needing 0.08 (create) + 0.08 (attack) = 0.16eth once. The fund will be withdrawable after 3.5 (game clock) + 7 (weth delay) = 10.5 days. Assume block time is 2s, the capital needed is 0.16 × 10.5 × 24 × 3600 ÷ 2 = 72576eth ≈ 237 million dollars. Assume interest rate is 3%, to freeze l2 fund for one year, the cost would be 237 million × 3% = 7.11 million dollars, while the loss would be 13.54 billion (Optimism + Base TVL) × 3% = 406.2 million dollars.

Fix

Include parentHash in uuid calculation.

Assessed type

Context

ajsutton commented 4 months ago

The report is correct, however the claimed loss is dramatically overstated since it is not expected that the entire TVL of op-mainnet and base are trying to be withdrawn. Additionally the attacker would have to ensure they create a proposal for every unsafe block before they become safe - if a single block is missed all pending withdrawals could be proven against the proposal for that block.

The attacker would also be relying on the batcher submitting transactions that exactly match the unsafe blocks. While this is typically the case and is intended in the smooth operation of a chain, it is not guaranteed. If the actual safe block did differ from the attacker's proposed root the actual root could still be used for a proposal. For any in progress games, the attacker would be at risk of losing the bond for both their root claim and their counter claim, as the value specified in the counter claim would now be invalid, allowing an honest actor to counter it and post their own counter to the root claim.

The attacker would also lose money in gas costs for creating each game (~421k gas each), posting the counter claim to avoid losing their bond (~231k gas each) and then reclaiming their bonds after the lock up period.

zobront commented 3 months ago

I respect the sponsor's perspective here that this issue is unlikely to become a serious concern, but after carefully considering it, I've decided that the ability to create failing games for valid output roots that will block the correct game from being created seems to be a valid issue. I will be downgrading to Medium and accepting.

c4-judge commented 3 months ago

zobront changed the severity to 2 (Med Risk)

c4-judge commented 3 months ago

zobront marked the issue as satisfactory

c4-judge commented 3 months ago

zobront marked the issue as selected for report

0xEVom commented 3 months ago

the ability to create failing games for valid output roots that will block the correct game from being created seems to be a valid issue

I completely agree with the above and I think this is a really nice finding.

However, the severity should be assessed according to the highest realistic impact and this finding fails to provide one that would qualify it for Medium severity.

Let's examine the costs of this attack. As @ajsutton mentioned, the costs are not limited to the opportunity cost of the significant capital required, but also include the gas cost of creating and resolving claims for every single block, in particular for:

creating each game (~421k gas each), posting the counter claim to avoid losing their bond (~231k gas each) and then reclaiming their bonds after the lock up period.

The latter requires:

All of this put together leads to a total of ~857k gas per censored block, which at an ETH price of $3k, a reasonable gas price of 20 gwei and a 2s L2 block time amount to a cost of $2,2 million per DAY that the attack is ongoing in addition to the already mentioned capital requirements and opportunity loss.

This together with the fact that the attack can be easily mitigated by migrating to a new game type means the likelihood that this is exploited (to no benefit for the attacker) and actually impacts the availability of the protocol is essentially non-existent. (Edit: just a quick note that migrating to a new game is not one of the safeguards that should be considered nonexistent for this audit)

The issue was also brought up here in the previous contest (specific attack vector of the L1 block being too early is mentioned "e.g., the L1 parent block is too early" as well as the inability to create another game, without the DOS claims).

xuwinnie commented 3 months ago

@0xEVom

  1. The impact is critical, not low. How could you call “freeze whole l2 fund for one year” low?
  2. Gas price has dropped after Cancun and will continue to drop. It should not be used as an argument. OP TVL will grow to 1 trillion and the attack cost will eventually be negligible.
  3. Attacker can short $OP to take profit, panic would be huge.
  4. In my report, neither L1 nor L2 block is too early.
  5. The report you mentioned misses two key points. It does not point of proposed block should be safe It does not utilize create game for every block to DOS. Basically it just says there could be something wrong without describing how it could actually be wrong.

For the sake of this audit, you should pretend the safeguards don't exist

Under the context of this audit, the max damage could be permanently freezing the l2 fund. So I believe this is a high severity issue @zobront

The attacker would also be relying on the batcher submitting transactions that exactly match the unsafe blocks.

Even they don't match, attacker can still monitor mempool and frontrun batcher's the transaction.

zobront commented 3 months ago

While I agree with @0xEVom that the cost to the attacker is large and doesn't provide obvious benefit (such that I don't think DOS'ing the chain for a year is at all likely), I do believe a Medium severity is justified.

1) As @xuwinnie mentioned, gas prices have dropped a lot. I don't think it's unreasonable to think that 2 gwei will often be a better estimate than 20 gwei.

2) At least to start, every OP Mainnet block doesn't need to be proven. Proposals are created once per hour (https://etherscan.io/address/0xe5965Ab5962eDc7477C8520243A95517CD252fA9), and if we read the op-proposer code (https://github.com/ethereum-optimism/optimism/blob/d283e9be6e3ff9294c61634bda0131c373ecaaf8/op-proposer/proposer/driver.go#L471-L492) we can see that it doesn't matter whether past proposals landed. It just tries at regular interval from config, which is set to 1 hour. Until OP team changed the config and relaunched the proposer, it would only take a couple txs per hour to make sure it was blocked.

3) We can't predict situations where delaying ability to withdraw for some period of time would be harmful.

I agree that this is unlikely and benefit is unclear enough that it shouldn't be a High, but I think Medium is warranted and the code should be corrected, so will keep judging as-is.

ajsutton commented 3 months ago

I'm staying well out of the debate around severity levels but I think it's worth clarifying:

At least to start, every OP Mainnet block doesn't need to be proven. Proposals are created once per hour

Proposals are permissionless, so any user whose withdrawal is blocked can propose for any L2 block (which could then be used for any pending withdawals). So for this attack to be at all effective you need to create a game for every L2 block, not just the block that winds up being the next safe head. Any user who would be harmed by a delay to their withdrawal would also be incentivised to make their own proposal.

zobront commented 3 months ago

@ajsutton That's fair. I still believe Medium is the right classification, but appreciate the correction.