diff --git a/packages/contracts-bedrock/interfaces/dispute/IDisputeGame.sol b/packages/contracts-bedrock/interfaces/dispute/IDisputeGame.sol index 85bb61606dea7..cae5a8fc9244e 100644 --- a/packages/contracts-bedrock/interfaces/dispute/IDisputeGame.sol +++ b/packages/contracts-bedrock/interfaces/dispute/IDisputeGame.sol @@ -13,6 +13,7 @@ interface IDisputeGame is IInitializable { function gameType() external view returns (GameType gameType_); function gameCreator() external pure returns (address creator_); function rootClaim() external pure returns (Claim rootClaim_); + function rootClaimByChainId(uint256 _chainId) external pure returns (Claim rootClaim_); function l1Head() external pure returns (Hash l1Head_); function l2SequenceNumber() external pure returns (uint256 l2SequenceNumber_); function extraData() external pure returns (bytes memory extraData_); diff --git a/packages/contracts-bedrock/interfaces/dispute/IFaultDisputeGame.sol b/packages/contracts-bedrock/interfaces/dispute/IFaultDisputeGame.sol index 86ace4d527077..cba277a4a26a6 100644 --- a/packages/contracts-bedrock/interfaces/dispute/IFaultDisputeGame.sol +++ b/packages/contracts-bedrock/interfaces/dispute/IFaultDisputeGame.sol @@ -74,6 +74,7 @@ interface IFaultDisputeGame is IDisputeGame { error UnexpectedList(); error UnexpectedRootClaim(Claim rootClaim); error UnexpectedString(); + error UnknownChainId(); error ValidStep(); error InvalidBondDistributionMode(); error GameNotFinalized(); @@ -121,6 +122,7 @@ interface IFaultDisputeGame is IDisputeGame { function move(Claim _disputed, uint256 _challengeIndex, Claim _claim, bool _isAttack) external payable; function normalModeCredit(address) external view returns (uint256); function refundModeCredit(address) external view returns (uint256); + function rootClaimByChainId(uint256 _chainId) external pure returns (Claim rootClaim_); function resolutionCheckpoints(uint256) external view diff --git a/packages/contracts-bedrock/interfaces/dispute/IPermissionedDisputeGame.sol b/packages/contracts-bedrock/interfaces/dispute/IPermissionedDisputeGame.sol index 788c65790c030..92dc3ddeeec8d 100644 --- a/packages/contracts-bedrock/interfaces/dispute/IPermissionedDisputeGame.sol +++ b/packages/contracts-bedrock/interfaces/dispute/IPermissionedDisputeGame.sol @@ -63,6 +63,7 @@ interface IPermissionedDisputeGame is IDisputeGame { error UnexpectedList(); error UnexpectedRootClaim(Claim rootClaim); error UnexpectedString(); + error UnknownChainId(); error ValidStep(); error InvalidBondDistributionMode(); error GameNotFinalized(); @@ -111,6 +112,7 @@ interface IPermissionedDisputeGame is IDisputeGame { function move(Claim _disputed, uint256 _challengeIndex, Claim _claim, bool _isAttack) external payable; function normalModeCredit(address) external view returns (uint256); function refundModeCredit(address) external view returns (uint256); + function rootClaimByChainId(uint256 _chainId) external pure returns (Claim rootClaim_); function resolutionCheckpoints(uint256) external view diff --git a/packages/contracts-bedrock/interfaces/dispute/ISuperFaultDisputeGame.sol b/packages/contracts-bedrock/interfaces/dispute/ISuperFaultDisputeGame.sol index 40f7b0e87cabd..314d1b1656e9b 100644 --- a/packages/contracts-bedrock/interfaces/dispute/ISuperFaultDisputeGame.sol +++ b/packages/contracts-bedrock/interfaces/dispute/ISuperFaultDisputeGame.sol @@ -105,6 +105,7 @@ interface ISuperFaultDisputeGame is IDisputeGame { function normalModeCredit(address) external view returns (uint256); function l2SequenceNumber() external pure returns (uint256 l2SequenceNumber_); function refundModeCredit(address) external view returns (uint256); + function rootClaimByChainId(uint256 _chainId) external pure returns (Claim outputRootClaim_); function resolutionCheckpoints(uint256) external view @@ -121,8 +122,6 @@ interface ISuperFaultDisputeGame is IDisputeGame { function vm() external view returns (IBigStepper vm_); function wasRespectedGameTypeWhenCreated() external view returns (bool); function weth() external view returns (IDelayedWETH weth_); - // TODO(#18516): Remove once IDisputeGame includes this interface - function rootClaimByChainId(uint256 _chainId) external view returns (Claim outputRootClaim_); function __constructor__(GameConstructorParams memory _params) external; } diff --git a/packages/contracts-bedrock/interfaces/dispute/ISuperPermissionedDisputeGame.sol b/packages/contracts-bedrock/interfaces/dispute/ISuperPermissionedDisputeGame.sol index 06e9d2cbd2519..1af339e77c17b 100644 --- a/packages/contracts-bedrock/interfaces/dispute/ISuperPermissionedDisputeGame.sol +++ b/packages/contracts-bedrock/interfaces/dispute/ISuperPermissionedDisputeGame.sol @@ -103,6 +103,7 @@ interface ISuperPermissionedDisputeGame is IDisputeGame { function normalModeCredit(address) external view returns (uint256); function l2SequenceNumber() external pure returns (uint256 l2SequenceNumber_); function refundModeCredit(address) external view returns (uint256); + function rootClaimByChainId(uint256 _chainId) external pure returns (Claim outputRootClaim_); function resolutionCheckpoints(uint256) external view @@ -119,8 +120,6 @@ interface ISuperPermissionedDisputeGame is IDisputeGame { function vm() external view returns (IBigStepper vm_); function wasRespectedGameTypeWhenCreated() external view returns (bool); function weth() external view returns (IDelayedWETH weth_); - // TODO(#18516): Remove once IDisputeGame includes this interface - function rootClaimByChainId(uint256 _chainId) external view returns (Claim outputRootClaim_); function __constructor__(ISuperFaultDisputeGame.GameConstructorParams memory _params) external; } diff --git a/packages/contracts-bedrock/interfaces/dispute/v2/IFaultDisputeGameV2.sol b/packages/contracts-bedrock/interfaces/dispute/v2/IFaultDisputeGameV2.sol index 3b31babbbabf1..35d896a1cb275 100644 --- a/packages/contracts-bedrock/interfaces/dispute/v2/IFaultDisputeGameV2.sol +++ b/packages/contracts-bedrock/interfaces/dispute/v2/IFaultDisputeGameV2.sol @@ -68,6 +68,7 @@ interface IFaultDisputeGameV2 is IDisputeGame { error UnexpectedList(); error UnexpectedRootClaim(Claim rootClaim); error UnexpectedString(); + error UnknownChainId(); error ValidStep(); error InvalidBondDistributionMode(); error GameNotFinalized(); @@ -114,6 +115,7 @@ interface IFaultDisputeGameV2 is IDisputeGame { function move(Claim _disputed, uint256 _challengeIndex, Claim _claim, bool _isAttack) external payable; function normalModeCredit(address) external view returns (uint256); function refundModeCredit(address) external view returns (uint256); + function rootClaimByChainId(uint256 _chainId) external pure returns (Claim rootClaim_); function resolutionCheckpoints(uint256) external view diff --git a/packages/contracts-bedrock/interfaces/dispute/v2/IPermissionedDisputeGameV2.sol b/packages/contracts-bedrock/interfaces/dispute/v2/IPermissionedDisputeGameV2.sol index 7db5da9e2f7fa..52419eea9d3a0 100644 --- a/packages/contracts-bedrock/interfaces/dispute/v2/IPermissionedDisputeGameV2.sol +++ b/packages/contracts-bedrock/interfaces/dispute/v2/IPermissionedDisputeGameV2.sol @@ -63,6 +63,7 @@ interface IPermissionedDisputeGameV2 is IDisputeGame { error UnexpectedList(); error UnexpectedRootClaim(Claim rootClaim); error UnexpectedString(); + error UnknownChainId(); error ValidStep(); error InvalidBondDistributionMode(); error GameNotFinalized(); @@ -110,6 +111,7 @@ interface IPermissionedDisputeGameV2 is IDisputeGame { function move(Claim _disputed, uint256 _challengeIndex, Claim _claim, bool _isAttack) external payable; function normalModeCredit(address) external view returns (uint256); function refundModeCredit(address) external view returns (uint256); + function rootClaimByChainId(uint256 _chainId) external pure returns (Claim rootClaim_); function resolutionCheckpoints(uint256) external view diff --git a/packages/contracts-bedrock/interfaces/dispute/zk/IOptimisticZkGame.sol b/packages/contracts-bedrock/interfaces/dispute/zk/IOptimisticZkGame.sol index 748ccb066420c..8ff83c79c8ced 100644 --- a/packages/contracts-bedrock/interfaces/dispute/zk/IOptimisticZkGame.sol +++ b/packages/contracts-bedrock/interfaces/dispute/zk/IOptimisticZkGame.sol @@ -72,6 +72,7 @@ interface IOptimisticZkGame is IDisputeGame, ISemver { function gameType() external view returns (GameType gameType_); function gameCreator() external pure returns (address creator_); function rootClaim() external pure returns (Claim rootClaim_); + function rootClaimByChainId(uint256) external pure returns (Claim rootClaim_); function l1Head() external pure returns (Hash l1Head_); function extraData() external pure returns (bytes memory extraData_); function gameData() external view returns (GameType gameType_, Claim rootClaim_, bytes memory extraData_); diff --git a/packages/contracts-bedrock/snapshots/abi/FaultDisputeGame.json b/packages/contracts-bedrock/snapshots/abi/FaultDisputeGame.json index 26a1351d53d79..57107a1de6fbd 100644 --- a/packages/contracts-bedrock/snapshots/abi/FaultDisputeGame.json +++ b/packages/contracts-bedrock/snapshots/abi/FaultDisputeGame.json @@ -781,6 +781,25 @@ "stateMutability": "pure", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + } + ], + "name": "rootClaimByChainId", + "outputs": [ + { + "internalType": "Claim", + "name": "rootClaim_", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "splitDepth", @@ -1212,6 +1231,11 @@ "name": "UnexpectedString", "type": "error" }, + { + "inputs": [], + "name": "UnknownChainId", + "type": "error" + }, { "inputs": [], "name": "ValidStep", diff --git a/packages/contracts-bedrock/snapshots/abi/FaultDisputeGameV2.json b/packages/contracts-bedrock/snapshots/abi/FaultDisputeGameV2.json index c3c9a6555f2a8..92cc0f80814e5 100644 --- a/packages/contracts-bedrock/snapshots/abi/FaultDisputeGameV2.json +++ b/packages/contracts-bedrock/snapshots/abi/FaultDisputeGameV2.json @@ -751,6 +751,25 @@ "stateMutability": "pure", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + } + ], + "name": "rootClaimByChainId", + "outputs": [ + { + "internalType": "Claim", + "name": "rootClaim_", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, { "inputs": [], "name": "splitDepth", @@ -1177,6 +1196,11 @@ "name": "UnexpectedString", "type": "error" }, + { + "inputs": [], + "name": "UnknownChainId", + "type": "error" + }, { "inputs": [], "name": "ValidStep", diff --git a/packages/contracts-bedrock/snapshots/abi/OptimisticZkGame.json b/packages/contracts-bedrock/snapshots/abi/OptimisticZkGame.json index 0109d574c03d2..5dc919132786b 100644 --- a/packages/contracts-bedrock/snapshots/abi/OptimisticZkGame.json +++ b/packages/contracts-bedrock/snapshots/abi/OptimisticZkGame.json @@ -505,6 +505,25 @@ "stateMutability": "pure", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "rootClaimByChainId", + "outputs": [ + { + "internalType": "Claim", + "name": "rootClaim_", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, { "inputs": [], "name": "sp1Verifier", diff --git a/packages/contracts-bedrock/snapshots/abi/PermissionedDisputeGame.json b/packages/contracts-bedrock/snapshots/abi/PermissionedDisputeGame.json index 8bb88f4663986..f9718eac61dcd 100644 --- a/packages/contracts-bedrock/snapshots/abi/PermissionedDisputeGame.json +++ b/packages/contracts-bedrock/snapshots/abi/PermissionedDisputeGame.json @@ -817,6 +817,25 @@ "stateMutability": "pure", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + } + ], + "name": "rootClaimByChainId", + "outputs": [ + { + "internalType": "Claim", + "name": "rootClaim_", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "splitDepth", @@ -1253,6 +1272,11 @@ "name": "UnexpectedString", "type": "error" }, + { + "inputs": [], + "name": "UnknownChainId", + "type": "error" + }, { "inputs": [], "name": "ValidStep", diff --git a/packages/contracts-bedrock/snapshots/abi/PermissionedDisputeGameV2.json b/packages/contracts-bedrock/snapshots/abi/PermissionedDisputeGameV2.json index 09352c2b75827..fb9900ca2d400 100644 --- a/packages/contracts-bedrock/snapshots/abi/PermissionedDisputeGameV2.json +++ b/packages/contracts-bedrock/snapshots/abi/PermissionedDisputeGameV2.json @@ -777,6 +777,25 @@ "stateMutability": "pure", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + } + ], + "name": "rootClaimByChainId", + "outputs": [ + { + "internalType": "Claim", + "name": "rootClaim_", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, { "inputs": [], "name": "splitDepth", @@ -1208,6 +1227,11 @@ "name": "UnexpectedString", "type": "error" }, + { + "inputs": [], + "name": "UnknownChainId", + "type": "error" + }, { "inputs": [], "name": "ValidStep", diff --git a/packages/contracts-bedrock/snapshots/semver-lock.json b/packages/contracts-bedrock/snapshots/semver-lock.json index dc38b2a02055f..fa3d1ac3b6e0d 100644 --- a/packages/contracts-bedrock/snapshots/semver-lock.json +++ b/packages/contracts-bedrock/snapshots/semver-lock.json @@ -196,12 +196,12 @@ "sourceCodeHash": "0xf19216b7943479af87a01ab8935e68561853e8e333d09719c917228bc7a01a3a" }, "src/dispute/FaultDisputeGame.sol:FaultDisputeGame": { - "initCodeHash": "0xe7d3c982532946d196d7efadb9e2576c76b8f9e0d1f885ac36977d6f3fb72a65", - "sourceCodeHash": "0x63222e6926c8dd050d1adc0e65039c42382f269c3b0e113751d79e7a5167b7ac" + "initCodeHash": "0x57b01ba6873a49b3adafe58d05e0e0c4f342281181682f9f7ecd30752395b4ad", + "sourceCodeHash": "0x04111af652e4a059b591da704a7d7a15dcb46a75be05fd7cad6b88c1b7a1ac1b" }, "src/dispute/PermissionedDisputeGame.sol:PermissionedDisputeGame": { - "initCodeHash": "0xefa478f976e55eb53fcccf653b202bc2532781230f20013450ce0845b77d815c", - "sourceCodeHash": "0x335a503a4cc02dd30d88d163393680f3fd89168e0faa4fa4b0ae5da399656f91" + "initCodeHash": "0xcd7a262ac008a2de347e459902ca7039c1c980eb312106b9cc2c1f3190ae0840", + "sourceCodeHash": "0x618013c7ad9742f59445f355f7b26347ee1727c9e6616218a6f3443f1b4bb8e0" }, "src/dispute/SuperFaultDisputeGame.sol:SuperFaultDisputeGame": { "initCodeHash": "0xb5ce71bc56109055cd0dc71fc63015443bbdb29c5975e049802cd1b5188f06ca", @@ -212,16 +212,16 @@ "sourceCodeHash": "0x314b6e0412f698ce3531e8176ce8e5b8a3976cc3fa9d7ecb1f3278612f90ed4e" }, "src/dispute/v2/FaultDisputeGameV2.sol:FaultDisputeGameV2": { - "initCodeHash": "0x6fc59e2da083c9e2093e42b0fda705e8215cc216e4dcedbf728c08f69ec2d3bd", - "sourceCodeHash": "0x7fc97734c12e207f011c4f079fffe84f5bd11f4fb4a95dd56ad6a69df184584f" + "initCodeHash": "0x2806f9c9f0babb80be2a0c40382d265d598632dc6c1902db7f5f8f214d233f2f", + "sourceCodeHash": "0x1ac7a6aa4adafe2058046f06a425c662369f756a89be956b5a222647d99fabe8" }, "src/dispute/v2/PermissionedDisputeGameV2.sol:PermissionedDisputeGameV2": { - "initCodeHash": "0x9896fd04e9a3f9fe4f1d6e93eb298b37a6bfa33424aa705e68cc58d0ba7f3f90", - "sourceCodeHash": "0xc0ff6e93b6e2b9111c11e81b5df8948ab71d02b9d2c4dfda982fcb615519f1f7" + "initCodeHash": "0xfbb451f1a0bf22bb96242db527371dd0b0c3435208f9e074441ec0aacbf414bd", + "sourceCodeHash": "0x92bb886203246108435408762fab6e56fe223c2ed5ae85b5b792653cead4ec7a" }, "src/dispute/zk/OptimisticZkGame.sol:OptimisticZkGame": { - "initCodeHash": "0x0e905fc81f45b1e9aa786e66bfe70b3ec4abd8d550be5d4c8f43cdad6f2618b2", - "sourceCodeHash": "0x162408c90e8d9d8afd982e9825db093eba5c387cbe1145c1a9b86e2361547138" + "initCodeHash": "0x6eff352a513e3ce2ac5c53e4094985bf2ae1acad3992d73d6564c95aca3aebf1", + "sourceCodeHash": "0x998796b0286830629cd50eeb003eec571680cd171f4ad80bd5cad53aca756909" }, "src/legacy/DeployerWhitelist.sol:DeployerWhitelist": { "initCodeHash": "0x2e0ef4c341367eb59cc6c25190c64eff441d3fe130189da91d4d126f6bdbc9b5", diff --git a/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol b/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol index 8689221a03a8a..97f4e0506ec35 100644 --- a/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol +++ b/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol @@ -58,7 +58,8 @@ import { GameNotResolved, ReservedGameType, GamePaused, - BadExtraData + BadExtraData, + UnknownChainId } from "src/dispute/lib/Errors.sol"; // Interfaces @@ -172,9 +173,9 @@ contract FaultDisputeGame is Clone, ISemver { uint256 internal constant HEADER_BLOCK_NUMBER_INDEX = 8; /// @notice Semantic version. - /// @custom:semver 1.8.0 + /// @custom:semver 1.9.0 function version() public pure virtual returns (string memory) { - return "1.8.0"; + return "1.9.0"; } /// @notice The starting timestamp of the game @@ -865,6 +866,14 @@ contract FaultDisputeGame is Clone, ISemver { rootClaim_ = Claim.wrap(_getArgBytes32(20)); } + /// @notice Getter for the root claim for a given L2 chain ID. + /// @param _chainId The L2 chain ID to get the root claim for. + /// @return rootClaim_ The root claim of the DisputeGame. + function rootClaimByChainId(uint256 _chainId) public view returns (Claim rootClaim_) { + if (_chainId != L2_CHAIN_ID) revert UnknownChainId(); + rootClaim_ = rootClaim(); + } + /// @notice Getter for the parent hash of the L1 block when the dispute game was created. /// @dev `clones-with-immutable-args` argument #3 /// @return l1Head_ The parent hash of the L1 block when the dispute game was created. diff --git a/packages/contracts-bedrock/src/dispute/PermissionedDisputeGame.sol b/packages/contracts-bedrock/src/dispute/PermissionedDisputeGame.sol index f356190ccdd7e..5dc45e46a3d37 100644 --- a/packages/contracts-bedrock/src/dispute/PermissionedDisputeGame.sol +++ b/packages/contracts-bedrock/src/dispute/PermissionedDisputeGame.sol @@ -32,9 +32,9 @@ contract PermissionedDisputeGame is FaultDisputeGame { } /// @notice Semantic version. - /// @custom:semver 1.8.0 + /// @custom:semver 1.9.0 function version() public pure override returns (string memory) { - return "1.8.0"; + return "1.9.0"; } /// @param _params Parameters for creating a new FaultDisputeGame. diff --git a/packages/contracts-bedrock/src/dispute/lib/Errors.sol b/packages/contracts-bedrock/src/dispute/lib/Errors.sol index 5779fc3f92e26..2f5ce0dd777d5 100644 --- a/packages/contracts-bedrock/src/dispute/lib/Errors.sol +++ b/packages/contracts-bedrock/src/dispute/lib/Errors.sol @@ -133,6 +133,9 @@ error GameNotResolved(); /// @notice Thrown when a reserved game type is used. error ReservedGameType(); +/// @notice Thrown when an unknown chain ID is passed to rootClaimByChainId. +error UnknownChainId(); + //////////////////////////////////////////////////////////////// // `PermissionedDisputeGame` Errors // //////////////////////////////////////////////////////////////// @@ -177,10 +180,3 @@ error InvalidProposalStatus(); /// @notice Thrown when the game is initialized by an incorrect factory. error IncorrectDisputeGameFactory(); - -//////////////////////////////////////////////////////////////// -// `SuperFaultDisputeGame` Errors // -//////////////////////////////////////////////////////////////// - -/// @notice Thrown when an unknown chain ID is encountered. -error UnknownChainId(); diff --git a/packages/contracts-bedrock/src/dispute/v2/FaultDisputeGameV2.sol b/packages/contracts-bedrock/src/dispute/v2/FaultDisputeGameV2.sol index eb373b027c45f..1072a12458c76 100644 --- a/packages/contracts-bedrock/src/dispute/v2/FaultDisputeGameV2.sol +++ b/packages/contracts-bedrock/src/dispute/v2/FaultDisputeGameV2.sol @@ -57,7 +57,8 @@ import { InvalidBondDistributionMode, GameNotResolved, GamePaused, - BadExtraData + BadExtraData, + UnknownChainId } from "src/dispute/lib/Errors.sol"; // Interfaces @@ -146,9 +147,9 @@ contract FaultDisputeGameV2 is Clone, ISemver { uint256 internal constant HEADER_BLOCK_NUMBER_INDEX = 8; /// @notice Semantic version. - /// @custom:semver 2.2.0 + /// @custom:semver 2.3.0 function version() public pure virtual returns (string memory) { - return "2.2.0"; + return "2.3.0"; } /// @notice The starting timestamp of the game @@ -845,6 +846,14 @@ contract FaultDisputeGameV2 is Clone, ISemver { rootClaim_ = Claim.wrap(_getArgBytes32(20)); } + /// @notice Getter for the root claim for a given L2 chain ID. + /// @param _chainId The L2 chain ID to get the root claim for. + /// @return rootClaim_ The root claim of the DisputeGame. + function rootClaimByChainId(uint256 _chainId) public pure returns (Claim rootClaim_) { + if (_chainId != l2ChainId()) revert UnknownChainId(); + rootClaim_ = rootClaim(); + } + /// @notice Getter for the parent hash of the L1 block when the dispute game was created. /// @dev `clones-with-immutable-args` argument #3 /// @return l1Head_ The parent hash of the L1 block when the dispute game was created. diff --git a/packages/contracts-bedrock/src/dispute/v2/PermissionedDisputeGameV2.sol b/packages/contracts-bedrock/src/dispute/v2/PermissionedDisputeGameV2.sol index d0a9faa9afe2f..9f2a58ab712b4 100644 --- a/packages/contracts-bedrock/src/dispute/v2/PermissionedDisputeGameV2.sol +++ b/packages/contracts-bedrock/src/dispute/v2/PermissionedDisputeGameV2.sol @@ -26,9 +26,9 @@ contract PermissionedDisputeGameV2 is FaultDisputeGameV2 { } /// @notice Semantic version. - /// @custom:semver 2.2.0 + /// @custom:semver 2.3.0 function version() public pure override returns (string memory) { - return "2.2.0"; + return "2.3.0"; } /// @param _params Parameters for creating a new FaultDisputeGame. diff --git a/packages/contracts-bedrock/src/dispute/zk/OptimisticZkGame.sol b/packages/contracts-bedrock/src/dispute/zk/OptimisticZkGame.sol index ee9ab2589b108..a9c91d6f28991 100644 --- a/packages/contracts-bedrock/src/dispute/zk/OptimisticZkGame.sol +++ b/packages/contracts-bedrock/src/dispute/zk/OptimisticZkGame.sol @@ -146,8 +146,8 @@ contract OptimisticZkGame is Clone, ISemver, IDisputeGame { AccessManager internal immutable ACCESS_MANAGER; /// @notice Semantic version. - /// @custom:semver 0.0.1 - string public constant version = "0.0.1"; + /// @custom:semver 0.0.2 + string public constant version = "0.0.2"; /// @notice The starting timestamp of the game. Timestamp public createdAt; @@ -592,6 +592,13 @@ contract OptimisticZkGame is Clone, ISemver, IDisputeGame { rootClaim_ = Claim.wrap(_getArgBytes32(0x14)); } + /// @notice Getter for the root claim for a given L2 chain ID. + /// @dev For pre-interop games, returns the root claim regardless of chain ID. + /// @return rootClaim_ The root claim of the DisputeGame. + function rootClaimByChainId(uint256) public pure returns (Claim rootClaim_) { + rootClaim_ = rootClaim(); + } + /// @notice Getter for the parent hash of the L1 block when the dispute game was created. /// @dev `clones-with-immutable-args` argument #3 /// @return l1Head_ The parent hash of the L1 block when the dispute game was created. diff --git a/packages/contracts-bedrock/test/dispute/AnchorStateRegistry.t.sol b/packages/contracts-bedrock/test/dispute/AnchorStateRegistry.t.sol index 2334ce904da4d..a33f69642154c 100644 --- a/packages/contracts-bedrock/test/dispute/AnchorStateRegistry.t.sol +++ b/packages/contracts-bedrock/test/dispute/AnchorStateRegistry.t.sol @@ -467,7 +467,7 @@ contract AnchorStateRegistry_GetStartingAnchorRoot_Test is AnchorStateRegistry_T // Mock the game's anchor root to be different from the starting anchor root. vm.mockCall( address(gameProxy), - abi.encodeCall(gameProxy.rootClaim, ()), + abi.encodeCall(IDisputeGame.rootClaim, ()), abi.encode(Claim.wrap(keccak256(abi.encode(123)))) ); diff --git a/packages/contracts-bedrock/test/dispute/FaultDisputeGame.t.sol b/packages/contracts-bedrock/test/dispute/FaultDisputeGame.t.sol index 3ad1f2a0b9e28..50599d9a950c4 100644 --- a/packages/contracts-bedrock/test/dispute/FaultDisputeGame.t.sol +++ b/packages/contracts-bedrock/test/dispute/FaultDisputeGame.t.sol @@ -2078,6 +2078,17 @@ contract FaultDisputeGame_RootClaim_Test is FaultDisputeGame_TestInit { function test_rootClaim_succeeds() public view { assertEq(gameProxy.rootClaim().raw(), ROOT_CLAIM.raw()); } + + /// @notice Tests that rootClaimByChainId returns the same value as rootClaim(). + function test_rootClaimByChainId_succeeds() public view { + assertEq(gameProxy.rootClaimByChainId(gameProxy.l2ChainId()).raw(), gameProxy.rootClaim().raw()); + } + + /// @notice Tests that rootClaimByChainId reverts with unknown chain ID. + function test_rootClaimByChainId_unknownChainId_reverts() public { + vm.expectRevert(UnknownChainId.selector); + gameProxy.rootClaimByChainId(0); + } } /// @title FaultDisputeGame_ExtraData_Test diff --git a/packages/contracts-bedrock/test/dispute/PermissionedDisputeGame.t.sol b/packages/contracts-bedrock/test/dispute/PermissionedDisputeGame.t.sol index e5f15c3424c74..4c344d6d1a96b 100644 --- a/packages/contracts-bedrock/test/dispute/PermissionedDisputeGame.t.sol +++ b/packages/contracts-bedrock/test/dispute/PermissionedDisputeGame.t.sol @@ -415,3 +415,19 @@ contract PermissionedDisputeGame_Uncategorized_Test is PermissionedDisputeGame_T vm.stopPrank(); } } + +/// @title PermissionedDisputeGame_RootClaimByChainId_Test +/// @notice Tests the `rootClaimByChainId` function. +contract PermissionedDisputeGame_RootClaimByChainId_Test is PermissionedDisputeGame_TestInit { + /// @notice Tests that rootClaimByChainId returns the same value as rootClaim(). + function test_rootClaimByChainId_succeeds() public view { + assertEq(gameProxy.rootClaimByChainId(gameProxy.l2ChainId()).raw(), gameProxy.rootClaim().raw()); + } + + /// @notice Tests that rootClaimByChainId reverts with unknown chain ID. + function test_rootClaimByChainId_unknownChainId_reverts(uint256 _chainId) public { + vm.assume(_chainId != gameProxy.l2ChainId()); + vm.expectRevert(UnknownChainId.selector); + gameProxy.rootClaimByChainId(_chainId); + } +} diff --git a/packages/contracts-bedrock/test/dispute/SuperPermissionedDisputeGame.t.sol b/packages/contracts-bedrock/test/dispute/SuperPermissionedDisputeGame.t.sol index c3d0dd5412bc2..f3b216e82458d 100644 --- a/packages/contracts-bedrock/test/dispute/SuperPermissionedDisputeGame.t.sol +++ b/packages/contracts-bedrock/test/dispute/SuperPermissionedDisputeGame.t.sol @@ -372,3 +372,22 @@ contract SuperPermissionedDisputeGame_Initialize_Test is SuperPermissionedDisput ); } } + +/// @title SuperPermissionedDisputeGame_RootClaimByChainId_Test +/// @notice Tests the `rootClaimByChainId` function. +contract SuperPermissionedDisputeGame_RootClaimByChainId_Test is SuperPermissionedDisputeGame_TestInit { + /// @notice Tests that the game's root claim for each output root is set correctly. + function test_rootClaimForOutputRoot_succeeds() public view { + for (uint256 i = 0; i < superRootProof.outputRoots.length; i++) { + uint256 chainId = superRootProof.outputRoots[i].chainId; + assertEq(gameProxy.rootClaimByChainId(chainId).raw(), superRootProof.outputRoots[i].root); + } + } + + /// @notice Tests that requesting the root claim for an unknown chain ID reverts. + function test_rootClaimForOutputRoot_unknownChainId_reverts() public { + uint256 invalidChainId = 9999; + vm.expectRevert(UnknownChainId.selector); + gameProxy.rootClaimByChainId(invalidChainId); + } +}