github.com/ethereum-optimism/optimism@v1.7.2/packages/contracts-bedrock/scripts/fpac/FPACOPS.s.sol (about)

     1  // SPDX-License-Identifier: MIT
     2  pragma solidity 0.8.15;
     3  
     4  import { Proxy } from "src/universal/Proxy.sol";
     5  import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol";
     6  import { AnchorStateRegistry, IAnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol";
     7  import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol";
     8  import { StdAssertions } from "forge-std/StdAssertions.sol";
     9  import "src/libraries/DisputeTypes.sol";
    10  import "scripts/Deploy.s.sol";
    11  
    12  /// @notice Deploys the Fault Proof Alpha Chad contracts.
    13  contract FPACOPS is Deploy, StdAssertions {
    14      ////////////////////////////////////////////////////////////////
    15      //                        ENTRYPOINTS                         //
    16      ////////////////////////////////////////////////////////////////
    17  
    18      function deployFPAC(address _proxyAdmin, address _systemOwnerSafe, address _superchainConfigProxy) public {
    19          console.log("Deploying a fresh FPAC system and OptimismPortal2 implementation.");
    20  
    21          prankDeployment("ProxyAdmin", msg.sender);
    22          prankDeployment("SystemOwnerSafe", msg.sender);
    23          prankDeployment("SuperchainConfigProxy", _superchainConfigProxy);
    24  
    25          // Deploy the proxies.
    26          deployERC1967Proxy("DisputeGameFactoryProxy");
    27          deployERC1967Proxy("DelayedWETHProxy");
    28          deployERC1967Proxy("AnchorStateRegistryProxy");
    29  
    30          // Deploy implementations.
    31          deployDisputeGameFactory();
    32          deployDelayedWETH();
    33          deployAnchorStateRegistry();
    34          deployPreimageOracle();
    35          deployMips();
    36  
    37          // Deploy the new `OptimismPortal` implementation.
    38          deployOptimismPortal2();
    39  
    40          // Initialize the proxies.
    41          initializeDisputeGameFactoryProxy();
    42          initializeDelayedWETHProxy();
    43          initializeAnchorStateRegistryProxy();
    44  
    45          // Deploy the Cannon Fault game implementation and set it as game ID = 0.
    46          setCannonFaultGameImplementation({ _allowUpgrade: false });
    47          // Deploy the Permissioned Cannon Fault game implementation and set it as game ID = 1.
    48          setPermissionedCannonFaultGameImplementation({ _allowUpgrade: false });
    49  
    50          // Transfer ownership of the DisputeGameFactory to the SystemOwnerSafe, and transfer the administrative rights
    51          // of the DisputeGameFactoryProxy to the ProxyAdmin.
    52          transferDGFOwnershipFinal({ _proxyAdmin: _proxyAdmin, _systemOwnerSafe: _systemOwnerSafe });
    53          transferWethOwnershipFinal({ _proxyAdmin: _proxyAdmin, _systemOwnerSafe: _systemOwnerSafe });
    54          transferAnchorStateOwnershipFinal({ _proxyAdmin: _proxyAdmin });
    55  
    56          // Run post-deployment assertions.
    57          postDeployAssertions({ _proxyAdmin: _proxyAdmin, _systemOwnerSafe: _systemOwnerSafe });
    58  
    59          // Print overview
    60          printConfigReview();
    61      }
    62  
    63      ////////////////////////////////////////////////////////////////
    64      //                          HELPERS                           //
    65      ////////////////////////////////////////////////////////////////
    66  
    67      /// @notice Initializes the DisputeGameFactoryProxy with the DisputeGameFactory.
    68      function initializeDisputeGameFactoryProxy() internal broadcast {
    69          console.log("Initializing DisputeGameFactoryProxy with DisputeGameFactory.");
    70  
    71          address dgfProxy = mustGetAddress("DisputeGameFactoryProxy");
    72          Proxy(payable(dgfProxy)).upgradeToAndCall(
    73              mustGetAddress("DisputeGameFactory"), abi.encodeCall(DisputeGameFactory.initialize, msg.sender)
    74          );
    75  
    76          // Set the initialization bonds for the FaultDisputeGame and PermissionedDisputeGame.
    77          DisputeGameFactory dgf = DisputeGameFactory(dgfProxy);
    78          dgf.setInitBond(GameTypes.CANNON, 0.08 ether);
    79          dgf.setInitBond(GameTypes.PERMISSIONED_CANNON, 0.08 ether);
    80      }
    81  
    82      function initializeDelayedWETHProxy() internal broadcast {
    83          console.log("Initializing DelayedWETHProxy with DelayedWETH.");
    84  
    85          address wethProxy = mustGetAddress("DelayedWETHProxy");
    86          address superchainConfigProxy = mustGetAddress("SuperchainConfigProxy");
    87          Proxy(payable(wethProxy)).upgradeToAndCall(
    88              mustGetAddress("DelayedWETH"),
    89              abi.encodeCall(DelayedWETH.initialize, (msg.sender, SuperchainConfig(superchainConfigProxy)))
    90          );
    91      }
    92  
    93      function initializeAnchorStateRegistryProxy() internal broadcast {
    94          console.log("Initializing AnchorStateRegistryProxy with AnchorStateRegistry.");
    95  
    96          AnchorStateRegistry.StartingAnchorRoot[] memory roots = new AnchorStateRegistry.StartingAnchorRoot[](2);
    97          roots[0] = AnchorStateRegistry.StartingAnchorRoot({
    98              gameType: GameTypes.CANNON,
    99              outputRoot: OutputRoot({
   100                  root: Hash.wrap(cfg.faultGameGenesisOutputRoot()),
   101                  l2BlockNumber: cfg.faultGameGenesisBlock()
   102              })
   103          });
   104          roots[1] = AnchorStateRegistry.StartingAnchorRoot({
   105              gameType: GameTypes.PERMISSIONED_CANNON,
   106              outputRoot: OutputRoot({
   107                  root: Hash.wrap(cfg.faultGameGenesisOutputRoot()),
   108                  l2BlockNumber: cfg.faultGameGenesisBlock()
   109              })
   110          });
   111  
   112          address asrProxy = mustGetAddress("AnchorStateRegistryProxy");
   113          Proxy(payable(asrProxy)).upgradeToAndCall(
   114              mustGetAddress("AnchorStateRegistry"), abi.encodeCall(AnchorStateRegistry.initialize, (roots))
   115          );
   116      }
   117  
   118      /// @notice Transfers admin rights of the `DisputeGameFactoryProxy` to the `ProxyAdmin` and sets the
   119      ///         `DisputeGameFactory` owner to the `SystemOwnerSafe`.
   120      function transferDGFOwnershipFinal(address _proxyAdmin, address _systemOwnerSafe) internal broadcast {
   121          DisputeGameFactory dgf = DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy"));
   122  
   123          // Transfer the ownership of the DisputeGameFactory to the SystemOwnerSafe.
   124          dgf.transferOwnership(_systemOwnerSafe);
   125  
   126          // Transfer the admin rights of the DisputeGameFactoryProxy to the ProxyAdmin.
   127          Proxy prox = Proxy(payable(address(dgf)));
   128          prox.changeAdmin(_proxyAdmin);
   129      }
   130  
   131      /// @notice Transfers admin rights of the `DelayedWETHProxy` to the `ProxyAdmin` and sets the
   132      ///         `DelayedWETH` owner to the `SystemOwnerSafe`.
   133      function transferWethOwnershipFinal(address _proxyAdmin, address _systemOwnerSafe) internal broadcast {
   134          DelayedWETH weth = DelayedWETH(mustGetAddress("DelayedWETHProxy"));
   135  
   136          // Transfer the ownership of the DelayedWETH to the SystemOwnerSafe.
   137          weth.transferOwnership(_systemOwnerSafe);
   138  
   139          // Transfer the admin rights of the DelayedWETHProxy to the ProxyAdmin.
   140          Proxy prox = Proxy(payable(address(weth)));
   141          prox.changeAdmin(_proxyAdmin);
   142      }
   143  
   144      /// @notice Transfers admin rights of the `AnchorStateRegistryProxy` to the `ProxyAdmin`.
   145      function transferAnchorStateOwnershipFinal(address _proxyAdmin) internal broadcast {
   146          AnchorStateRegistry asr = AnchorStateRegistry(mustGetAddress("AnchorStateRegistryProxy"));
   147  
   148          // Transfer the admin rights of the AnchorStateRegistryProxy to the ProxyAdmin.
   149          Proxy prox = Proxy(payable(address(asr)));
   150          prox.changeAdmin(_proxyAdmin);
   151      }
   152  
   153      /// @notice Checks that the deployed system is configured correctly.
   154      function postDeployAssertions(address _proxyAdmin, address _systemOwnerSafe) internal {
   155          Types.ContractSet memory contracts = _proxiesUnstrict();
   156          contracts.OptimismPortal2 = mustGetAddress("OptimismPortal2");
   157  
   158          // Ensure that `useFaultProofs` is set to `true`.
   159          assertTrue(cfg.useFaultProofs());
   160  
   161          // Ensure the contracts are owned by the correct entities.
   162          address dgfProxyAddr = mustGetAddress("DisputeGameFactoryProxy");
   163          DisputeGameFactory dgfProxy = DisputeGameFactory(dgfProxyAddr);
   164          assertEq(address(uint160(uint256(vm.load(dgfProxyAddr, Constants.PROXY_OWNER_ADDRESS)))), _proxyAdmin);
   165          ChainAssertions.checkDisputeGameFactory(contracts, _systemOwnerSafe);
   166          address wethProxyAddr = mustGetAddress("DelayedWETHProxy");
   167          assertEq(address(uint160(uint256(vm.load(wethProxyAddr, Constants.PROXY_OWNER_ADDRESS)))), _proxyAdmin);
   168          ChainAssertions.checkDelayedWETH(contracts, cfg, true, _systemOwnerSafe);
   169  
   170          // Check the config elements in the deployed contracts.
   171          ChainAssertions.checkOptimismPortal2(contracts, cfg, false);
   172  
   173          PreimageOracle oracle = PreimageOracle(mustGetAddress("PreimageOracle"));
   174          assertEq(oracle.minProposalSize(), cfg.preimageOracleMinProposalSize());
   175          assertEq(oracle.challengePeriod(), cfg.preimageOracleChallengePeriod());
   176  
   177          MIPS mips = MIPS(mustGetAddress("Mips"));
   178          assertEq(address(mips.oracle()), address(oracle));
   179  
   180          // Check the FaultDisputeGame configuration.
   181          FaultDisputeGame gameImpl = FaultDisputeGame(payable(address(dgfProxy.gameImpls(GameTypes.CANNON))));
   182          assertEq(gameImpl.maxGameDepth(), cfg.faultGameMaxDepth());
   183          assertEq(gameImpl.splitDepth(), cfg.faultGameSplitDepth());
   184          assertEq(gameImpl.gameDuration().raw(), cfg.faultGameMaxDuration());
   185          assertEq(gameImpl.absolutePrestate().raw(), bytes32(cfg.faultGameAbsolutePrestate()));
   186  
   187          // Check the security override yoke configuration.
   188          PermissionedDisputeGame soyGameImpl =
   189              PermissionedDisputeGame(payable(address(dgfProxy.gameImpls(GameTypes.PERMISSIONED_CANNON))));
   190          assertEq(soyGameImpl.maxGameDepth(), cfg.faultGameMaxDepth());
   191          assertEq(soyGameImpl.splitDepth(), cfg.faultGameSplitDepth());
   192          assertEq(soyGameImpl.gameDuration().raw(), cfg.faultGameMaxDuration());
   193          assertEq(soyGameImpl.absolutePrestate().raw(), bytes32(cfg.faultGameAbsolutePrestate()));
   194  
   195          // Check the AnchorStateRegistry configuration.
   196          AnchorStateRegistry asr = AnchorStateRegistry(mustGetAddress("AnchorStateRegistryProxy"));
   197          (Hash root1, uint256 l2BlockNumber1) = asr.anchors(GameTypes.CANNON);
   198          (Hash root2, uint256 l2BlockNumber2) = asr.anchors(GameTypes.PERMISSIONED_CANNON);
   199          assertEq(root1.raw(), cfg.faultGameGenesisOutputRoot());
   200          assertEq(root2.raw(), cfg.faultGameGenesisOutputRoot());
   201          assertEq(l2BlockNumber1, cfg.faultGameGenesisBlock());
   202          assertEq(l2BlockNumber2, cfg.faultGameGenesisBlock());
   203      }
   204  
   205      /// @notice Prints a review of the fault proof configuration section of the deploy config.
   206      function printConfigReview() internal view {
   207          console.log(unicode"📖 FaultDisputeGame Config Overview (chainid: %d)", block.chainid);
   208          console.log("    0. Use Fault Proofs: %s", cfg.useFaultProofs() ? "true" : "false");
   209          console.log("    1. Absolute Prestate: %x", cfg.faultGameAbsolutePrestate());
   210          console.log("    2. Max Depth: %d", cfg.faultGameMaxDepth());
   211          console.log("    3. Output / Execution split Depth: %d", cfg.faultGameSplitDepth());
   212          console.log("    4. Game Duration (seconds): %d", cfg.faultGameMaxDuration());
   213          console.log("    5. L2 Genesis block number: %d", cfg.faultGameGenesisBlock());
   214          console.log("    6. L2 Genesis output root: %x", uint256(cfg.faultGameGenesisOutputRoot()));
   215          console.log("    7. Proof Maturity Delay (seconds): ", cfg.proofMaturityDelaySeconds());
   216          console.log("    8. Dispute Game Finality Delay (seconds): ", cfg.disputeGameFinalityDelaySeconds());
   217          console.log("    9. Respected Game Type: ", cfg.respectedGameType());
   218          console.log("   10. Preimage Oracle Min Proposal Size (bytes): ", cfg.preimageOracleMinProposalSize());
   219          console.log("   11. Preimage Oracle Challenge Period (seconds): ", cfg.preimageOracleChallengePeriod());
   220      }
   221  }