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 }