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 }