diff --git a/Makefile b/Makefile index a6e95e08..e4291c0c 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,7 @@ SAFE_MANAGEMENT_DIR = $(network)/$(shell date +'%Y-%m-%d')-safe-swap-owner FUNDING_DIR = $(network)/$(shell date +'%Y-%m-%d')-funding SET_BASE_BRIDGE_PARTNER_THRESHOLD_DIR = $(network)/$(shell date +'%Y-%m-%d')-pause-bridge-base PAUSE_BRIDGE_BASE_DIR = $(network)/$(shell date +'%Y-%m-%d')-pause-bridge-base +SWITCH_TO_PERMISSIONED_GAME_DIR=$(network)/$(shell date +'%Y-%m-%d')-switch-to-permissioned-game TEMPLATE_GENERIC = setup-templates/template-generic TEMPLATE_GAS_INCREASE = setup-templates/template-gas-increase @@ -15,6 +16,7 @@ TEMPLATE_SAFE_MANAGEMENT = setup-templates/template-safe-management TEMPLATE_FUNDING = setup-templates/template-funding TEMPLATE_SET_BASE_BRIDGE_PARTNER_THRESHOLD = setup-templates/template-set-bridge-partner-threshold TEMPLATE_PAUSE_BRIDGE_BASE = setup-templates/template-pause-bridge-base +TEMPLATE_SWITCH_TO_PERMISSIONED_GAME = setup-templates/template-switch-to-permissioned-game ifndef $(GOPATH) GOPATH=$(shell go env GOPATH) @@ -63,6 +65,10 @@ setup-bridge-pause: rm -rf $(TEMPLATE_PAUSE_BRIDGE_BASE)/cache $(TEMPLATE_PAUSE_BRIDGE_BASE)/lib $(TEMPLATE_PAUSE_BRIDGE_BASE)/out cp -r $(TEMPLATE_PAUSE_BRIDGE_BASE) $(PAUSE_BRIDGE_BASE_DIR) +setup-switch-to-permissioned-game: + rm -rf $(TEMPLATE_SWITCH_TO_PERMISSIONED_GAME)/cache $(TEMPLATE_SWITCH_TO_PERMISSIONED_GAME)/lib $(TEMPLATE_SWITCH_TO_PERMISSIONED_GAME)/out + cp -r $(TEMPLATE_SWITCH_TO_PERMISSIONED_GAME) $(SWITCH_TO_PERMISSIONED_GAME_DIR) + ## # Solidity Setup ## diff --git a/README.md b/README.md index 5b6a76f2..b88d556d 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ To execute a new task, run one of the following commands (depending on the type - For funding tasks: `make setup-funding network=` - For updating the partner threshold in Base Bridge: `make setup-bridge-partner-threshold network=` - For pausing / un-pausing Base Bridge: `make setup-bridge-pause network=` +- For switching to a permissioned game and retiring dispute games: `make setup-switch-to-permissioned-game network=` Next, `cd` into the directory that was created for you and follow the steps listed below for the relevant template. @@ -172,3 +173,17 @@ This template is used to pause or un-pause [Base Bridge](https://github.com/base 1. Generate the validation file for signers with `make gen-validation`. 1. Check in the task when it's ready to sign and request the facilitators to collect signatures from signers. 1. Once executed, check in the records files and mark the task `EXECUTED` in the README. + +## Using the Switch to Permissioned Game template + +This template is used to switch Base to a Permissioned Game. + +1. Ensure you have followed the instructions above in `setup`. +1. Run `mmake setup-switch-to-permissioned-game network=` and go to the folder that was created by this command. +1. Specify the commit of [Optimism code](https://github.com/ethereum-optimism/optimism) and [Base contracts code](https://github.com/base/contracts) you intend to use in the `.env` file. +1. Run `make deps`. +1. Ensure only the Sepolia or Mainnet variables are in the `.env` file depending on what network this task is for. +1. Build the contracts with `forge build`. +1. Generate the validation file for signers with `make gen-validation`. +1. Check in the task when it's ready to sign and request the facilitators to collect signatures from signers. +1. Once executed, check in the records files and mark the task `EXECUTED` in the README. diff --git a/setup-templates/template-switch-to-permissioned-game/.env b/setup-templates/template-switch-to-permissioned-game/.env new file mode 100644 index 00000000..2c7d9882 --- /dev/null +++ b/setup-templates/template-switch-to-permissioned-game/.env @@ -0,0 +1,25 @@ +OP_COMMIT= +BASE_CONTRACTS_COMMIT= + +RECORD_STATE_DIFF=true + +# Mainnet Config +SYSTEM_CONFIG=0x73a79Fab69143498Ed3712e519A88a918e1f4072 + +# Optimism Guardian Multisig (controls Anchor State Registry) +OWNER_SAFE=0x09f7150D8c019BeF34450d6920f6B3608ceFdAf2 +# Owner of Optimism Guardian Multisig +OP_SECURITY_COUNCIL_SAFE=0xc2819DC788505Aac350142A7A707BF9D03E3Bd03 + +SENDER=0x1822b35B09f5ce1C78ecbC06AC0A4e17885b925e # used to simulate + +# #Sepolia Config +#SYSTEM_CONFIG=0xf272670eb55e895584501d564AfEB048bEd26194 + +# #Optimism Guardian Multisig (controls Anchor State Registry) +#OWNER_SAFE=0x7a50f00e8D05b95F98fE38d8BeE366a7324dCf7E +# #Owner of Optimism Guardian Multisig +#OP_SECURITY_COUNCIL_SAFE=0xf64bc17485f0B4Ea5F06A96514182FC4cB561977 + +# # used to simulate +#SENDER=0x1084092Ac2f04c866806CF3d4a385Afa4F6A6C97 \ No newline at end of file diff --git a/setup-templates/template-switch-to-permissioned-game/Makefile b/setup-templates/template-switch-to-permissioned-game/Makefile new file mode 100644 index 00000000..1ed1a53f --- /dev/null +++ b/setup-templates/template-switch-to-permissioned-game/Makefile @@ -0,0 +1,33 @@ +include ../../Makefile +include ../../Multisig.mk + +include ../.env +include .env + +ifndef LEDGER_ACCOUNT +override LEDGER_ACCOUNT = 0 +endif + +RPC_URL = $(L1_RPC_URL) +SCRIPT_NAME = SwitchToPermissionedGame + +.PHONY: gen-validation +gen-validation: checkout-signer-tool run-script + +.PHONY: run-script +run-script: + cd $(SIGNER_TOOL_PATH); \ + mkdir validations; \ + npm ci; \ + bun run scripts/genValidationFile.ts --rpc-url $(L1_RPC_URL) \ + --workdir .. --forge-cmd 'forge script --rpc-url $(L1_RPC_URL) \ + $(SCRIPT_NAME) --sig "sign(address[])" ["$(OP_SECURITY_COUNCIL_SAFE)"] --sender $(SENDER)' --out ../validations/op-signer.json; + +.PHONY: approve-op +approve-op: + $(call MULTISIG_APPROVE,$(OP_SECURITY_COUNCIL_SAFE),$(SIGNATURES)) + +# Execute +.PHONY: execute +execute: + $(call MULTISIG_EXECUTE,0x) diff --git a/setup-templates/template-switch-to-permissioned-game/README.md b/setup-templates/template-switch-to-permissioned-game/README.md new file mode 100644 index 00000000..a64bb3d5 --- /dev/null +++ b/setup-templates/template-switch-to-permissioned-game/README.md @@ -0,0 +1,48 @@ +# Switch to Permissioned Games + +Status: READY TO SIGN + +## Description + +Switches Base to Permissioned Fault Dispute Games and retires existing games. + +## Install dependencies + +### 1. Update foundry + +```bash +foundryup +``` + +### 2. Install Node.js if needed + +First, check if you have node installed + +```bash +node --version +``` + +If you see a version output from the above command, you can move on. Otherwise, install node + +```bash +brew install node +``` + +## Sign Task + +### 1. Update repo: + +```bash +cd contract-deployments +git pull +``` + +### 2. Run the signing tool (NOTE: do not enter the task directory. Run this command from the project's root). + +```bash +make sign-task +``` + +### 3. Open the UI at [http://localhost:3000](http://localhost:3000) + +### 4. Send signature to facilitator diff --git a/setup-templates/template-switch-to-permissioned-game/foundry.toml b/setup-templates/template-switch-to-permissioned-game/foundry.toml new file mode 100644 index 00000000..7a443d45 --- /dev/null +++ b/setup-templates/template-switch-to-permissioned-game/foundry.toml @@ -0,0 +1,20 @@ +[profile.default] +src = 'src' +out = 'out' +libs = ['lib'] +broadcast = 'records' +fs_permissions = [{ access = "read-write", path = "./" }] +optimizer = true +optimizer_runs = 200 +via-ir = false +remappings = [ + '@eth-optimism-bedrock/=lib/optimism/packages/contracts-bedrock/', + '@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts', + '@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts', + '@rari-capital/solmate/=lib/solmate/', + '@base-contracts/=lib/base-contracts', + 'solady/=lib/solady/src/', + '@lib-keccak/=lib/lib-keccak/contracts/lib', +] + +# See more config options https://github.com/foundry-rs/foundry/tree/master/config diff --git a/setup-templates/template-switch-to-permissioned-game/script/SwitchToPermissionedGame.sol b/setup-templates/template-switch-to-permissioned-game/script/SwitchToPermissionedGame.sol new file mode 100644 index 00000000..8669ca14 --- /dev/null +++ b/setup-templates/template-switch-to-permissioned-game/script/SwitchToPermissionedGame.sol @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import {Vm} from "forge-std/Vm.sol"; +import {IMulticall3} from "forge-std/interfaces/IMulticall3.sol"; +import {IAnchorStateRegistry} from "@eth-optimism-bedrock/src/dispute/FaultDisputeGame.sol"; +import {SystemConfig} from "@eth-optimism-bedrock/src/L1/SystemConfig.sol"; +import {DisputeGameFactory} from "@eth-optimism-bedrock/src/dispute/DisputeGameFactory.sol"; +import {FaultDisputeGame} from "@eth-optimism-bedrock/src/dispute/PermissionedDisputeGame.sol"; +import {GameTypes, GameType} from "@eth-optimism-bedrock/src/dispute/lib/Types.sol"; +import {MultisigScript} from "@base-contracts/script/universal/MultisigScript.sol"; +import {Simulation} from "@base-contracts/script/universal/Simulation.sol"; + +/// @notice This script updates the respectedGameType and retires existing games in the AnchorStateRegistry. +contract SwitchToPermissionedGame is MultisigScript { + // TODO: Confirm expected version + string public constant EXPECTED_VERSION = "1.4.1"; + + address public immutable OWNER_SAFE; + + SystemConfig internal immutable _SYSTEM_CONFIG = SystemConfig(vm.envAddress("SYSTEM_CONFIG")); + + IAnchorStateRegistry anchorStateRegistry; + + constructor() { + OWNER_SAFE = vm.envAddress("OWNER_SAFE"); + } + + function setUp() public { + DisputeGameFactory dgfProxy = DisputeGameFactory(_SYSTEM_CONFIG.disputeGameFactory()); + FaultDisputeGame currentFdg = FaultDisputeGame(address(dgfProxy.gameImpls(GameTypes.CANNON))); + anchorStateRegistry = currentFdg.anchorStateRegistry(); + } + + // Confirm the retirementTimestamp is updated to the block time and the + // respectedGameType is updated to PERMISSIONED_CANNON. + function _postCheck(Vm.AccountAccess[] memory, Simulation.Payload memory) internal view override { + require(anchorStateRegistry.retirementTimestamp() == block.timestamp, "post-110"); + require( + GameType.unwrap(anchorStateRegistry.respectedGameType()) == GameType.unwrap(GameTypes.PERMISSIONED_CANNON), + "post-111" + ); + } + + function _buildCalls() internal view override returns (IMulticall3.Call3Value[] memory) { + IMulticall3.Call3Value[] memory calls = new IMulticall3.Call3Value[](2); + + calls[0] = IMulticall3.Call3Value({ + target: address(anchorStateRegistry), + allowFailure: false, + callData: abi.encodeCall(IAnchorStateRegistry.setRespectedGameType, (GameTypes.PERMISSIONED_CANNON)), + value: 0 + }); + + calls[1] = IMulticall3.Call3Value({ + target: address(anchorStateRegistry), + allowFailure: false, + callData: abi.encodeCall(IAnchorStateRegistry.updateRetirementTimestamp, ()), + value: 0 + }); + + return calls; + } + + function _ownerSafe() internal view override returns (address) { + return OWNER_SAFE; + } +}