-
Notifications
You must be signed in to change notification settings - Fork 301
feat: Add Task Template for Switching Base to a Permissioned Game and Retiring Existing Dispute Games #434
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
a786588
f761424
28bf2bd
eda82fa
9fb2d57
6a57626
4013a7e
fc54b97
88d35c9
56dd64d
7384d6a
e483c92
c5308c9
f8f9c3f
95e5edb
f701ab8
2ae4922
504edab
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This root README should contain specific instructions in a sub-section below for this task, for example like here. Note that it can avoid any step about modifying the JSON validations file after its generated as long as the |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,20 @@ | ||||||||||||||||||||||||
| OP_COMMIT= | ||||||||||||||||||||||||
| BASE_CONTRACTS_COMMIT= | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| RECORD_STATE_DIFF=true | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| # Mainnet Config | ||||||||||||||||||||||||
| SYSTEM_CONFIG=0x73a79Fab69143498Ed3712e519A88a918e1f4072 | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| OWNER_SAFE=0x09f7150D8c019BeF34450d6920f6B3608ceFdAf2 # Optimism Guardian Multisig (controls Anchor State Registry) | ||||||||||||||||||||||||
| OP_SECURITY_COUNCIL_SAFE=0xc2819DC788505Aac350142A7A707BF9D03E3Bd03 # Owner of Optimism Guardian Multisig | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| SENDER=0x1822b35B09f5ce1C78ecbC06AC0A4e17885b925e # used to simulate | ||||||||||||||||||||||||
|
Comment on lines
+9
to
+12
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All of these comments must be on seperate lines, otherwise when
Suggested change
|
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| # Sepolia Config | ||||||||||||||||||||||||
| #SYSTEM_CONFIG=0xf272670eb55e895584501d564AfEB048bEd26194 | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| #OWNER_SAFE=0x7a50f00e8D05b95F98fE38d8BeE366a7324dCf7E # Optimism Guardian Multisig (controls Anchor State Registry) | ||||||||||||||||||||||||
| #OP_SECURITY_COUNCIL_SAFE=0xf64bc17485f0B4Ea5F06A96514182FC4cB561977 # Owner of Optimism Guardian Multisig | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| #SENDER=0x1084092Ac2f04c866806CF3d4a385Afa4F6A6C97 # used to simulate | ||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,32 @@ | ||||||||
| 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); \ | ||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There must be an empty
Suggested change
|
||||||||
| 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) | ||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we're using the Signer Tool, this README should follow the standard Signer Tool format, like here. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,168 @@ | ||
| # Switch to Permissioned Game and Retire Games | ||
|
|
||
| Status: PENDING | ||
|
|
||
| ## Description | ||
|
|
||
| This task contains a single script that will update the `respectedGameType` and `retirementTimestamp` in the AnchorStateRegistry. This can only be done by the | ||
| "Optimism Guardian Multisig" which is a single-nested multisig controlled by the OP Security Council. | ||
|
|
||
| ## Procedure | ||
|
|
||
| ### 1. Update repo: | ||
|
|
||
| ```bash | ||
| cd contract-deployments | ||
| git pull | ||
| cd <network>/<date>-switch-to-permissioned-game | ||
| make deps | ||
| ``` | ||
|
|
||
| ### 2. Setup Ledger | ||
|
|
||
| Your Ledger needs to be connected and unlocked. The Ethereum | ||
| application needs to be opened on Ledger with the message "Application | ||
| is ready". | ||
|
|
||
| ### 3. Run relevant script(s) | ||
|
|
||
| #### 3.1 Sign the transaction | ||
|
|
||
| **If on mainnet**: | ||
|
|
||
| Op signer: | ||
|
|
||
| ```bash | ||
| make sign-op | ||
| ``` | ||
|
|
||
| You will see a "Simulation link" from the output. | ||
|
|
||
| Paste this URL in your browser. A prompt may ask you to choose a | ||
| project, any project will do. You can create one if necessary. | ||
|
|
||
| Click "Simulate Transaction". | ||
|
|
||
| We will be performing 3 validations and extract the domain hash and message hash to approve on your Ledger: | ||
|
|
||
| 1. Validate integrity of the simulation. | ||
| 2. Validate correctness of the state diff. | ||
| 3. Validate and extract domain hash and message hash to approve. | ||
|
|
||
| ##### 3.2.1 Validate integrity of the simulation. | ||
|
|
||
| Make sure you are on the "Summary" tab of the tenderly simulation, to | ||
| validate integrity of the simulation, we need to check the following: | ||
|
|
||
| 1. "Network": Check the network is Sepolia or Mainnet. | ||
| 2. "Timestamp": Check the simulation is performed on a block with a | ||
| recent timestamp (i.e. close to when you run the script). | ||
| 3. "Sender": Check the address shown is your signer account. If not see the derivation path Note above. | ||
|
|
||
| ##### 3.2.2. Validate correctness of the state diff. | ||
|
|
||
| Now click on the "State" tab, and refer to the [State Validations](./VALIDATION.md) instructions for the transaction you are signing. | ||
| Once complete return to this document to complete the signing. | ||
|
|
||
| ##### 3.2.3. Extract the domain hash and the message hash to approve. | ||
|
|
||
| Now that we have verified the transaction performs the right | ||
| operation, we need to extract the domain hash and the message hash to | ||
| approve. | ||
|
|
||
| Go back to the "Summary" tab, and find the | ||
| `GnosisSafe.checkSignatures` (for OP signers) or `Safe.checkSignatures` (for Coinbase signers) call. | ||
| This call's `data` parameter contains both the domain hash and the | ||
| message hash that will show up in your Ledger. | ||
|
|
||
| It will be a concatenation of `0x1901`, the domain hash, and the | ||
| message hash: `0x1901[domain hash][message hash]`. | ||
|
|
||
| Note down this value. You will need to compare it with the ones | ||
| displayed on the Ledger screen at signing. | ||
|
|
||
| Once the validations are done, it's time to actually sign the | ||
| transaction. | ||
|
|
||
| > [!WARNING] | ||
| > This is the most security critical part of the playbook: make sure the | ||
| > domain hash and message hash in the following two places match: | ||
| > | ||
| > 1. On your Ledger screen. | ||
| > 2. In the Tenderly simulation. You should use the same Tenderly | ||
| > simulation as the one you used to verify the state diffs, instead | ||
| > of opening the new one printed in the console. | ||
| > | ||
| > There is no need to verify anything printed in the console. There is | ||
| > no need to open the new Tenderly simulation link either. | ||
|
|
||
| After verification, sign the transaction. You will see the `Data`, | ||
| `Signer` and `Signature` printed in the console. Format should be | ||
| something like this: | ||
|
|
||
| ```shell | ||
| Data: <DATA> | ||
| Signer: <ADDRESS> | ||
| Signature: <SIGNATURE> | ||
| ``` | ||
|
|
||
| Double check the signer address is the right one. | ||
|
|
||
| ##### 3.2.4 Send the output to Facilitator(s) | ||
|
|
||
| Nothing has occurred onchain - these are offchain signatures which | ||
| will be collected by Facilitators for execution. Execution can occur | ||
| by anyone once a threshold of signatures are collected, so a | ||
| Facilitator will do the final execution for convenience. | ||
|
|
||
| Share the `Data`, `Signer` and `Signature` with the Facilitator, and | ||
| congrats, you are done! | ||
|
|
||
| ### [For Facilitator ONLY] How to execute | ||
|
|
||
| #### Execute the transaction | ||
|
|
||
| 1. IMPORTANT: Ensure op-challenger has been updated before executing. | ||
| 1. Collect outputs from all participating signers. | ||
| 1. Concatenate all signatures and export it as the `SIGNATURES` | ||
| environment variable, i.e. `export | ||
| SIGNATURES="[SIGNATURE1][SIGNATURE2]..."`. | ||
| 1. Run the `make execute` or `make approve` command as described below to execute the transaction. | ||
|
|
||
| For example, if the quorum is 2 and you get the following outputs: | ||
|
|
||
| ```shell | ||
| Data: 0xDEADBEEF | ||
| Signer: 0xC0FFEE01 | ||
| Signature: AAAA | ||
| ``` | ||
|
|
||
| ```shell | ||
| Data: 0xDEADBEEF | ||
| Signer: 0xC0FFEE02 | ||
| Signature: BBBB | ||
| ``` | ||
|
|
||
| If on testnet, then you should run: | ||
|
|
||
| Coinbase facilitator: | ||
|
|
||
| ```bash | ||
| SIGNATURES=AAAABBBB make execute | ||
| ``` | ||
|
|
||
| If on mainnet, then you should run: | ||
|
|
||
| Optimism facilitator: | ||
|
|
||
| ```bash | ||
| SIGNATURES=AAAABBBB make approve-op | ||
| ``` | ||
|
|
||
| #### If on mainnet, execute the transaction | ||
|
|
||
| Once the signatures have been submitted approving the transaction for all nested Safes run: | ||
|
|
||
| ```bash | ||
| make execute | ||
| ``` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
jjtny1 marked this conversation as resolved.
Show resolved
Hide resolved
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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; | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Line 121 below should be switched to use the latest version of the Signer Tool:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(This is since the latest version of the Signer Tool removes the need for modifying the validations file after its generated.)