Commit 6c23fbee authored by clabby's avatar clabby Committed by GitHub

feat(ctb): Prevent `extraData` from being too large in the `OutputBisectionGame` (#8729)

* Prevent `extraData` from being too long for the `OutputBisectionGame`

* semver
parent 5489b7ff
This diff is collapsed.
...@@ -100,8 +100,8 @@ ...@@ -100,8 +100,8 @@
"sourceCodeHash": "0xa995b54dce03ddf5c9c47451bd7181996b91398ad66b54ab0b8cbf582863a33e" "sourceCodeHash": "0xa995b54dce03ddf5c9c47451bd7181996b91398ad66b54ab0b8cbf582863a33e"
}, },
"src/dispute/OutputBisectionGame.sol": { "src/dispute/OutputBisectionGame.sol": {
"initCodeHash": "0xcf6ab94ff4048485d9d13753bb2c49e0af716a50c3d853ad187517a6bdb77070", "initCodeHash": "0x10596ff55c460324b6b442fe19d7f849e6dd8202c9b4514ca979ca02be339060",
"sourceCodeHash": "0x2963a04d32929665d1ca31d79b840068de0541d2e6f5e48e5655041b7e406d65" "sourceCodeHash": "0xe0fada6499eb1a24a4e1ccce50568f0b10617dec0fc8af189bff2c9ab4c320ce"
}, },
"src/legacy/DeployerWhitelist.sol": { "src/legacy/DeployerWhitelist.sol": {
"initCodeHash": "0x8de80fb23b26dd9d849f6328e56ea7c173cd9e9ce1f05c9beea559d1720deb3d", "initCodeHash": "0x8de80fb23b26dd9d849f6328e56ea7c173cd9e9ce1f05c9beea559d1720deb3d",
......
...@@ -81,8 +81,8 @@ contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver { ...@@ -81,8 +81,8 @@ contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver {
bool internal subgameAtRootResolved; bool internal subgameAtRootResolved;
/// @notice Semantic version. /// @notice Semantic version.
/// @custom:semver 0.0.17 /// @custom:semver 0.0.18
string public constant version = "0.0.17"; string public constant version = "0.0.18";
/// @param _gameType The type ID of the game. /// @param _gameType The type ID of the game.
/// @param _absolutePrestate The absolute prestate of the instruction trace. /// @param _absolutePrestate The absolute prestate of the instruction trace.
...@@ -454,6 +454,19 @@ contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver { ...@@ -454,6 +454,19 @@ contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver {
// Set the game's starting timestamp // Set the game's starting timestamp
createdAt = Timestamp.wrap(uint64(block.timestamp)); createdAt = Timestamp.wrap(uint64(block.timestamp));
// Revert if the calldata size is too large, which signals that the `extraData` contains more than expected.
// This is to prevent adding extra bytes to the `extraData` that result in a different game UUID in the factory,
// but are not used by the game, which would allow for multiple dispute games for the same output proposal to
// be created.
// Expected length: 0x46 (0x04 selector + 0x20 root claim + 0x20 extraData + 0x02 CWIA bytes)
assembly {
if gt(calldatasize(), 0x46) {
// Store the selector for `ExtraDataTooLong()` & revert
mstore(0x00, 0xc407e025)
revert(0x1C, 0x04)
}
}
// Set the root claim // Set the root claim
claimData.push( claimData.push(
ClaimData({ ClaimData({
......
...@@ -28,6 +28,9 @@ error UnexpectedRootClaim(Claim rootClaim); ...@@ -28,6 +28,9 @@ error UnexpectedRootClaim(Claim rootClaim);
/// cost of the next possible counter claim. /// cost of the next possible counter claim.
error BondTooLow(); error BondTooLow();
/// @notice Thrown when the `extraData` passed to the CWIA proxy is too long for the `FaultDisputeGame`.
error ExtraDataTooLong();
/// @notice Thrown when a defense against the root claim is attempted. /// @notice Thrown when a defense against the root claim is attempted.
error CannotDefendRootClaim(); error CannotDefendRootClaim();
......
...@@ -168,6 +168,28 @@ contract OutputBisectionGame_Test is OutputBisectionGame_Init { ...@@ -168,6 +168,28 @@ contract OutputBisectionGame_Test is OutputBisectionGame_Init {
gameProxy = OutputBisectionGame(address(factory.create(GAME_TYPE, claim, abi.encode(_blockNumber)))); gameProxy = OutputBisectionGame(address(factory.create(GAME_TYPE, claim, abi.encode(_blockNumber))));
} }
/// @dev Tests that the game cannot be initialized with extra data > 64 bytes long (root claim + l2 block number
/// concatenated)
function testFuzz_initialize_extraDataTooLong_reverts(uint256 _extraDataLen) public {
// The `DisputeGameFactory` will pack the root claim and the extra data into a single array, which is enforced
// to be at least 64 bytes long.
// We bound the upper end to 23.5KB to ensure that the minimal proxy never surpasses the contract size limit
// in this test, as CWIA proxies store the immutable args in their bytecode.
// [33 bytes, 23.5 KB]
_extraDataLen = bound(_extraDataLen, 33, 23_500);
bytes memory _extraData = new bytes(_extraDataLen);
// Assign the first 32 bytes in `extraData` to a valid L2 block number passed genesis.
uint256 genesisBlockNumber = gameProxy.genesisBlockNumber();
assembly {
mstore(add(_extraData, 0x20), add(genesisBlockNumber, 1))
}
Claim claim = _dummyClaim();
vm.expectRevert(abi.encodeWithSelector(ExtraDataTooLong.selector));
gameProxy = OutputBisectionGame(address(factory.create(GAME_TYPE, claim, _extraData)));
}
/// @dev Tests that the game is initialized with the correct data. /// @dev Tests that the game is initialized with the correct data.
function test_initialize_correctData_succeeds() public { function test_initialize_correctData_succeeds() public {
// Assert that the root claim is initialized correctly. // Assert that the root claim is initialized correctly.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment