From db4601e3d04136ff40370ceed8bc3ebf9ffe3425 Mon Sep 17 00:00:00 2001 From: Cody Wang Date: Tue, 27 Aug 2024 16:50:48 -0400 Subject: [PATCH] only updating batcher --- sepolia/2024-08-26-update-batcher-hash/.env | 18 ++ .../2024-08-26-update-batcher-hash/Makefile | 30 ++ .../2024-08-26-update-batcher-hash/README.md | 289 ++++++++++++++++++ .../foundry.toml | 20 ++ .../script/RollbackBatcherHash.s.sol | 56 ++++ .../script/UpdateBatcherHash.s.sol | 56 ++++ 6 files changed, 469 insertions(+) create mode 100644 sepolia/2024-08-26-update-batcher-hash/.env create mode 100644 sepolia/2024-08-26-update-batcher-hash/Makefile create mode 100644 sepolia/2024-08-26-update-batcher-hash/README.md create mode 100644 sepolia/2024-08-26-update-batcher-hash/foundry.toml create mode 100644 sepolia/2024-08-26-update-batcher-hash/script/RollbackBatcherHash.s.sol create mode 100644 sepolia/2024-08-26-update-batcher-hash/script/UpdateBatcherHash.s.sol diff --git a/sepolia/2024-08-26-update-batcher-hash/.env b/sepolia/2024-08-26-update-batcher-hash/.env new file mode 100644 index 0000000..b3dfead --- /dev/null +++ b/sepolia/2024-08-26-update-batcher-hash/.env @@ -0,0 +1,18 @@ +OP_COMMIT=9047beb54c66a5c572784efec8984f259302ec92 +BASE_CONTRACTS_COMMIT=5d98dab6a4f3ba60713a17417a2df7a17d77c52f + +# Batcher +L1_SYSTEM_CONFIG_ADDRESS=0xf272670eb55e895584501d564AfEB048bEd26194 +SYSTEM_CONFIG_OWNER=0x0fe884546476dDd290eC46318785046ef68a0BA9 +# TO FIX +NEW_BATCH_SENDER=0x4672425C27A942bB27e7b9709c1b21ab89a3cA13 +ROLLBACK_BATCH_SENDER=0x6cdebe940bc0f26850285caca097c11c33103e47 + +# Proposer +DISPUTE_GAME_FACTORY_PROXY=0xd6E6dBf4F7EA0ac412fD8b65ED297e64BB7a06E1 +DISPUTE_GAME_FACTORY_PROXY_OWNER=0x0fe884546476dDd290eC46318785046ef68a0BA9 +PERMISSIONED_DISPUTE_GAME=0x54966d5A42a812D0dAaDe1FA2321FF8b102d1ee1 +NEW_PERMISSIONED_DISPUTE_GAME= +OLD_PROPOSER=0x20044a0d104E9e788A0C984A2B7eAe615afD046b +# TO FIX +NEW_PROPOSER=0x4672425C27A942bB27e7b9709c1b21ab89a3cA13 diff --git a/sepolia/2024-08-26-update-batcher-hash/Makefile b/sepolia/2024-08-26-update-batcher-hash/Makefile new file mode 100644 index 0000000..cfea55c --- /dev/null +++ b/sepolia/2024-08-26-update-batcher-hash/Makefile @@ -0,0 +1,30 @@ +include ../../Makefile +include ../.env +include .env + +ifndef LEDGER_ACCOUNT +override LEDGER_ACCOUNT = 1 # Sepolia using hd-path of 1 +endif + +# Batcher +.PHONY: sign-update-batcher +sign-update-batcher: + $(GOPATH)/bin/eip712sign --ledger --hd-paths "m/44'/60'/$(LEDGER_ACCOUNT)'/0/0" -- \ + forge script --rpc-url $(L1_RPC_URL) UpdateBatcherHash \ + --sig "sign()" + +.PHONY: execute-update-batcher +execute-update-batcher: + forge script --rpc-url $(L1_RPC_URL) UpdateBatcherHash \ + --sig "run(bytes)" $(SIGNATURES) --ledger --hd-paths "m/44'/60'/$(LEDGER_ACCOUNT)'/0/0" + +.PHONY: sign-rollback-batcher +sign-rollback-batcher: + $(GOPATH)/bin/eip712sign --ledger --hd-paths "m/44'/60'/$(LEDGER_ACCOUNT)'/0/0" -- \ + forge script --rpc-url $(L1_RPC_URL) RollbackBatcherHash \ + --sig "sign()" + +.PHONY: execute-rollback-batcher +execute-rollback-batcher: + forge script --rpc-url $(L1_RPC_URL) RollbackBatcherHash \ + --sig "run(bytes)" $(SIGNATURES) --ledger --hd-paths "m/44'/60'/$(LEDGER_ACCOUNT)'/0/0" diff --git a/sepolia/2024-08-26-update-batcher-hash/README.md b/sepolia/2024-08-26-update-batcher-hash/README.md new file mode 100644 index 0000000..2b325d9 --- /dev/null +++ b/sepolia/2024-08-26-update-batcher-hash/README.md @@ -0,0 +1,289 @@ +# Update Batcher and Proposer addresses in L1 for sSepolia-alpha + +Status: ready to execute + +## Objective + +We are updating batcher address for sepolia to a key that is managed by the internal key management service. + +This runbook implements scripts which allow system owner to execute: +1. `UpdateBatcherHash` -- Updates the batcher hash in `SystemConfig` to be the new key. +2. `RollbackBatcherHash` -- Rollback the batcher upgrade. + +The values we are sending are statically defined in the `.env`. + +## Approving the Update transaction + +### 1. Update repo and move to the appropriate folder: +``` +cd contract-deployments +git pull +cd sepolia/2024-08-26-update-batcher-hash +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. Simulate and validate the transaction + +Make sure your ledger is still unlocked and run the following. + +``` shell +make sign-update-batcher +``` + +Once you run the `make sign...` command successfully, 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 then we'll extract the domain hash and +message hash to approve on your Ledger then verify completion: + +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.1. Validate integrity of the simulation. + +Make sure you are on the "Overview" tab of the tenderly simulation, to +validate integrity of the simulation, we need to check the following: + +1. "Network": Check the network is Ethereum 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, + you will need to determine which “number” it is in the list of + addresses on your ledger. +4. "Success" with a green check mark + + +#### 3.2. Validate correctness of the state diff. + +Now click on the "State" tab. Verify that: + +1. Verify that the nonce is incremented for the Incident Multisig under the "SystemConfigProxy" at address `0xf272670eb55e895584501d564AfEB048bEd26194`. We should see the nonce increment from 5 to 6: + +``` +Key: 0x0000000000000000000000000000000000000000000000000000000000000005 +Before: 0x0000000000000000000000000000000000000000000000000000000000000005 +After: 0x00000000000000000000000000000000000000000000000000000000000000006 +``` + +2. Verify the new batcher hash value is appropriately updated under "SystemConfigProxy" at address `0xf272670eb55e895584501d564AfEB048bEd26194`. + +``` +Key: 0x0000000000000000000000000000000000000000000000000000000000000067 +Before: 0x0000000000000000000000006cdebe940bc0f26850285caca097c11c33103e47 +After: 0x0000000000000000000000004672425c27a942bb27e7b9709c1b21ab89a3ca13 (TODO) +``` + +#### 3.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 "Overview" tab, and find the +`GnosisSafe.checkSignatures` call. This call's `data` parameter +contains both the domain hash and the message hash that will show up +in your Ledger. + +Here is an example screenshot. Note that the value will be +different for each signer: + +![Screenshot 2024-03-07 at 5 49 02 PM](https://github.com/base-org/contract-deployments/assets/84420280/1b7905f1-1350-4634-a804-7b4458d0ddc9) + + +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. + +### 4. Approve the signature on your ledger + +Once the validations are done, it's time to actually sign the +transaction. Make sure your ledger is still unlocked and run the +following: + +``` shell +make sign-update-batcher +``` + +> [!IMPORTANT] 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: + +``` +Data: +Signer:
+Signature: +``` + +Double check the signer address is the right one. + +### 5. 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! + + +## Approving the Rollback transaction + +Complete the above steps for `Approving the Update transaction` before continuing below. + +### 1. Simulate and validate the transaction + +Make sure your ledger is still unlocked and run the following. +``` shell +make sign-rollback-batcher +``` +Once you run the make sign command successfully, you will see a "Simulation link" from the output. Once again paste this URL in your browser and click "Simulate Transaction". + +We will be performing 3 validations and then we'll extract the domain hash and +message hash to approve on your Ledger then verify completion: + +1. Validate integrity of the simulation. +2. Validate correctness of the state diff. +3. Validate and extract domain hash and message hash to approve. +4. Validate that the transaction completed successfully + + +#### 3.1. Validate integrity of the simulation. + +Make sure you are on the "Overview" tab of the tenderly simulation, to +validate integrity of the simulation, we need to check the following: + +1. "Network": Check the network is Ethereum 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, + you will need to determine which “number” it is in the list of + addresses on your ledger. +4. "Success" with a green check mark + + +#### 3.2. Validate correctness of the state diff. + +Now click on the "State" tab. Verify that: + +1. Verify that the nonce is incremented for the Incident Multisig under the "GnosisSafeProxy" at address `0x14536667Cd30e52C0b458BaACcB9faDA7046E056`: + +``` +Key: 0x0000000000000000000000000000000000000000000000000000000000000005 +Before: 0x0000000000000000000000000000000000000000000000000000000000000005 +After: 0x00000000000000000000000000000000000000000000000000000000000000006 +``` + +2. Verify that batcher hash value to set under `Events` tab, you should see in the `ConfigUpdate` section: + +``` +{ +"version":"0" +"updateType":0 +"data":"0x0000000000000000000000006cdebe940bc0f26850285caca097c11c33103e47" +} +``` + +#### 3.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 "Overview" tab, and find the +`GnosisSafe.checkSignatures` call. This call's `data` parameter +contains both the domain hash and the message hash that will show up +in your Ledger. + +Here is an example screenshot. Note that the value will be +different for each signer: + +![Screenshot 2024-03-07 at 5 49 32 PM](https://github.com/base-org/contract-deployments/assets/84420280/b6b5817f-0d05-4862-b16a-4f7f5f18f036) + +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. + +### 4. Approve the signature on your ledger + +Once the validations are done, it's time to actually sign the +transaction. Make sure your ledger is still unlocked and run the +following: + +``` shell +make sign-rollback-batcher +``` + +> [!IMPORTANT] 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: + +``` +Data: +Signer:
+Signature: +``` + +Double check the signer address is the right one. + +### 5. 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! + +## Execute the output + +1. Collect outputs from all participating signers. +2. Concatenate all signatures and export it as the `SIGNATURES` + environment variable, i.e. `export + SIGNATURES="0x[SIGNATURE1][SIGNATURE2]..."`. +3. Run `make execute` + +> [!IMPORTANT] IN THE EVENT WE NEED TO PERFORM ROLLBACK +> Repeat the above, but replace the signatures with the signed +> rollback signatures collected, the call `make execute-rollback` diff --git a/sepolia/2024-08-26-update-batcher-hash/foundry.toml b/sepolia/2024-08-26-update-batcher-hash/foundry.toml new file mode 100644 index 0000000..0d7a9ef --- /dev/null +++ b/sepolia/2024-08-26-update-batcher-hash/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 = 999999 +solc_version = "0.8.15" +via-ir = true +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/' +] + +# See more config options https://github.com/foundry-rs/foundry/tree/master/config \ No newline at end of file diff --git a/sepolia/2024-08-26-update-batcher-hash/script/RollbackBatcherHash.s.sol b/sepolia/2024-08-26-update-batcher-hash/script/RollbackBatcherHash.s.sol new file mode 100644 index 0000000..fe1e738 --- /dev/null +++ b/sepolia/2024-08-26-update-batcher-hash/script/RollbackBatcherHash.s.sol @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import {SystemConfig} from "@eth-optimism-bedrock/src/L1/SystemConfig.sol"; +import {Vm} from "forge-std/Vm.sol"; +import "forge-std/Script.sol"; +import "forge-std/console.sol"; +import { + MultisigBuilder, + IMulticall3, + IGnosisSafe, + console, + Enum +} from "@base-contracts/script/universal/MultisigBuilder.sol"; + +contract RollbackBatcherHash is MultisigBuilder { + address internal SYSTEM_CONFIG_OWNER = vm.envAddress("SYSTEM_CONFIG_OWNER"); + address internal L1_SYSTEM_CONFIG = vm.envAddress("L1_SYSTEM_CONFIG_ADDRESS"); + address internal ROLLBACK_BATCH_SENDER = vm.envAddress("ROLLBACK_BATCH_SENDER"); + + function _convertAddressToBytes32(address _address) internal pure returns (bytes32) { + return bytes32(uint256(uint160(_address))); + } + + function _postCheck(Vm.AccountAccess[] memory, SimulationPayload memory) internal view override { + require( + SystemConfig(L1_SYSTEM_CONFIG).batcherHash() == _convertAddressToBytes32(ROLLBACK_BATCH_SENDER), + "Rollback Deploy: batcherHash is incorrect" + ); + console.log("New batcherHash: "); + console.logBytes32(SystemConfig(L1_SYSTEM_CONFIG).batcherHash()); + } + + function _buildCalls() internal view override returns (IMulticall3.Call3[] memory) { + IMulticall3.Call3[] memory calls = new IMulticall3.Call3[](1); + console.log("Current batcherHash: "); + console.logBytes32(SystemConfig(L1_SYSTEM_CONFIG).batcherHash()); + calls[0] = IMulticall3.Call3({ + target: L1_SYSTEM_CONFIG, + allowFailure: false, + callData: abi.encodeCall(SystemConfig.setBatcherHash, (_convertAddressToBytes32(ROLLBACK_BATCH_SENDER))) + }); + + return calls; + } + + function _ownerSafe() internal view override returns (address) { + return SYSTEM_CONFIG_OWNER; + } + + function _addOverrides(address _safe) internal view override returns (SimulationStateOverride memory) { + IGnosisSafe safe = IGnosisSafe(payable(_safe)); + uint256 _nonce = _getNonce(safe); + return overrideSafeThresholdOwnerAndNonce(_safe, DEFAULT_SENDER, _nonce); + } +} diff --git a/sepolia/2024-08-26-update-batcher-hash/script/UpdateBatcherHash.s.sol b/sepolia/2024-08-26-update-batcher-hash/script/UpdateBatcherHash.s.sol new file mode 100644 index 0000000..9dbfb19 --- /dev/null +++ b/sepolia/2024-08-26-update-batcher-hash/script/UpdateBatcherHash.s.sol @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import {SystemConfig} from "@eth-optimism-bedrock/src/L1/SystemConfig.sol"; +import {Vm} from "forge-std/Vm.sol"; +import "forge-std/Script.sol"; +import "forge-std/console.sol"; +import { + MultisigBuilder, + IMulticall3, + IGnosisSafe, + console, + Enum +} from "@base-contracts/script/universal/MultisigBuilder.sol"; + +contract UpdateBatcherHash is MultisigBuilder { + address internal SYSTEM_CONFIG_OWNER = vm.envAddress("SYSTEM_CONFIG_OWNER"); + address internal L1_SYSTEM_CONFIG = vm.envAddress("L1_SYSTEM_CONFIG_ADDRESS"); + address internal NEW_BATCH_SENDER = vm.envAddress("NEW_BATCH_SENDER"); + + function _convertAddressToBytes32(address _address) internal pure returns (bytes32) { + return bytes32(uint256(uint160(_address))); + } + + function _postCheck(Vm.AccountAccess[] memory, SimulationPayload memory) internal view override { + require( + SystemConfig(L1_SYSTEM_CONFIG).batcherHash() == _convertAddressToBytes32(NEW_BATCH_SENDER), + "Rollback Deploy: batcherHash is incorrect" + ); + console.log("New batcherHash: "); + console.logBytes32(SystemConfig(L1_SYSTEM_CONFIG).batcherHash()); + } + + function _buildCalls() internal view override returns (IMulticall3.Call3[] memory) { + IMulticall3.Call3[] memory calls = new IMulticall3.Call3[](1); + console.log("Current batcherHash: "); + console.logBytes32(SystemConfig(L1_SYSTEM_CONFIG).batcherHash()); + calls[0] = IMulticall3.Call3({ + target: L1_SYSTEM_CONFIG, + allowFailure: false, + callData: abi.encodeCall(SystemConfig.setBatcherHash, (_convertAddressToBytes32(NEW_BATCH_SENDER))) + }); + + return calls; + } + + function _ownerSafe() internal view override returns (address) { + return SYSTEM_CONFIG_OWNER; + } + + function _addOverrides(address _safe) internal view override returns (SimulationStateOverride memory) { + IGnosisSafe safe = IGnosisSafe(payable(_safe)); + uint256 _nonce = _getNonce(safe); + return overrideSafeThresholdOwnerAndNonce(_safe, DEFAULT_SENDER, _nonce); + } +}