diff --git a/packages/contracts-bedrock/interfaces/dispute/IAnchorStateRegistry.sol b/packages/contracts-bedrock/interfaces/dispute/IAnchorStateRegistry.sol index 19435b2794666..5b7f6f7e42fe0 100644 --- a/packages/contracts-bedrock/interfaces/dispute/IAnchorStateRegistry.sol +++ b/packages/contracts-bedrock/interfaces/dispute/IAnchorStateRegistry.sol @@ -2,7 +2,6 @@ pragma solidity ^0.8.0; import { IDisputeGame } from "interfaces/dispute/IDisputeGame.sol"; -import { IFaultDisputeGame } from "interfaces/dispute/IFaultDisputeGame.sol"; import { IDisputeGameFactory } from "interfaces/dispute/IDisputeGameFactory.sol"; import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; import { GameType, Hash, Proposal } from "src/dispute/lib/Types.sol"; @@ -14,14 +13,14 @@ interface IAnchorStateRegistry is IProxyAdminOwnedBase { error AnchorStateRegistry_Unauthorized(); error ReinitializableBase_ZeroInitVersion(); - event AnchorUpdated(IFaultDisputeGame indexed game); + event AnchorUpdated(IDisputeGame indexed game); event DisputeGameBlacklisted(IDisputeGame indexed disputeGame); event Initialized(uint8 version); event RespectedGameTypeSet(GameType gameType); event RetirementTimestampSet(uint256 timestamp); function initVersion() external view returns (uint8); - function anchorGame() external view returns (IFaultDisputeGame); + function anchorGame() external view returns (IDisputeGame); function anchors(GameType) external view returns (Hash, uint256); function blacklistDisputeGame(IDisputeGame _disputeGame) external; function disputeGameBlacklist(IDisputeGame) external view returns (bool); diff --git a/packages/contracts-bedrock/snapshots/abi/AnchorStateRegistry.json b/packages/contracts-bedrock/snapshots/abi/AnchorStateRegistry.json index f6171f09bd2a3..8957b66aff6f4 100644 --- a/packages/contracts-bedrock/snapshots/abi/AnchorStateRegistry.json +++ b/packages/contracts-bedrock/snapshots/abi/AnchorStateRegistry.json @@ -15,7 +15,7 @@ "name": "anchorGame", "outputs": [ { - "internalType": "contract IFaultDisputeGame", + "internalType": "contract IDisputeGame", "name": "", "type": "address" } @@ -495,7 +495,7 @@ "inputs": [ { "indexed": true, - "internalType": "contract IFaultDisputeGame", + "internalType": "contract IDisputeGame", "name": "game", "type": "address" } diff --git a/packages/contracts-bedrock/snapshots/semver-lock.json b/packages/contracts-bedrock/snapshots/semver-lock.json index b787c12f110a9..ed344968c438c 100644 --- a/packages/contracts-bedrock/snapshots/semver-lock.json +++ b/packages/contracts-bedrock/snapshots/semver-lock.json @@ -184,8 +184,8 @@ "sourceCodeHash": "0x03c160168986ffc8d26a90c37366e7ad6da03f49d83449e1f8b3de0f4b590f6f" }, "src/dispute/AnchorStateRegistry.sol:AnchorStateRegistry": { - "initCodeHash": "0xc00fdb1a4ae0ec8d7a96ebaad38ffaee9d96b942ab2a56e0ce2f76639f79ae7c", - "sourceCodeHash": "0xd2837ddf6992926ced31ef1916f95ebb8cc2006e94b82c2287997e5397edfeaf" + "initCodeHash": "0x7d85ca3f30f6526a62214a6ef876299dcf15e536afe4f5dd7b232a92120e170f", + "sourceCodeHash": "0x896011529b7fdb6623a0b3f72b099f38229168f54514e674c6b3aa7afc35e4fc" }, "src/dispute/DelayedWETH.sol:DelayedWETH": { "initCodeHash": "0xa8f60e142108b33675a8f6b6979c73b96eea247884842d796f9f878904c0a906", diff --git a/packages/contracts-bedrock/snapshots/storageLayout/AnchorStateRegistry.json b/packages/contracts-bedrock/snapshots/storageLayout/AnchorStateRegistry.json index 7b404d1f8c65c..2d538dd3ef9be 100644 --- a/packages/contracts-bedrock/snapshots/storageLayout/AnchorStateRegistry.json +++ b/packages/contracts-bedrock/snapshots/storageLayout/AnchorStateRegistry.json @@ -32,7 +32,7 @@ "label": "anchorGame", "offset": 0, "slot": "2", - "type": "contract IFaultDisputeGame" + "type": "contract IDisputeGame" }, { "bytes": "64", diff --git a/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol b/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol index cc44cac8ff259..d9a21c6ace89a 100644 --- a/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol +++ b/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol @@ -11,7 +11,6 @@ import { GameType, Proposal, Claim, GameStatus, Hash } from "src/dispute/lib/Typ // Interfaces import { ISemver } from "interfaces/universal/ISemver.sol"; -import { IFaultDisputeGame } from "interfaces/dispute/IFaultDisputeGame.sol"; import { IDisputeGame } from "interfaces/dispute/IDisputeGame.sol"; import { IDisputeGameFactory } from "interfaces/dispute/IDisputeGameFactory.sol"; import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; @@ -25,8 +24,8 @@ import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; /// be initialized with a more recent starting state which reduces the amount of required offchain computation. contract AnchorStateRegistry is ProxyAdminOwnedBase, Initializable, ReinitializableBase, ISemver { /// @notice Semantic version. - /// @custom:semver 3.7.0 - string public constant version = "3.7.0"; + /// @custom:semver 3.8.0 + string public constant version = "3.8.0"; /// @notice The dispute game finality delay in seconds. uint256 internal immutable DISPUTE_GAME_FINALITY_DELAY_SECONDS; @@ -38,7 +37,7 @@ contract AnchorStateRegistry is ProxyAdminOwnedBase, Initializable, Reinitializa IDisputeGameFactory public disputeGameFactory; /// @notice The game whose claim is currently being used as the anchor state. - IFaultDisputeGame public anchorGame; + IDisputeGame public anchorGame; /// @notice The starting anchor root. Proposal internal startingAnchorRoot; @@ -56,7 +55,7 @@ contract AnchorStateRegistry is ProxyAdminOwnedBase, Initializable, Reinitializa /// @notice Emitted when an anchor state is updated. /// @param game Game that was used as the new anchor game. - event AnchorUpdated(IFaultDisputeGame indexed game); + event AnchorUpdated(IDisputeGame indexed game); /// @notice Emitted when the respected game type is set. /// @param gameType The new respected game type. @@ -190,7 +189,7 @@ contract AnchorStateRegistry is ProxyAdminOwnedBase, Initializable, Reinitializa } /// @notice Determines whether a game is registered by checking that it was created by the - /// DisputeGameFactory and that it uses this AnchorStateRegistry. + /// DisputeGameFactory. /// @param _game The game to check. /// @return Whether the game is registered. function isGameRegistered(IDisputeGame _game) public view returns (bool) { @@ -201,16 +200,8 @@ contract AnchorStateRegistry is ProxyAdminOwnedBase, Initializable, Reinitializa (IDisputeGame factoryRegisteredGame,) = disputeGameFactory.games({ _gameType: gameType, _rootClaim: rootClaim, _extraData: extraData }); - // Grab the AnchorStateRegistry from the game. Awkward type conversion here but - // IDisputeGame probably needs to have this function eventually anyway. - address asr = address(IFaultDisputeGame(address(_game)).anchorStateRegistry()); - - // Return whether the game is factory registered and uses this AnchorStateRegistry. We - // check for both of these conditions because the game could be using a different - // AnchorStateRegistry if the registry was updated at some point. We mitigate the risks of - // an outdated AnchorStateRegistry by invalidating all previous games in the initializer of - // this contract, but an explicit check avoids potential footguns in the future. - return address(factoryRegisteredGame) == address(_game) && asr == address(this); + // Return whether the game is factory registered. + return address(factoryRegisteredGame) == address(_game); } /// @notice Determines whether a game is of a respected game type. @@ -332,27 +323,20 @@ contract AnchorStateRegistry is ProxyAdminOwnedBase, Initializable, Reinitializa /// @notice Updates the anchor game. /// @param _game New candidate anchor game. function setAnchorState(IDisputeGame _game) public { - // Convert game to FaultDisputeGame. - // We can't use FaultDisputeGame in the interface because this function is called from the - // FaultDisputeGame contract which can't import IFaultDisputeGame by convention. We should - // likely introduce a new interface (e.g., StateDisputeGame) that can act as a more useful - // version of IDisputeGame in the future. - IFaultDisputeGame game = IFaultDisputeGame(address(_game)); - // Check if the candidate game claim is valid. - if (!isGameClaimValid(game)) { + if (!isGameClaimValid(_game)) { revert AnchorStateRegistry_InvalidAnchorGame(); } // Must be newer than the current anchor game. (, uint256 anchorL2BlockNumber) = getAnchorRoot(); - if (game.l2SequenceNumber() <= anchorL2BlockNumber) { + if (_game.l2SequenceNumber() <= anchorL2BlockNumber) { revert AnchorStateRegistry_InvalidAnchorGame(); } // Update the anchor game. - anchorGame = game; - emit AnchorUpdated(game); + anchorGame = _game; + emit AnchorUpdated(_game); } /// @notice Asserts that the caller is the Guardian. diff --git a/packages/contracts-bedrock/test/dispute/AnchorStateRegistry.t.sol b/packages/contracts-bedrock/test/dispute/AnchorStateRegistry.t.sol index 2af2302d2b54e..8c39da243c939 100644 --- a/packages/contracts-bedrock/test/dispute/AnchorStateRegistry.t.sol +++ b/packages/contracts-bedrock/test/dispute/AnchorStateRegistry.t.sol @@ -516,22 +516,6 @@ contract AnchorStateRegistry_IsGameRegistered_Test is AnchorStateRegistry_TestIn // Game should not be registered. assertFalse(anchorStateRegistry.isGameRegistered(gameProxy)); } - - /// @notice Tests that isGameRegistered will return false if the game is not using the same - /// AnchorStateRegistry as the one checking the registration. - /// @param _anchorStateRegistry The AnchorStateRegistry to use for the test. - function test_isGameRegistered_isNotSameAnchorStateRegistry_succeeds(address _anchorStateRegistry) public { - // Make sure the AnchorStateRegistry is different. - vm.assume(_anchorStateRegistry != address(anchorStateRegistry)); - - // Mock the gameProxy's AnchorStateRegistry to be a different address. - vm.mockCall( - address(gameProxy), abi.encodeCall(gameProxy.anchorStateRegistry, ()), abi.encode(_anchorStateRegistry) - ); - - // Game should not be registered. - assertFalse(anchorStateRegistry.isGameRegistered(gameProxy)); - } } /// @title AnchorStateRegistry_IsGameRespected_Test @@ -970,7 +954,7 @@ contract AnchorStateRegistry_SetAnchorState_Test is AnchorStateRegistry_TestInit assertEq(root.raw(), gameProxy.rootClaim().raw()); // Confirm that the anchor game is now set. - IFaultDisputeGame anchorGame = anchorStateRegistry.anchorGame(); + IDisputeGame anchorGame = anchorStateRegistry.anchorGame(); assertEq(address(anchorGame), address(gameProxy)); }