Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
485de298
Commit
485de298
authored
May 30, 2023
by
Kevin Chen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add multisig transactions and verification script for bedrock migration.
parent
499c0f0e
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
403 additions
and
0 deletions
+403
-0
foundry.toml
packages/contracts-bedrock/foundry.toml
+1
-0
CheckForBedrockMigration.s.sol
...s-bedrock/scripts/multisig/CheckForBedrockMigration.s.sol
+209
-0
b1.json
...s-bedrock/scripts/multisig/json/mainnet-migration/b1.json
+79
-0
b2.json
...s-bedrock/scripts/multisig/json/mainnet-migration/b2.json
+48
-0
b3.json
...s-bedrock/scripts/multisig/json/mainnet-migration/b3.json
+33
-0
escapeHatch.json
.../scripts/multisig/json/mainnet-migration/escapeHatch.json
+33
-0
No files found.
packages/contracts-bedrock/foundry.toml
View file @
485de298
...
@@ -22,6 +22,7 @@ no_match_contract = 'EchidnaFuzz'
...
@@ -22,6 +22,7 @@ no_match_contract = 'EchidnaFuzz'
fs_permissions
=
[
fs_permissions
=
[
{
'access'='read-write'
,
'path'='./.resource-metering.csv'
}
,
{
'access'='read-write'
,
'path'='./.resource-metering.csv'
}
,
{
'access'='read'
,
'path'='./deployments/'
}
,
]
]
[profile.ci]
[profile.ci]
...
...
packages/contracts-bedrock/scripts/multisig/CheckForBedrockMigration.s.sol
0 → 100644
View file @
485de298
// 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);
}
function checkL1CrossDomainMessengerProxy(ContractSet memory contracts) internal {
console2.log("Checking L1CrossDomainMessengerProxy %s", contracts.L1CrossDomainMessengerProxy);
}
function checkL1ERC721BridgeImpl(ContractSet memory contracts) internal {
console2.log("Checking L1ERC721Bridge %s", contracts.L1ERC721BridgeImpl);
}
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.SystemDictatorProxy, contracts.L1ProxyAdmin, "owner()");
}
function checkL1StandardBridgeImpl(ContractSet memory contracts) internal {
console2.log("Checking L1StandardBridge %s", contracts.L1StandardBridgeImpl);
}
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);
}
function checkL2OutputOracleImpl(ContractSet memory contracts) internal {
console2.log("Checking L2OutputOracle %s", contracts.L2OutputOracleImpl);
}
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);
}
function checkSystemDictatorImpl(ContractSet memory contracts) internal {
console2.log("Checking SystemDictator %s", contracts.SystemDictatorImpl);
}
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");
}
}
packages/contracts-bedrock/scripts/multisig/json/mainnet-migration/b1.json
0 → 100644
View file @
485de298
{
"version"
:
"1.0"
,
"chainId"
:
"1"
,
"meta"
:
{
"name"
:
"batch1"
,
"description"
:
"AddressManager.transferOwnership, L1StandardBridgeProxy.setOwner, L1ERC721BridgeProxy.changeAdmin, and SystemDictatorProxy.phase1."
,
"txBuilderVersion"
:
"1.13.3"
},
"transactions"
:
[
{
"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"
:
{}
}
]
}
packages/contracts-bedrock/scripts/multisig/json/mainnet-migration/b2.json
0 → 100644
View file @
485de298
{
"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"
}
}
]
}
packages/contracts-bedrock/scripts/multisig/json/mainnet-migration/b3.json
0 → 100644
View file @
485de298
{
"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"
:
{}
}
]
}
packages/contracts-bedrock/scripts/multisig/json/mainnet-migration/escapeHatch.json
0 → 100644
View file @
485de298
{
"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
}
]
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment