diff --git a/packages/contracts-bedrock/foundry.toml b/packages/contracts-bedrock/foundry.toml index 5c812b95828d4..9161d0d8770a0 100644 --- a/packages/contracts-bedrock/foundry.toml +++ b/packages/contracts-bedrock/foundry.toml @@ -22,6 +22,7 @@ no_match_contract = 'EchidnaFuzz' fs_permissions = [ { 'access'='read-write', 'path'='./.resource-metering.csv' }, + { 'access'='read', 'path'='./deployments/' }, ] [profile.ci] diff --git a/packages/contracts-bedrock/scripts/multisig/CheckForBedrockMigration.s.sol b/packages/contracts-bedrock/scripts/multisig/CheckForBedrockMigration.s.sol new file mode 100644 index 0000000000000..d26537bd68a8f --- /dev/null +++ b/packages/contracts-bedrock/scripts/multisig/CheckForBedrockMigration.s.sol @@ -0,0 +1,221 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { console2 } from "forge-std/console2.sol"; +import { Script } from "forge-std/Script.sol"; +import { StdAssertions } from "forge-std/StdAssertions.sol"; + +/** + * @title BedrockMigrationChecker + * @notice A script to check safety of multisig operations for Bedrock. + * The usage is as follows: + * $ forge script scripts/CheckForBedrockMigration.s.sol \ + * --rpc-url $ETH_RPC_URL + */ + +contract BedrockMigrationChecker is Script, StdAssertions { + + struct ContractSet { + // Please keep these sorted by name. + address AddressManager; + address L1CrossDomainMessengerImpl; + address L1CrossDomainMessengerProxy; + address L1ERC721BridgeImpl; + address L1ERC721BridgeProxy; + address L1ProxyAdmin; + address L1StandardBridgeImpl; + address L1StandardBridgeProxy; + address L1UpgradeKey; + address L2OutputOracleImpl; + address L2OutputOracleProxy; + address OptimismMintableERC20FactoryImpl; + address OptimismMintableERC20FactoryProxy; + address OptimismPortalImpl; + address OptimismPortalProxy; + address PortalSender; + address SystemConfigProxy; + address SystemDictatorImpl; + address SystemDictatorProxy; + } + + /** + * @notice The entrypoint function. + */ + function run() external { + string memory bedrockJsonDir = vm.envString("BEDROCK_JSON_DIR"); + console2.log("BEDROCK_JSON_DIR = %s", bedrockJsonDir); + ContractSet memory contracts = getContracts(bedrockJsonDir); + checkAddressManager(contracts); + checkL1CrossDomainMessengerImpl(contracts); + checkL1CrossDomainMessengerProxy(contracts); + checkL1ERC721BridgeImpl(contracts); + checkL1ERC721BridgeProxy(contracts); + checkL1ProxyAdmin(contracts); + checkL1StandardBridgeImpl(contracts); + checkL1StandardBridgeProxy(contracts); + checkL1UpgradeKey(contracts); + checkL2OutputOracleImpl(contracts); + checkL2OutputOracleProxy(contracts); + checkOptimismMintableERC20FactoryImpl(contracts); + checkOptimismMintableERC20FactoryProxy(contracts); + checkOptimismPortalImpl(contracts); + checkOptimismPortalProxy(contracts); + checkPortalSender(contracts); + checkSystemConfigProxy(contracts); + checkSystemDictatorImpl(contracts); + checkSystemDictatorProxy(contracts); + } + + function checkAddressManager(ContractSet memory contracts) internal { + console2.log("Checking AddressManager %s", contracts.AddressManager); + checkAddressIsExpected(contracts.L1UpgradeKey, contracts.AddressManager, "owner()"); + } + + function checkL1CrossDomainMessengerImpl(ContractSet memory contracts) internal { + console2.log("Checking L1CrossDomainMessenger %s", contracts.L1CrossDomainMessengerImpl); + checkAddressIsExpected(contracts.OptimismPortalProxy, contracts.L1CrossDomainMessengerImpl, "PORTAL()"); + } + + function checkL1CrossDomainMessengerProxy(ContractSet memory contracts) internal { + console2.log("Checking L1CrossDomainMessengerProxy %s", contracts.L1CrossDomainMessengerProxy); + checkAddressIsExpected(contracts.L1UpgradeKey, contracts.L1CrossDomainMessengerProxy, "owner()"); + checkAddressIsExpected(contracts.AddressManager, contracts.L1CrossDomainMessengerProxy, "libAddressManager()"); + } + + function checkL1ERC721BridgeImpl(ContractSet memory contracts) internal { + console2.log("Checking L1ERC721Bridge %s", contracts.L1ERC721BridgeImpl); + checkAddressIsExpected(contracts.L1CrossDomainMessengerProxy, contracts.L1ERC721BridgeImpl, "messenger()"); + } + + function checkL1ERC721BridgeProxy(ContractSet memory contracts) internal { + console2.log("Checking L1ERC721BridgeProxy %s", contracts.L1ERC721BridgeProxy); + checkAddressIsExpected(contracts.L1UpgradeKey, contracts.L1ERC721BridgeProxy, "admin()"); + checkAddressIsExpected(contracts.L1CrossDomainMessengerProxy, contracts.L1ERC721BridgeProxy, "messenger()"); + } + + function checkL1ProxyAdmin(ContractSet memory contracts) internal { + console2.log("Checking L1ProxyAdmin %s", contracts.L1ProxyAdmin); + checkAddressIsExpected(contracts.L1UpgradeKey, contracts.L1ProxyAdmin, "owner()"); + } + + function checkL1StandardBridgeImpl(ContractSet memory contracts) internal { + console2.log("Checking L1StandardBridge %s", contracts.L1StandardBridgeImpl); + checkAddressIsExpected(contracts.L1CrossDomainMessengerProxy, contracts.L1StandardBridgeImpl, "messenger()"); + } + + function checkL1StandardBridgeProxy(ContractSet memory contracts) internal { + console2.log("Checking L1StandardBridgeProxy %s", contracts.L1StandardBridgeProxy); + checkAddressIsExpected(contracts.L1UpgradeKey, contracts.L1StandardBridgeProxy, "getOwner()"); + checkAddressIsExpected(contracts.L1CrossDomainMessengerProxy, contracts.L1StandardBridgeProxy, "messenger()"); + } + + function checkL1UpgradeKey(ContractSet memory contracts) internal { + console2.log("Checking L1UpgradeKeyAddress %s", contracts.L1UpgradeKey); + // No need to check anything here, so just printing the address. + } + + function checkL2OutputOracleImpl(ContractSet memory contracts) internal { + console2.log("Checking L2OutputOracle %s", contracts.L2OutputOracleImpl); + checkAddressIsExpected(contracts.L1UpgradeKey, contracts.L2OutputOracleImpl, "CHALLENGER()"); + // 604800 seconds = 7 days, reusing the logic in + // checkAddressIsExpected for simplicity. + checkAddressIsExpected(address(604800), contracts.L2OutputOracleImpl, "FINALIZATION_PERIOD_SECONDS()"); + } + + function checkL2OutputOracleProxy(ContractSet memory contracts) internal { + console2.log("Checking L2OutputOracleProxy %s", contracts.L2OutputOracleProxy); + checkAddressIsExpected(contracts.L1ProxyAdmin, contracts.L2OutputOracleProxy, "admin()"); + } + + function checkOptimismMintableERC20FactoryImpl(ContractSet memory contracts) internal { + console2.log("Checking OptimismMintableERC20Factory %s", contracts.OptimismMintableERC20FactoryImpl); + checkAddressIsExpected(contracts.L1StandardBridgeProxy, contracts.OptimismMintableERC20FactoryImpl, "BRIDGE()"); + } + + function checkOptimismMintableERC20FactoryProxy(ContractSet memory contracts) internal { + console2.log("Checking OptimismMintableERC20FactoryProxy %s", contracts.OptimismMintableERC20FactoryProxy); + checkAddressIsExpected(contracts.L1ProxyAdmin, contracts.OptimismMintableERC20FactoryProxy, "admin()"); + } + + function checkOptimismPortalImpl(ContractSet memory contracts) internal { + console2.log("Checking OptimismPortal %s", contracts.OptimismPortalImpl); + checkAddressIsExpected(contracts.L2OutputOracleProxy, contracts.OptimismPortalImpl, "L2_ORACLE()"); + } + + function checkOptimismPortalProxy(ContractSet memory contracts) internal { + console2.log("Checking OptimismPortalProxy %s", contracts.OptimismPortalProxy); + checkAddressIsExpected(contracts.L1ProxyAdmin, contracts.OptimismPortalProxy, "admin()"); + } + + function checkPortalSender(ContractSet memory contracts) internal { + console2.log("Checking PortalSender %s", contracts.PortalSender); + checkAddressIsExpected(contracts.OptimismPortalProxy, contracts.PortalSender, "PORTAL()"); + } + + function checkSystemConfigProxy(ContractSet memory contracts) internal { + console2.log("Checking SystemConfigProxy %s", contracts.SystemConfigProxy); + checkAddressIsExpected(contracts.L1ProxyAdmin, contracts.SystemConfigProxy, "admin()"); + } + + function checkSystemDictatorImpl(ContractSet memory contracts) internal { + console2.log("Checking SystemDictator %s", contracts.SystemDictatorImpl); + checkAddressIsExpected(address(0), contracts.SystemDictatorImpl, "owner()"); + } + + function checkSystemDictatorProxy(ContractSet memory contracts) internal { + console2.log("Checking SystemDictatorProxy %s", contracts.SystemDictatorProxy); + checkAddressIsExpected(contracts.SystemDictatorImpl, contracts.SystemDictatorProxy, "implementation()"); + checkAddressIsExpected(contracts.L1UpgradeKey, contracts.SystemDictatorProxy, "owner()"); + checkAddressIsExpected(contracts.L1UpgradeKey, contracts.SystemDictatorProxy, "admin()"); + } + + function checkAddressIsExpected(address expectedAddr, address contractAddr, string memory signature) internal { + address actual = getAddressFromCall(contractAddr, signature); + if (expectedAddr != actual) { + console2.log(" !! Error: %s != %s.%s, ", expectedAddr, contractAddr, signature); + console2.log(" which is %s", actual); + } else { + console2.log(" -- Success: %s == %s.%s.", expectedAddr, contractAddr, signature); + } + } + + function getAddressFromCall(address contractAddr, string memory signature) internal returns (address) { + vm.prank(address(0)); + (bool success, bytes memory addrBytes) = contractAddr.staticcall(abi.encodeWithSignature(signature)); + if (!success) { + console2.log(" !! Error calling %s.%s", contractAddr, signature); + return address(0); + } + return abi.decode(addrBytes, (address)); + } + + function getContracts(string memory bedrockJsonDir) internal returns (ContractSet memory) { + return ContractSet({ + AddressManager: getAddressFromJson(string.concat(bedrockJsonDir, "/Lib_AddressManager.json")), + L1CrossDomainMessengerImpl: getAddressFromJson(string.concat(bedrockJsonDir, "/L1CrossDomainMessenger.json")), + L1CrossDomainMessengerProxy: getAddressFromJson(string.concat(bedrockJsonDir, "/L1CrossDomainMessengerProxy.json")), + L1ERC721BridgeImpl: getAddressFromJson(string.concat(bedrockJsonDir, "/L1ERC721Bridge.json")), + L1ERC721BridgeProxy: getAddressFromJson(string.concat(bedrockJsonDir, "/L1ERC721BridgeProxy.json")), + L1ProxyAdmin: getAddressFromJson(string.concat(bedrockJsonDir, "/ProxyAdmin.json")), + L1StandardBridgeImpl: getAddressFromJson(string.concat(bedrockJsonDir, "/L1StandardBridge.json")), + L1StandardBridgeProxy: getAddressFromJson(string.concat(bedrockJsonDir, "/L1StandardBridgeProxy.json")), + L1UpgradeKey: vm.envAddress("L1_UPGRADE_KEY"), + L2OutputOracleImpl: getAddressFromJson(string.concat(bedrockJsonDir, "/L2OutputOracle.json")), + L2OutputOracleProxy: getAddressFromJson(string.concat(bedrockJsonDir, "/L2OutputOracleProxy.json")), + OptimismMintableERC20FactoryImpl: getAddressFromJson(string.concat(bedrockJsonDir, "/OptimismMintableERC20Factory.json")), + OptimismMintableERC20FactoryProxy: getAddressFromJson(string.concat(bedrockJsonDir, "/OptimismMintableERC20FactoryProxy.json")), + OptimismPortalImpl: getAddressFromJson(string.concat(bedrockJsonDir, "/OptimismPortal.json")), + OptimismPortalProxy: getAddressFromJson(string.concat(bedrockJsonDir, "/OptimismPortalProxy.json")), + PortalSender: getAddressFromJson(string.concat(bedrockJsonDir, "/PortalSender.json")), + SystemConfigProxy: getAddressFromJson(string.concat(bedrockJsonDir, "/SystemConfigProxy.json")), + SystemDictatorImpl: getAddressFromJson(string.concat(bedrockJsonDir, "/SystemDictator.json")), + SystemDictatorProxy: getAddressFromJson(string.concat(bedrockJsonDir, "/SystemDictatorProxy.json")) + }); + } + + function getAddressFromJson(string memory jsonPath) internal returns (address) { + string memory json = vm.readFile(jsonPath); + return vm.parseJsonAddress(json, ".address"); + } + +} diff --git a/packages/contracts-bedrock/scripts/multisig/README.md b/packages/contracts-bedrock/scripts/multisig/README.md new file mode 100644 index 0000000000000..eff88431ce224 --- /dev/null +++ b/packages/contracts-bedrock/scripts/multisig/README.md @@ -0,0 +1,81 @@ +## Multisig Operation Scripts + +A collection of scripts used by multisig signers to verify the +integrity of the transactions to be signed. + + +### Contract Verification for Bedrock Migration + +[CheckForBedrockMigration.s.sol](./CheckForBedrockMigration.s.sol) is +a script used by the Bedrock migration signers before the migration, +to verify the contracts affected by the migration are always under the +control of the multisig, and security critical configurations are +correctly initialized. + +Example usage: + +``` bash +git clone git@github.com:ethereum-optimism/optimism.git +cd optimism/ +git pull +git checkout develop +nvm use +yarn install +yarn clean +yarn build +cd packages/contracts-bedrock +export L1_UPGRADE_KEY=0x9BA6e03D8B90dE867373Db8cF1A58d2F7F006b3A +export BEDROCK_JSON_DIR=deployments/mainnet +forge script scripts/multisig/CheckForBedrockMigration.s.sol --rpc-url +``` + +Expected output: + +``` bash +Script ran successfully. + + BEDROCK_JSON_DIR = deployments/mainnet + Checking AddressManager 0xdE1FCfB0851916CA5101820A69b13a4E276bd81F + -- Success: 0x9BA6e03D8B90dE867373Db8cF1A58d2F7F006b3A == 0xdE1FCfB0851916CA5101820A69b13a4E276bd81F.owner(). + Checking L1CrossDomainMessenger 0x2150Bc3c64cbfDDbaC9815EF615D6AB8671bfe43 + -- Success: 0xbEb5Fc579115071764c7423A4f12eDde41f106Ed == 0x2150Bc3c64cbfDDbaC9815EF615D6AB8671bfe43.PORTAL(). + Checking L1CrossDomainMessengerProxy 0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1 + -- Success: 0x9BA6e03D8B90dE867373Db8cF1A58d2F7F006b3A == 0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1.owner(). + -- Success: 0xdE1FCfB0851916CA5101820A69b13a4E276bd81F == 0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1.libAddressManager(). + Checking L1ERC721Bridge 0x4afDD3A48E13B305e98D9EEad67B1b5867E370DF + -- Success: 0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1 == 0x4afDD3A48E13B305e98D9EEad67B1b5867E370DF.messenger(). + Checking L1ERC721BridgeProxy 0x5a7749f83b81B301cAb5f48EB8516B986DAef23D + -- Success: 0x9BA6e03D8B90dE867373Db8cF1A58d2F7F006b3A == 0x5a7749f83b81B301cAb5f48EB8516B986DAef23D.admin(). + -- Success: 0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1 == 0x5a7749f83b81B301cAb5f48EB8516B986DAef23D.messenger(). + Checking L1ProxyAdmin 0x543bA4AADBAb8f9025686Bd03993043599c6fB04 + -- Success: 0xB4453CEb33d2e67FA244A24acf2E50CEF31F53cB == 0x543bA4AADBAb8f9025686Bd03993043599c6fB04.owner(). + Checking L1StandardBridge 0xBFB731Cd36D26c2a7287716DE857E4380C73A64a + -- Success: 0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1 == 0xBFB731Cd36D26c2a7287716DE857E4380C73A64a.messenger(). + Checking L1StandardBridgeProxy 0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1 + -- Success: 0x9BA6e03D8B90dE867373Db8cF1A58d2F7F006b3A == 0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1.getOwner(). + -- Success: 0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1 == 0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1.messenger(). + Checking L1UpgradeKeyAddress 0x9BA6e03D8B90dE867373Db8cF1A58d2F7F006b3A + Checking L2OutputOracle 0xd2E67B6a032F0A9B1f569E63ad6C38f7342c2e00 + -- Success: 0x9BA6e03D8B90dE867373Db8cF1A58d2F7F006b3A == 0xd2E67B6a032F0A9B1f569E63ad6C38f7342c2e00.CHALLENGER(). + -- Success: 0x0000000000000000000000000000000000093A80 == 0xd2E67B6a032F0A9B1f569E63ad6C38f7342c2e00.FINALIZATION_PERIOD_SECONDS(). + Checking L2OutputOracleProxy 0xdfe97868233d1aa22e815a266982f2cf17685a27 + -- Success: 0x543bA4AADBAb8f9025686Bd03993043599c6fB04 == 0xdfe97868233d1aa22e815a266982f2cf17685a27.admin(). + Checking OptimismMintableERC20Factory 0xaE849EFA4BcFc419593420e14707996936E365E2 + -- Success: 0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1 == 0xaE849EFA4BcFc419593420e14707996936E365E2.BRIDGE(). + Checking OptimismMintableERC20FactoryProxy 0x75505a97BD334E7BD3C476893285569C4136Fa0F + -- Success: 0x543bA4AADBAb8f9025686Bd03993043599c6fB04 == 0x75505a97BD334E7BD3C476893285569C4136Fa0F.admin(). + Checking OptimismPortal 0x28a55488fef40005309e2DA0040DbE9D300a64AB + -- Success: 0xdfe97868233d1aa22e815a266982f2cf17685a27 == 0x28a55488fef40005309e2DA0040DbE9D300a64AB.L2_ORACLE(). + Checking OptimismPortalProxy 0xbEb5Fc579115071764c7423A4f12eDde41f106Ed + -- Success: 0x543bA4AADBAb8f9025686Bd03993043599c6fB04 == 0xbEb5Fc579115071764c7423A4f12eDde41f106Ed.admin(). + Checking PortalSender 0x0A893d9576b9cFD9EF78595963dc973238E78210 + -- Success: 0xbEb5Fc579115071764c7423A4f12eDde41f106Ed == 0x0A893d9576b9cFD9EF78595963dc973238E78210.PORTAL(). + Checking SystemConfigProxy 0x229047fed2591dbec1eF1118d64F7aF3dB9EB290 + -- Success: 0x543bA4AADBAb8f9025686Bd03993043599c6fB04 == 0x229047fed2591dbec1eF1118d64F7aF3dB9EB290.admin(). + Checking SystemDictator 0x09E040a72FD3492355C5aEEdbC3154075f83488a + -- Success: 0x0000000000000000000000000000000000000000 == 0x09E040a72FD3492355C5aEEdbC3154075f83488a.owner(). + Checking SystemDictatorProxy 0xB4453CEb33d2e67FA244A24acf2E50CEF31F53cB + -- Success: 0x09E040a72FD3492355C5aEEdbC3154075f83488a == 0xB4453CEb33d2e67FA244A24acf2E50CEF31F53cB.implementation(). + -- Success: 0x9BA6e03D8B90dE867373Db8cF1A58d2F7F006b3A == 0xB4453CEb33d2e67FA244A24acf2E50CEF31F53cB.owner(). + -- Success: 0x9BA6e03D8B90dE867373Db8cF1A58d2F7F006b3A == 0xB4453CEb33d2e67FA244A24acf2E50CEF31F53cB.admin(). +``` diff --git a/packages/contracts-bedrock/scripts/multisig/json/mainnet-migration/b1.json b/packages/contracts-bedrock/scripts/multisig/json/mainnet-migration/b1.json new file mode 100644 index 0000000000000..0171bc4acad86 --- /dev/null +++ b/packages/contracts-bedrock/scripts/multisig/json/mainnet-migration/b1.json @@ -0,0 +1,98 @@ +{ + "version": "1.0", + "chainId": "1", + "meta": { + "name": "batch1", + "description": "ProxyAdmin.transferOwnership, AddressManager.transferOwnership, L1StandardBridgeProxy.setOwner, L1ERC721BridgeProxy.changeAdmin, and SystemDictatorProxy.phase1.", + "txBuilderVersion": "1.13.3" + }, + "transactions": [ + { + "to": "0x543bA4AADBAb8f9025686Bd03993043599c6fB04", + "value": "0", + "data": null, + "contractMethod": { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "payable": false + }, + "contractInputsValues": { + "newOwner": "0xB4453CEb33d2e67FA244A24acf2E50CEF31F53cB" + } + }, + { + "to": "0xdE1FCfB0851916CA5101820A69b13a4E276bd81F", + "value": "0", + "data": null, + "contractMethod": { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "payable": false + }, + "contractInputsValues": { + "newOwner": "0xB4453CEb33d2e67FA244A24acf2E50CEF31F53cB" + } + }, + { + "to": "0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1", + "value": "0", + "data": null, + "contractMethod": { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "payable": false + }, + "contractInputsValues": { + "_owner": "0xB4453CEb33d2e67FA244A24acf2E50CEF31F53cB" + } + }, + { + "to": "0x5a7749f83b81B301cAb5f48EB8516B986DAef23D", + "value": "0", + "data": null, + "contractMethod": { + "inputs": [ + { + "internalType": "address", + "name": "_admin", + "type": "address" + } + ], + "name": "changeAdmin", + "payable": false + }, + "contractInputsValues": { + "_admin": "0xB4453CEb33d2e67FA244A24acf2E50CEF31F53cB" + } + }, + { + "to": "0xB4453CEb33d2e67FA244A24acf2E50CEF31F53cB", + "value": "0", + "data": null, + "contractMethod": { + "inputs": [], + "name": "phase1", + "payable": false + }, + "contractInputsValues": {} + } + ] +} diff --git a/packages/contracts-bedrock/scripts/multisig/json/mainnet-migration/b2.json b/packages/contracts-bedrock/scripts/multisig/json/mainnet-migration/b2.json new file mode 100644 index 0000000000000..91cb036f6c754 --- /dev/null +++ b/packages/contracts-bedrock/scripts/multisig/json/mainnet-migration/b2.json @@ -0,0 +1,48 @@ +{ + "version": "1.0", + "chainId": "1", + "meta": { + "name": "batch2", + "description": "SystemDictatorProxy.updateDynamicConfig.", + "txBuilderVersion": "1.13.3" + }, + "transactions": [ + { + "to": "0xB4453CEb33d2e67FA244A24acf2E50CEF31F53cB", + "value": "0", + "data": null, + "contractMethod": { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "l2OutputOracleStartingBlockNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "l2OutputOracleStartingTimestamp", + "type": "uint256" + } + ], + "internalType": "struct SystemDictator.L2OutputOracleDynamicConfig", + "name": "_l2OutputOracleDynamicConfig", + "type": "tuple" + }, + { + "internalType": "bool", + "name": "_optimismPortalDynamicConfig", + "type": "bool" + } + ], + "name": "updateDynamicConfig", + "payable": false + }, + "contractInputsValues": { + "_l2OutputOracleDynamicConfig": "[TBD, TBD]", + "_optimismPortalDynamicConfig": "true" + } + } + ] +} diff --git a/packages/contracts-bedrock/scripts/multisig/json/mainnet-migration/b3.json b/packages/contracts-bedrock/scripts/multisig/json/mainnet-migration/b3.json new file mode 100644 index 0000000000000..f2fd1ead29838 --- /dev/null +++ b/packages/contracts-bedrock/scripts/multisig/json/mainnet-migration/b3.json @@ -0,0 +1,33 @@ +{ + "version": "1.0", + "chainId": "1", + "meta": { + "name": "batch3", + "description": "SystemDictatorProxy.phase2 and OptimismPortalProxy.unpause.", + "txBuilderVersion": "1.13.3" + }, + "transactions": [ + { + "to": "0xB4453CEb33d2e67FA244A24acf2E50CEF31F53cB", + "value": "0", + "data": null, + "contractMethod": { + "inputs": [], + "name": "phase2", + "payable": false + }, + "contractInputsValues": {} + }, + { + "to": "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed", + "value": "0", + "data": null, + "contractMethod": { + "inputs": [], + "name": "unpause", + "payable": false + }, + "contractInputsValues": {} + } + ] +} diff --git a/packages/contracts-bedrock/scripts/multisig/json/mainnet-migration/escapeHatch.json b/packages/contracts-bedrock/scripts/multisig/json/mainnet-migration/escapeHatch.json new file mode 100644 index 0000000000000..928d9b3f7c219 --- /dev/null +++ b/packages/contracts-bedrock/scripts/multisig/json/mainnet-migration/escapeHatch.json @@ -0,0 +1,33 @@ +{ + "version": "1.0", + "chainId": "1", + "meta": { + "name": "EscapeHatch", + "description": "SystemDictatorProxy.exit1 and finalize.", + "txBuilderVersion": "1.14.1" + }, + "transactions": [ + { + "to": "0xB4453CEb33d2e67FA244A24acf2E50CEF31F53cB", + "value": "0", + "data": null, + "contractMethod": { + "inputs": [], + "name": "exit1", + "payable": false + }, + "contractInputsValues": null + }, + { + "to": "0xB4453CEb33d2e67FA244A24acf2E50CEF31F53cB", + "value": "0", + "data": null, + "contractMethod": { + "inputs": [], + "name": "finalize", + "payable": false + }, + "contractInputsValues": null + } + ] +}