github.com/ethereum-optimism/optimism@v1.7.2/packages/contracts-bedrock/test/dispute/AnchorStateRegistry.t.sol (about)

     1  // SPDX-License-Identifier: MIT
     2  pragma solidity ^0.8.15;
     3  
     4  import "src/libraries/DisputeTypes.sol";
     5  import "src/libraries/DisputeErrors.sol";
     6  
     7  import { Test } from "forge-std/Test.sol";
     8  import { FaultDisputeGame_Init, _changeClaimStatus } from "test/dispute/FaultDisputeGame.t.sol";
     9  
    10  contract AnchorStateRegistry_Init is FaultDisputeGame_Init {
    11      function setUp() public virtual override {
    12          // Duplicating the initialization/setup logic of FaultDisputeGame_Test.
    13          // See that test for more information, actual values here not really important.
    14          Claim rootClaim = Claim.wrap(bytes32((uint256(1) << 248) | uint256(10)));
    15          bytes memory absolutePrestateData = abi.encode(0);
    16          Claim absolutePrestate = _changeClaimStatus(Claim.wrap(keccak256(absolutePrestateData)), VMStatuses.UNFINISHED);
    17  
    18          super.setUp();
    19          super.init({ rootClaim: rootClaim, absolutePrestate: absolutePrestate, l2BlockNumber: 0x10 });
    20      }
    21  }
    22  
    23  contract AnchorStateRegistry_Initialize_Test is AnchorStateRegistry_Init {
    24      /// @dev Tests that initialization is successful.
    25      function test_initialize_succeeds() public {
    26          (Hash cannonRoot, uint256 cannonL2BlockNumber) = anchorStateRegistry.anchors(GameTypes.CANNON);
    27          (Hash permissionedCannonRoot, uint256 permissionedCannonL2BlockNumber) =
    28              anchorStateRegistry.anchors(GameTypes.PERMISSIONED_CANNON);
    29          (Hash alphabetRoot, uint256 alphabetL2BlockNumber) = anchorStateRegistry.anchors(GameTypes.ALPHABET);
    30          assertEq(cannonRoot.raw(), 0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF);
    31          assertEq(cannonL2BlockNumber, 0);
    32          assertEq(permissionedCannonRoot.raw(), 0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF);
    33          assertEq(permissionedCannonL2BlockNumber, 0);
    34          assertEq(alphabetRoot.raw(), 0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF);
    35          assertEq(alphabetL2BlockNumber, 0);
    36      }
    37  }
    38  
    39  contract AnchorStateRegistry_TryUpdateAnchorState_Test is AnchorStateRegistry_Init {
    40      /// @dev Tests that updating the anchor state succeeds when the game state is valid and newer.
    41      function test_tryUpdateAnchorState_validNewerState_succeeds() public {
    42          // Confirm that the anchor state is older than the game state.
    43          (Hash root, uint256 l2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType());
    44          assert(l2BlockNumber < gameProxy.l2BlockNumber());
    45  
    46          // Mock the state that we want.
    47          vm.mockCall(
    48              address(gameProxy), abi.encodeWithSelector(gameProxy.status.selector), abi.encode(GameStatus.DEFENDER_WINS)
    49          );
    50  
    51          // Try to update the anchor state.
    52          vm.prank(address(gameProxy));
    53          anchorStateRegistry.tryUpdateAnchorState();
    54  
    55          // Confirm that the anchor state is now the same as the game state.
    56          (root, l2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType());
    57          assertEq(l2BlockNumber, gameProxy.l2BlockNumber());
    58          assertEq(root.raw(), gameProxy.rootClaim().raw());
    59      }
    60  
    61      /// @dev Tests that updating the anchor state fails when the game state is valid but older.
    62      function test_tryUpdateAnchorState_validOlderState_fails() public {
    63          // Confirm that the anchor state is newer than the game state.
    64          vm.mockCall(address(gameProxy), abi.encodeWithSelector(gameProxy.l2BlockNumber.selector), abi.encode(0));
    65          (Hash root, uint256 l2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType());
    66          assert(l2BlockNumber >= gameProxy.l2BlockNumber());
    67  
    68          // Mock the state that we want.
    69          vm.mockCall(address(gameProxy), abi.encodeWithSelector(gameProxy.l2BlockNumber.selector), abi.encode(0));
    70          vm.mockCall(
    71              address(gameProxy), abi.encodeWithSelector(gameProxy.status.selector), abi.encode(GameStatus.DEFENDER_WINS)
    72          );
    73  
    74          // Try to update the anchor state.
    75          vm.prank(address(gameProxy));
    76          anchorStateRegistry.tryUpdateAnchorState();
    77  
    78          // Confirm that the anchor state has not updated.
    79          (Hash updatedRoot, uint256 updatedL2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType());
    80          assertEq(updatedL2BlockNumber, l2BlockNumber);
    81          assertEq(updatedRoot.raw(), root.raw());
    82      }
    83  
    84      /// @dev Tests that updating the anchor state fails when the game state is invalid.
    85      function test_tryUpdateAnchorState_invalidNewerState_fails() public {
    86          // Confirm that the anchor state is older than the game state.
    87          (Hash root, uint256 l2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType());
    88          assert(l2BlockNumber < gameProxy.l2BlockNumber());
    89  
    90          // Mock the state that we want.
    91          vm.mockCall(
    92              address(gameProxy),
    93              abi.encodeWithSelector(gameProxy.status.selector),
    94              abi.encode(GameStatus.CHALLENGER_WINS)
    95          );
    96  
    97          // Try to update the anchor state.
    98          vm.prank(address(gameProxy));
    99          anchorStateRegistry.tryUpdateAnchorState();
   100  
   101          // Confirm that the anchor state has not updated.
   102          (Hash updatedRoot, uint256 updatedL2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType());
   103          assertEq(updatedL2BlockNumber, l2BlockNumber);
   104          assertEq(updatedRoot.raw(), root.raw());
   105      }
   106  
   107      /// @dev Tests that updating the anchor state fails when the game is not registered with the factory.
   108      function test_tryUpdateAnchorState_invalidGame_fails() public {
   109          // Confirm that the anchor state is older than the game state.
   110          (Hash root, uint256 l2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType());
   111          assert(l2BlockNumber < gameProxy.l2BlockNumber());
   112  
   113          // Mock the state that we want.
   114          vm.mockCall(
   115              address(disputeGameFactory),
   116              abi.encodeWithSelector(
   117                  disputeGameFactory.games.selector, gameProxy.gameType(), gameProxy.rootClaim(), gameProxy.extraData()
   118              ),
   119              abi.encode(address(0), 0)
   120          );
   121  
   122          // Try to update the anchor state.
   123          vm.prank(address(gameProxy));
   124          vm.expectRevert("AnchorStateRegistry: fault dispute game not registered with factory");
   125          anchorStateRegistry.tryUpdateAnchorState();
   126  
   127          // Confirm that the anchor state has not updated.
   128          (Hash updatedRoot, uint256 updatedL2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType());
   129          assertEq(updatedL2BlockNumber, l2BlockNumber);
   130          assertEq(updatedRoot.raw(), root.raw());
   131      }
   132  }