code-423n4 / 2024-05-arbitrum-foundation-validation

0 stars 0 forks source link

Using block.number as a time reference may be subjected to change if Ethereum upgrades #356

Open c4-bot-4 opened 4 months ago

c4-bot-4 commented 4 months ago

Lines of code

https://github.com/code-423n4/2024-05-arbitrum-foundation/blob/6f861c85b281a29f04daacfe17a2099d7dad5f8f/src/rollup/RollupUserLogic.sol#L109-L127

Vulnerability details

Impact

The deadline of the dispute game is dependent on Ethereum. If Ethereum decreases their block time dramatically, the dispute game deadline will be very narrow.

Proof of Concept

When confirming assertions, block.number is used as a unit of time measurement to check that the assertion has passed its deadline before it can be confirmed.

        // Check that deadline has passed
>       require(block.number >= assertion.createdAtBlock + prevConfig.confirmPeriodBlocks, "BEFORE_DEADLINE");

        // Check that prev is latest confirmed
        require(prevAssertionHash == latestConfirmed(), "PREV_NOT_LATEST_CONFIRMED");

        if (prevAssertion.secondChildBlock > 0) {
            // if the prev has more than 1 child, check if this assertion is the challenge winner
            ChallengeEdge memory winningEdge = IEdgeChallengeManager(prevConfig.challengeManager).getEdge(winningEdgeId);
            require(winningEdge.claimId == assertionHash, "NOT_WINNER");
            require(winningEdge.status == EdgeStatus.Confirmed, "EDGE_NOT_CONFIRMED");
            require(winningEdge.confirmedAtBlock != 0, "ZERO_CONFIRMED_AT_BLOCK");
            // an additional number of blocks is added to ensure that the result of the challenge is widely
            // observable before it causes an assertion to be confirmed. After a winning edge is found, it will
            // always be challengeGracePeriodBlocks before an assertion can be confirmed
>           require(
                block.number >= winningEdge.confirmedAtBlock + challengeGracePeriodBlocks,
                "CHALLENGE_GRACE_PERIOD_NOT_PASSED"
            );

The issue is that block.number is subjected to change by Ethereum.

Here is the historical chart of the block produced per second. It shows that at 2015, the block time used to be ~17 seconds, and now it is at ~12 seconds. In the future, with other upgrades, the block time can be further reduced.

Recommended Mitigation Steps

Use block.timestamp as a better unit for time measurement.

Assessed type

Context