From 57d68f520f0439ca0c7500c5cada7d6a34213d8a Mon Sep 17 00:00:00 2001 From: Baptiste Oueriagli Date: Tue, 23 Apr 2024 12:24:05 +0000 Subject: [PATCH 1/2] migrate to security-council --- .../.env | 16 ++ .../Makefile | 71 +++++++ .../README_L1.md | 195 +++++++++++++++++ .../README_L2.md | 201 ++++++++++++++++++ .../foundry.toml | 19 ++ .../script/MigrateL1ToSecurityCouncil.sol | 37 ++++ .../script/MigrateL2ToSecurityCouncil.sol | 37 ++++ 7 files changed, 576 insertions(+) create mode 100644 mainnet/2024-04-23-migrate-to-security-council/.env create mode 100644 mainnet/2024-04-23-migrate-to-security-council/Makefile create mode 100644 mainnet/2024-04-23-migrate-to-security-council/README_L1.md create mode 100644 mainnet/2024-04-23-migrate-to-security-council/README_L2.md create mode 100644 mainnet/2024-04-23-migrate-to-security-council/foundry.toml create mode 100644 mainnet/2024-04-23-migrate-to-security-council/script/MigrateL1ToSecurityCouncil.sol create mode 100644 mainnet/2024-04-23-migrate-to-security-council/script/MigrateL2ToSecurityCouncil.sol diff --git a/mainnet/2024-04-23-migrate-to-security-council/.env b/mainnet/2024-04-23-migrate-to-security-council/.env new file mode 100644 index 00000000..642b23c1 --- /dev/null +++ b/mainnet/2024-04-23-migrate-to-security-council/.env @@ -0,0 +1,16 @@ +OP_COMMIT=08f3dbed90faccb36135fc4bd1d40bfa8ed4066f +BASE_CONTRACTS_COMMIT=a0f86fcf67e61f08ba7d7a8b26256963379b8a60 + +# L1 configuration +L1_PROXY_ADMIN=0x0475cBCAebd9CE8AfA5025828d5b98DFb67E059E +L1_NESTED_SAFE=0x7bB41C3008B3f03FE483B28b8DB90e19Cf07595c +L1_BASE_SAFE=0x9855054731540A48b28990B63DcF4f33d8AE46A1 +L1_OP_SAFE=0x9BA6e03D8B90dE867373Db8cF1A58d2F7F006b3A +L1_DELAYED_VETOABLE=0x000000000000000000000000000000000000cafe + +# L2 configuration +L2_PROXY_ADMIN=0x4200000000000000000000000000000000000018 +L2_NESTED_SAFE=0x2304CB33d95999dC29f4CeF1e35065e670a70050 +L2_BASE_SAFE=0xd94E416cf2c7167608B2515B7e4102B41efff94f +L2_OP_SAFE=0x28EDB11394eb271212ED66c08f2b7893C04C5D65 +L2_DELAYED_VETOABLE=0x000000000000000000000000000000000000cafe diff --git a/mainnet/2024-04-23-migrate-to-security-council/Makefile b/mainnet/2024-04-23-migrate-to-security-council/Makefile new file mode 100644 index 00000000..2e9d46f9 --- /dev/null +++ b/mainnet/2024-04-23-migrate-to-security-council/Makefile @@ -0,0 +1,71 @@ +include ../../Makefile +include ../.env +include .env + +ifndef LEDGER_ACCOUNT +override LEDGER_ACCOUNT = 0 +endif + +### L1 migration commands + +.PHONY: sign-cb-l1 +sign-cb-l1: + $(GOPATH)/bin/eip712sign --ledger --hd-paths "m/44'/60'/$(LEDGER_ACCOUNT)'/0/0" -- \ + forge script --rpc-url $(L1_RPC_URL) MigrateL1ToSecurityCouncil \ + --sig "sign(address)" $(L1_BASE_SAFE) + +.PHONY: sign-op-l1 +sign-op-l1: + $(GOPATH)/bin/eip712sign --ledger --hd-paths "m/44'/60'/$(LEDGER_ACCOUNT)'/0/0" -- \ + forge script --rpc-url $(L1_RPC_URL) MigrateL1ToSecurityCouncil \ + --sig "sign(address)" $(L1_OP_SAFE) + + +.PHONY: approve-cb-l1 +approve-cb-l1: + forge script --rpc-url $(L1_RPC_URL) MigrateL1ToSecurityCouncil \ + --sig "approve(address,bytes)" $(L1_BASE_SAFE) $(SIGNATURES) \ + --ledger --hd-paths "m/44'/60'/$(LEDGER_ACCOUNT)'/0/0" + +.PHONY: approve-op-l1 +approve-op-l1: + forge script --rpc-url $(L1_RPC_URL) MigrateL1ToSecurityCouncil \ + --sig "approve(address,bytes)" $(L1_OP_SAFE) $(SIGNATURES) \ + --ledger --hd-paths "m/44'/60'/$(LEDGER_ACCOUNT)'/0/0" + +.PHONY: execute-l1 +execute-l1: + forge script --rpc-url $(L1_RPC_URL) MigrateL1ToSecurityCouncil \ + --sig "run()" --ledger --hd-paths "m/44'/60'/$(LEDGER_ACCOUNT)'/0/0" + +### L2 migration commands + +.PHONY: sign-cb-l2 +sign-cb-l2: + $(GOPATH)/bin/eip712sign --ledger --hd-paths "m/44'/60'/$(LEDGER_ACCOUNT)'/0/0" -- \ + forge script --rpc-url $(L2_RPC_URL) MigrateL2ToSecurityCouncil \ + --sig "sign(address)" $(L2_BASE_SAFE) + +.PHONY: sign-op-l2 +sign-op-l2: + $(GOPATH)/bin/eip712sign --ledger --hd-paths "m/44'/60'/$(LEDGER_ACCOUNT)'/0/0" -- \ + forge script --rpc-url $(L2_RPC_URL) MigrateL2ToSecurityCouncil \ + --sig "sign(address)" $(L2_OP_SAFE) + + +.PHONY: approve-cb-l2 +approve-cb-l2: + forge script --rpc-url $(L2_RPC_URL) MigrateL2ToSecurityCouncil \ + --sig "approve(address,bytes)" $(L2_BASE_SAFE) $(SIGNATURES) \ + --ledger --hd-paths "m/44'/60'/$(LEDGER_ACCOUNT)'/0/0" + +.PHONY: approve-op-l2 +approve-op-l2: + forge script --rpc-url $(L2_RPC_URL) MigrateL2ToSecurityCouncil \ + --sig "approve(address,bytes)" $(L2_OP_SAFE) $(SIGNATURES) \ + --ledger --hd-paths "m/44'/60'/$(LEDGER_ACCOUNT)'/0/0" + +.PHONY: execute-l2 +execute-l2: + forge script --rpc-url $(L2_RPC_URL) MigrateL2ToSecurityCouncil \ + --sig "run()" --ledger --hd-paths "m/44'/60'/$(LEDGER_ACCOUNT)'/0/0" diff --git a/mainnet/2024-04-23-migrate-to-security-council/README_L1.md b/mainnet/2024-04-23-migrate-to-security-council/README_L1.md new file mode 100644 index 00000000..6d3dd6e4 --- /dev/null +++ b/mainnet/2024-04-23-migrate-to-security-council/README_L1.md @@ -0,0 +1,195 @@ +# Migrate to Security Council on L1 + +Status: READY TO SIGN + +## Objective + +This task performs the migration from the 2/2 Nested Safe to the Security Council on Ethereum mainnet by udpating the ProxyAdmin [owner](https://etherscan.io/address/0x0475cBCAebd9CE8AfA5025828d5b98DFb67E059E#readContract#F6) from the [Nested Safe](https://etherscan.io/address/0x7bB41C3008B3f03FE483B28b8DB90e19Cf07595c#code) to the [DeleayedVetoable](TBD). + +## Approving the transaction + +### 1. Update repo and move to the appropriate folder: + +``` +cd contract-deployments +git pull +cd mainnet/2024-04-23-migrate-to-security-council +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-op-l1 # or make sign-cb-l1 for Coinbase signers +``` + +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. +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 Nested Multisig under the "GnosisSafeProxy" at address `0x7bb41c3008b3f03fe483b28b8db90e19cf07595c`: + +``` +Key: 0x0000000000000000000000000000000000000000000000000000000000000005 +Before: 0x0000000000000000000000000000000000000000000000000000000000000001 +After: 0x0000000000000000000000000000000000000000000000000000000000000002 +``` + +2. And for the same contract, verify that this specific execution is approved: + +``` +Key (if you are an OP signer): 0xe90bab20817c4baefb196a6db6043a5e4ab858154ae4c68fac9560335412107f +Key (if you are a CB signer): 0x63f218de6984b9cd553109ae3cb8e4da02ad64220d1bae968ff0833a72234d4d +Before: 0x0000000000000000000000000000000000000000000000000000000000000000 +After: 0x0000000000000000000000000000000000000000000000000000000000000001 +``` + +3. Verify that the nonce is incremented for your multisig: + +If you are an OP signer - the OP Foundation Multisig should be under the "GnosisSafeProxy" at address `0x9BA6e03D8B90dE867373Db8cF1A58d2F7F006b3A`: + +``` +Key: 0x0000000000000000000000000000000000000000000000000000000000000005 +Before: 0x000000000000000000000000000000000000000000000000000000000000005c +After: 0x000000000000000000000000000000000000000000000000000000000000005d +``` + +If you are a CB signer - the Coinbase Multisig should be under the address `0x9855054731540a48b28990b63dcf4f33d8ae46a1`: + +``` +Key: 0x0000000000000000000000000000000000000000000000000000000000000005 +Before: 0x000000000000000000000000000000000000000000000000000000000000000b +After: 0x000000000000000000000000000000000000000000000000000000000000000c +``` + +4. Verify that the ProxyAdmin contract at address `0x0475cbcaebd9ce8afa5025828d5b98dfb67e059e` has its owner updated to the `DelayedVetoable` contract at address `0x000000000000000000000000000000000000cafe`: + +``` +Key: 0x0000000000000000000000000000000000000000000000000000000000000000 +Before: 0x0000000000000000000000007bb41c3008b3f03fe483b28b8db90e19cf07595c +After: 0x000000000000000000000000000000000000000000000000000000000000cafe +``` + +5. Verify that the nonce for the sending address is appropriately incremented: + +``` +Nonce 0 -> 1 +``` + +#### 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 +`GnosisSafeL2.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 hash value may be +different: + +image + +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-op-l1 # or make sign-cb-l1 for Coinbase signers +``` + +> [!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! + +## [For Facilitator ONLY] How to execute the rehearsal + +### [After the rehearsal] 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 approve-cb-l1` with Coinbase signer signatures. +4. Run `make approve-op-l1` with Optimism signer signatures. +4. Run `make execute-l1` to execute the transaction onchain. + diff --git a/mainnet/2024-04-23-migrate-to-security-council/README_L2.md b/mainnet/2024-04-23-migrate-to-security-council/README_L2.md new file mode 100644 index 00000000..42b5f969 --- /dev/null +++ b/mainnet/2024-04-23-migrate-to-security-council/README_L2.md @@ -0,0 +1,201 @@ +# Migrate to Security Council on L2 + +Status: READY TO SIGN + +## Objective + +This task performs the migration from the 2/2 Nested Safe to the Security Council on Ethereum mainnet by udpating the ProxyAdmin [owner](https://etherscan.io/address/0x0475cBCAebd9CE8AfA5025828d5b98DFb67E059E#readContract#F6) from the [Nested Safe](https://etherscan.io/address/0x7bB41C3008B3f03FE483B28b8DB90e19Cf07595c#code) to the [DeleayedVetoable](TBD). + +## Approving the transaction + +### 1. Update repo and move to the appropriate folder: + +``` +cd contract-deployments +git pull +cd mainnet/2024-04-23-migrate-to-security-council +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-op-l2 # or make sign-cb-l2 for Coinbase signers +``` + +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. +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 Base 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 Nested Multisig under the "GnosisSafeProxy" at address `0x2304CB33d95999dC29f4CeF1e35065e670a70050`: + +``` +Key: 0x0000000000000000000000000000000000000000000000000000000000000005 +Before: 0x0000000000000000000000000000000000000000000000000000000000000003 +After: 0x0000000000000000000000000000000000000000000000000000000000000004 +``` + +2. For the same contract, verify that this specific execution is approved: + +``` +Key (if you are an OP signer): 0xdeffc934ea69025de735812acd65795f23eb4298f10a9ab589aa248bd4158100 +Key (if you are a CB signer): 0x06853935fddd4b1957d232ae52f6e2085b3b9ff565bd3f07300b8dfe55fa5ca3 +Before: 0x0000000000000000000000000000000000000000000000000000000000000000 +After: 0x0000000000000000000000000000000000000000000000000000000000000001 +``` + +3. Verify that the nonce is incremented for your multisig: + +If you are an OP signer - the OP Foundation Multisig should be under the "GnosisSafeProxy" at address `0x28edb11394eb271212ed66c08f2b7893c04c5d65`: + +``` +Key: 0x0000000000000000000000000000000000000000000000000000000000000005 +Before: 0x0000000000000000000000000000000000000000000000000000000000000003 +After: 0x0000000000000000000000000000000000000000000000000000000000000004 +``` + +If you are a CB signer - the Coinbase Multisig should be under the address `0xd94e416cf2c7167608b2515b7e4102b41efff94f`: + +``` +Key: 0x0000000000000000000000000000000000000000000000000000000000000005 +Before: 0x0000000000000000000000000000000000000000000000000000000000000006 +After: 0x0000000000000000000000000000000000000000000000000000000000000007 +``` + +4. Verify that the ProxyAdmin contract at address `0x4200000000000000000000000000000000000018` has its owner updated to the `DelayedVetoable` contract at address `0x000000000000000000000000000000000000cafe`: + +``` +Key: 0x0000000000000000000000000000000000000000000000000000000000000000 +Before: 0x0000000000000000000000002304cb33d95999dc29f4cef1e35065e670a70050 +After: 0x000000000000000000000000000000000000000000000000000000000000cafe +``` + +5. Verify that the L1FeeVault at `0x420000000000000000000000000000000000001a` receives the gas associated with the call: + +``` +Balance 2265189312213159486 -> 2265189469116205614 +``` + +6. Verify that the nonce for the sending address is appropriately incremented: + +``` +Nonce 0 -> 1 +``` + +#### 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 +`GnosisSafeL2.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 hash value may be +different: + +image + +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-op-l2 # or make sign-cb-l2 for Coinbase signers +``` + +> [!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! + +## [For Facilitator ONLY] How to execute the rehearsal + +### [After the rehearsal] 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 approve-cb-l2` with Coinbase signer signatures. +4. Run `make approve-op-l2` with Optimism signer signatures. +4. Run `make execute-l2` to execute the transaction onchain. + diff --git a/mainnet/2024-04-23-migrate-to-security-council/foundry.toml b/mainnet/2024-04-23-migrate-to-security-council/foundry.toml new file mode 100644 index 00000000..991457c3 --- /dev/null +++ b/mainnet/2024-04-23-migrate-to-security-council/foundry.toml @@ -0,0 +1,19 @@ +[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', + '@base-contracts/=lib/base-contracts', + 'solady/=lib/solady/src/', +] + +# See more config options https://github.com/foundry-rs/foundry/tree/master/config diff --git a/mainnet/2024-04-23-migrate-to-security-council/script/MigrateL1ToSecurityCouncil.sol b/mainnet/2024-04-23-migrate-to-security-council/script/MigrateL1ToSecurityCouncil.sol new file mode 100644 index 00000000..62b4e734 --- /dev/null +++ b/mainnet/2024-04-23-migrate-to-security-council/script/MigrateL1ToSecurityCouncil.sol @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import "@base-contracts/script/universal/NestedMultisigBuilder.sol"; + +interface IProxyAdmin { + function owner() external returns (address); + function transferOwnership(address newOwner) external; +} + +contract MigrateL1ToSecurityCouncil is NestedMultisigBuilder { + address proxyAdmin = vm.envAddress("L1_PROXY_ADMIN"); + address delayedVetoable = vm.envAddress("L1_DELAYED_VETOABLE"); + address nestedSafe = vm.envAddress("L1_NESTED_SAFE"); + + function _postCheck(Vm.AccountAccess[] memory, SimulationPayload memory) internal override { + address newOwner = IProxyAdmin(proxyAdmin).owner(); + if (newOwner != delayedVetoable) { + revert("New owner not correctly set"); + } + } + + function _buildCalls() internal view override returns (IMulticall3.Call3[] memory) { + IMulticall3.Call3[] memory calls = new IMulticall3.Call3[](1); + calls[0] = IMulticall3.Call3({ + target: address(proxyAdmin), + allowFailure: false, + callData: abi.encodeCall(IProxyAdmin.transferOwnership, (delayedVetoable)) + }); + + return calls; + } + + function _ownerSafe() internal view override returns (address) { + return nestedSafe; + } +} diff --git a/mainnet/2024-04-23-migrate-to-security-council/script/MigrateL2ToSecurityCouncil.sol b/mainnet/2024-04-23-migrate-to-security-council/script/MigrateL2ToSecurityCouncil.sol new file mode 100644 index 00000000..a907fc81 --- /dev/null +++ b/mainnet/2024-04-23-migrate-to-security-council/script/MigrateL2ToSecurityCouncil.sol @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import "@base-contracts/script/universal/NestedMultisigBuilder.sol"; + +interface IProxyAdmin { + function owner() external returns (address); + function transferOwnership(address newOwner) external; +} + +contract MigrateL2ToSecurityCouncil is NestedMultisigBuilder { + address proxyAdmin = vm.envAddress("L2_PROXY_ADMIN"); + address delayedVetoable = vm.envAddress("L2_DELAYED_VETOABLE"); + address nestedSafe = vm.envAddress("L2_NESTED_SAFE"); + + function _postCheck(Vm.AccountAccess[] memory, SimulationPayload memory) internal override { + address newOwner = IProxyAdmin(proxyAdmin).owner(); + if (newOwner != delayedVetoable) { + revert("New owner not correctly set"); + } + } + + function _buildCalls() internal view override returns (IMulticall3.Call3[] memory) { + IMulticall3.Call3[] memory calls = new IMulticall3.Call3[](1); + calls[0] = IMulticall3.Call3({ + target: address(proxyAdmin), + allowFailure: false, + callData: abi.encodeCall(IProxyAdmin.transferOwnership, (delayedVetoable)) + }); + + return calls; + } + + function _ownerSafe() internal view override returns (address) { + return nestedSafe; + } +} From 309e3ed1224e41be8dea7fa943b6924fa4c24e78 Mon Sep 17 00:00:00 2001 From: Baptiste Oueriagli Date: Wed, 1 May 2024 10:31:46 +0000 Subject: [PATCH 2/2] remove l2 configuration --- .../.env | 7 - .../Makefile | 34 --- .../{README_L1.md => README.md} | 0 .../README_L2.md | 201 ------------------ .../script/MigrateL2ToSecurityCouncil.sol | 37 ---- 5 files changed, 279 deletions(-) rename mainnet/2024-04-23-migrate-to-security-council/{README_L1.md => README.md} (100%) delete mode 100644 mainnet/2024-04-23-migrate-to-security-council/README_L2.md delete mode 100644 mainnet/2024-04-23-migrate-to-security-council/script/MigrateL2ToSecurityCouncil.sol diff --git a/mainnet/2024-04-23-migrate-to-security-council/.env b/mainnet/2024-04-23-migrate-to-security-council/.env index 642b23c1..24241a2c 100644 --- a/mainnet/2024-04-23-migrate-to-security-council/.env +++ b/mainnet/2024-04-23-migrate-to-security-council/.env @@ -7,10 +7,3 @@ L1_NESTED_SAFE=0x7bB41C3008B3f03FE483B28b8DB90e19Cf07595c L1_BASE_SAFE=0x9855054731540A48b28990B63DcF4f33d8AE46A1 L1_OP_SAFE=0x9BA6e03D8B90dE867373Db8cF1A58d2F7F006b3A L1_DELAYED_VETOABLE=0x000000000000000000000000000000000000cafe - -# L2 configuration -L2_PROXY_ADMIN=0x4200000000000000000000000000000000000018 -L2_NESTED_SAFE=0x2304CB33d95999dC29f4CeF1e35065e670a70050 -L2_BASE_SAFE=0xd94E416cf2c7167608B2515B7e4102B41efff94f -L2_OP_SAFE=0x28EDB11394eb271212ED66c08f2b7893C04C5D65 -L2_DELAYED_VETOABLE=0x000000000000000000000000000000000000cafe diff --git a/mainnet/2024-04-23-migrate-to-security-council/Makefile b/mainnet/2024-04-23-migrate-to-security-council/Makefile index 2e9d46f9..db7e322d 100644 --- a/mainnet/2024-04-23-migrate-to-security-council/Makefile +++ b/mainnet/2024-04-23-migrate-to-security-council/Makefile @@ -6,8 +6,6 @@ ifndef LEDGER_ACCOUNT override LEDGER_ACCOUNT = 0 endif -### L1 migration commands - .PHONY: sign-cb-l1 sign-cb-l1: $(GOPATH)/bin/eip712sign --ledger --hd-paths "m/44'/60'/$(LEDGER_ACCOUNT)'/0/0" -- \ @@ -37,35 +35,3 @@ approve-op-l1: execute-l1: forge script --rpc-url $(L1_RPC_URL) MigrateL1ToSecurityCouncil \ --sig "run()" --ledger --hd-paths "m/44'/60'/$(LEDGER_ACCOUNT)'/0/0" - -### L2 migration commands - -.PHONY: sign-cb-l2 -sign-cb-l2: - $(GOPATH)/bin/eip712sign --ledger --hd-paths "m/44'/60'/$(LEDGER_ACCOUNT)'/0/0" -- \ - forge script --rpc-url $(L2_RPC_URL) MigrateL2ToSecurityCouncil \ - --sig "sign(address)" $(L2_BASE_SAFE) - -.PHONY: sign-op-l2 -sign-op-l2: - $(GOPATH)/bin/eip712sign --ledger --hd-paths "m/44'/60'/$(LEDGER_ACCOUNT)'/0/0" -- \ - forge script --rpc-url $(L2_RPC_URL) MigrateL2ToSecurityCouncil \ - --sig "sign(address)" $(L2_OP_SAFE) - - -.PHONY: approve-cb-l2 -approve-cb-l2: - forge script --rpc-url $(L2_RPC_URL) MigrateL2ToSecurityCouncil \ - --sig "approve(address,bytes)" $(L2_BASE_SAFE) $(SIGNATURES) \ - --ledger --hd-paths "m/44'/60'/$(LEDGER_ACCOUNT)'/0/0" - -.PHONY: approve-op-l2 -approve-op-l2: - forge script --rpc-url $(L2_RPC_URL) MigrateL2ToSecurityCouncil \ - --sig "approve(address,bytes)" $(L2_OP_SAFE) $(SIGNATURES) \ - --ledger --hd-paths "m/44'/60'/$(LEDGER_ACCOUNT)'/0/0" - -.PHONY: execute-l2 -execute-l2: - forge script --rpc-url $(L2_RPC_URL) MigrateL2ToSecurityCouncil \ - --sig "run()" --ledger --hd-paths "m/44'/60'/$(LEDGER_ACCOUNT)'/0/0" diff --git a/mainnet/2024-04-23-migrate-to-security-council/README_L1.md b/mainnet/2024-04-23-migrate-to-security-council/README.md similarity index 100% rename from mainnet/2024-04-23-migrate-to-security-council/README_L1.md rename to mainnet/2024-04-23-migrate-to-security-council/README.md diff --git a/mainnet/2024-04-23-migrate-to-security-council/README_L2.md b/mainnet/2024-04-23-migrate-to-security-council/README_L2.md deleted file mode 100644 index 42b5f969..00000000 --- a/mainnet/2024-04-23-migrate-to-security-council/README_L2.md +++ /dev/null @@ -1,201 +0,0 @@ -# Migrate to Security Council on L2 - -Status: READY TO SIGN - -## Objective - -This task performs the migration from the 2/2 Nested Safe to the Security Council on Ethereum mainnet by udpating the ProxyAdmin [owner](https://etherscan.io/address/0x0475cBCAebd9CE8AfA5025828d5b98DFb67E059E#readContract#F6) from the [Nested Safe](https://etherscan.io/address/0x7bB41C3008B3f03FE483B28b8DB90e19Cf07595c#code) to the [DeleayedVetoable](TBD). - -## Approving the transaction - -### 1. Update repo and move to the appropriate folder: - -``` -cd contract-deployments -git pull -cd mainnet/2024-04-23-migrate-to-security-council -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-op-l2 # or make sign-cb-l2 for Coinbase signers -``` - -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. -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 Base 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 Nested Multisig under the "GnosisSafeProxy" at address `0x2304CB33d95999dC29f4CeF1e35065e670a70050`: - -``` -Key: 0x0000000000000000000000000000000000000000000000000000000000000005 -Before: 0x0000000000000000000000000000000000000000000000000000000000000003 -After: 0x0000000000000000000000000000000000000000000000000000000000000004 -``` - -2. For the same contract, verify that this specific execution is approved: - -``` -Key (if you are an OP signer): 0xdeffc934ea69025de735812acd65795f23eb4298f10a9ab589aa248bd4158100 -Key (if you are a CB signer): 0x06853935fddd4b1957d232ae52f6e2085b3b9ff565bd3f07300b8dfe55fa5ca3 -Before: 0x0000000000000000000000000000000000000000000000000000000000000000 -After: 0x0000000000000000000000000000000000000000000000000000000000000001 -``` - -3. Verify that the nonce is incremented for your multisig: - -If you are an OP signer - the OP Foundation Multisig should be under the "GnosisSafeProxy" at address `0x28edb11394eb271212ed66c08f2b7893c04c5d65`: - -``` -Key: 0x0000000000000000000000000000000000000000000000000000000000000005 -Before: 0x0000000000000000000000000000000000000000000000000000000000000003 -After: 0x0000000000000000000000000000000000000000000000000000000000000004 -``` - -If you are a CB signer - the Coinbase Multisig should be under the address `0xd94e416cf2c7167608b2515b7e4102b41efff94f`: - -``` -Key: 0x0000000000000000000000000000000000000000000000000000000000000005 -Before: 0x0000000000000000000000000000000000000000000000000000000000000006 -After: 0x0000000000000000000000000000000000000000000000000000000000000007 -``` - -4. Verify that the ProxyAdmin contract at address `0x4200000000000000000000000000000000000018` has its owner updated to the `DelayedVetoable` contract at address `0x000000000000000000000000000000000000cafe`: - -``` -Key: 0x0000000000000000000000000000000000000000000000000000000000000000 -Before: 0x0000000000000000000000002304cb33d95999dc29f4cef1e35065e670a70050 -After: 0x000000000000000000000000000000000000000000000000000000000000cafe -``` - -5. Verify that the L1FeeVault at `0x420000000000000000000000000000000000001a` receives the gas associated with the call: - -``` -Balance 2265189312213159486 -> 2265189469116205614 -``` - -6. Verify that the nonce for the sending address is appropriately incremented: - -``` -Nonce 0 -> 1 -``` - -#### 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 -`GnosisSafeL2.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 hash value may be -different: - -image - -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-op-l2 # or make sign-cb-l2 for Coinbase signers -``` - -> [!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! - -## [For Facilitator ONLY] How to execute the rehearsal - -### [After the rehearsal] 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 approve-cb-l2` with Coinbase signer signatures. -4. Run `make approve-op-l2` with Optimism signer signatures. -4. Run `make execute-l2` to execute the transaction onchain. - diff --git a/mainnet/2024-04-23-migrate-to-security-council/script/MigrateL2ToSecurityCouncil.sol b/mainnet/2024-04-23-migrate-to-security-council/script/MigrateL2ToSecurityCouncil.sol deleted file mode 100644 index a907fc81..00000000 --- a/mainnet/2024-04-23-migrate-to-security-council/script/MigrateL2ToSecurityCouncil.sol +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -import "@base-contracts/script/universal/NestedMultisigBuilder.sol"; - -interface IProxyAdmin { - function owner() external returns (address); - function transferOwnership(address newOwner) external; -} - -contract MigrateL2ToSecurityCouncil is NestedMultisigBuilder { - address proxyAdmin = vm.envAddress("L2_PROXY_ADMIN"); - address delayedVetoable = vm.envAddress("L2_DELAYED_VETOABLE"); - address nestedSafe = vm.envAddress("L2_NESTED_SAFE"); - - function _postCheck(Vm.AccountAccess[] memory, SimulationPayload memory) internal override { - address newOwner = IProxyAdmin(proxyAdmin).owner(); - if (newOwner != delayedVetoable) { - revert("New owner not correctly set"); - } - } - - function _buildCalls() internal view override returns (IMulticall3.Call3[] memory) { - IMulticall3.Call3[] memory calls = new IMulticall3.Call3[](1); - calls[0] = IMulticall3.Call3({ - target: address(proxyAdmin), - allowFailure: false, - callData: abi.encodeCall(IProxyAdmin.transferOwnership, (delayedVetoable)) - }); - - return calls; - } - - function _ownerSafe() internal view override returns (address) { - return nestedSafe; - } -}