Skip to content

Instantly share code, notes, and snippets.

@brockelmore
Last active April 19, 2024 22:28
Show Gist options
  • Save brockelmore/76f445bab01c2479f011e66332df7f82 to your computer and use it in GitHub Desktop.
Save brockelmore/76f445bab01c2479f011e66332df7f82 to your computer and use it in GitHub Desktop.
Optimism-Bedrock deployment with foundry
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.15;
import "forge-std/Script.sol";
// L1
import { L1CrossDomainMessenger } from "../L1/L1CrossDomainMessenger.sol";
import { L1ERC721Bridge } from "../L1/L1ERC721Bridge.sol";
import { L1StandardBridge } from "../L1/L1StandardBridge.sol";
import { L2OutputOracle } from "../L1/L2OutputOracle.sol";
import { OptimismPortal } from "../L1/OptimismPortal.sol";
import { SystemConfig } from "../L1/SystemConfig.sol";
// deployment
import { PortalSender } from "../deployment/PortalSender.sol";
import { SystemDictator } from "../deployment/SystemDictator.sol";
// Universal
import { Proxy } from "../universal/Proxy.sol";
import { ProxyAdmin } from "../universal/ProxyAdmin.sol";
import { OptimismMintableERC20Factory } from "../universal/OptimismMintableERC20Factory.sol";
import { CrossDomainMessenger } from "../universal/CrossDomainMessenger.sol";
// Legacy
import { AddressManager } from "../legacy/AddressManager.sol";
import { L1ChugSplashProxy } from "../legacy/L1ChugSplashProxy.sol";
import { ResolvedDelegateProxy } from "../legacy/ResolvedDelegateProxy.sol";
library Predeploys {
address constant internal L2ToL1MessagePasser = 0x4200000000000000000000000000000000000016;
address constant internal DeployerWhitelist = 0x4200000000000000000000000000000000000002;
address constant internal L2CrossDomainMessenger = 0x4200000000000000000000000000000000000007;
address constant internal GasPriceOracle = 0x420000000000000000000000000000000000000F;
address constant internal L2StandardBridge = 0x4200000000000000000000000000000000000010;
address constant internal SequencerFeeVault = 0x4200000000000000000000000000000000000011;
address constant internal OptimismMintableERC20Factory = 0x4200000000000000000000000000000000000012;
address constant internal L1BlockNumber = 0x4200000000000000000000000000000000000013;
address constant internal L1Block = 0x4200000000000000000000000000000000000015;
address constant internal LegacyERC20ETH = 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000;
address constant internal WETH9 = 0x4200000000000000000000000000000000000006;
address constant internal GovernanceToken = 0x4200000000000000000000000000000000000042;
address constant internal LegacyMessagePasser = 0x4200000000000000000000000000000000000000;
address constant internal L2ERC721Bridge = 0x4200000000000000000000000000000000000014;
address constant internal OptimismMintableERC721Factory = 0x4200000000000000000000000000000000000017;
address constant internal ProxyAdmin = 0x4200000000000000000000000000000000000018;
address constant internal BaseFeeVault = 0x4200000000000000000000000000000000000019;
address constant internal L1FeeVault = 0x420000000000000000000000000000000000001A;
}
contract Deployer is Script {
// configuration
mapping(string => bytes) default_config;
string config_json;
string deployments;
string deployments_path;
SystemDictator.GlobalConfig globalConfig;
SystemDictator.ProxyAddressConfig proxyAddressConfig;
SystemDictator.ImplementationAddressConfig implementationAddressConfig;
SystemDictator.SystemConfigConfig systemConfigConfig;
SystemDictator.DeployConfig deployConfig;
address tmp_proxy_admin;
// owners and managers
address deployer;
ProxyAdmin pa;
AddressManager am;
// Proxies
L1ChugSplashProxy l1StandardBridgeProxy;
Proxy l2OutputOracleProxy;
ResolvedDelegateProxy l1CrossDomainMessengerProxy;
Proxy optimismPortalProxy;
Proxy optimismMintableERC20FactoryProxy;
Proxy l1ERC721BridgeProxy;
Proxy systemConfigProxy;
Proxy systemDictatorProxy;
// L1
L1CrossDomainMessenger l1CDM;
L1StandardBridge l1StandardBridge;
L1ERC721Bridge l1ERC721Bridge;
L2OutputOracle l2OutputOracle;
OptimismPortal optimismPortal;
OptimismMintableERC20Factory omERC20Factory;
SystemConfig sysConfig;
SystemDictator systemDictator;
// Other
PortalSender portalSender;
function setUp() public {
uint256 pvk = vm.envUint("PRIVATE_KEY_DEPLOYER");
deployer = vm.rememberKey(pvk);
string memory loc = "./deploy-config/";
string memory network = vm.envString("NETWORK");
string memory path = string.concat(loc, network);
string memory full_path = string.concat(path, ".json");
config_json = vm.readFile(full_path);
bool redeploy = false;
try vm.envBool("REDEPLOY") returns (bool a) {
redeploy = a;
} catch {}
string memory dep_loc = "./foundry-deployments/";
string memory dep_path = string.concat(dep_loc, network);
deployments_path = string.concat(dep_path, ".json");
if (!redeploy) {
try vm.readFile(deployments_path) returns (string memory prev_dep) {
deployments = prev_dep;
} catch {
// create the file
vm.writeFile(deployments_path, "{}");
}
} else {
// create the file if it doesnt exist, overwrite it if it does
vm.writeFile(deployments_path, "{}");
}
// set default values for configuration
default_config["l2OutputOracleStartingBlockNumber"] = abi.encode(0);
default_config["finalizationPeriodSeconds"] = abi.encode(2);
default_config["cliqueSignerAddress"] = abi.encode(address(0));
default_config["l1BlockTime"] = abi.encode(15);
default_config["l1GenesisBlockNonce"] = abi.encode(0);
default_config["l1GenesisBlockGasLimit"] = abi.encode(15_000_000);
default_config["l1GenesisBlockDifficulty"] = abi.encode(1);
default_config["l1GenesisBlockMixHash"] = abi.encode(bytes32(0));
default_config["l1GenesisBlockCoinbase"] = abi.encode(address(0));
default_config["l1GenesisBlockNumber"] = abi.encode(0);
default_config["l1GenesisBlockGasUsed"] = abi.encode(0);
default_config["l1GenesisBlockParentHash"] = abi.encode(bytes32(0));
default_config["l1GenesisBlockBaseFeePerGas"] = abi.encode(1000_000_000);
default_config["l2GenesisBlockNonce"] = abi.encode(0);
default_config["l2GenesisBlockGasLimit"] = abi.encode(15_000_000);
default_config["l2GenesisBlockDifficulty"] = abi.encode(1);
default_config["l2GenesisBlockMixHash"] = abi.encode(bytes32(0));
default_config["l2GenesisBlockNumber"] = abi.encode(0);
default_config["l2GenesisBlockGasUsed"] = abi.encode(0);
default_config["l2GenesisBlockParentHash"] = abi.encode(bytes32(0));
default_config["l2GenesisBlockBaseFeePerGas"] = abi.encode(1000_000_000);
default_config["gasPriceOracleOverhead"] = abi.encode(2100);
default_config["gasPriceOracleScalar"] = abi.encode(1_000_000);
default_config["governanceTokenSymbol"] = abi.encode(string("OP"));
default_config["governanceTokenName"] = abi.encode(string("Optimism"));
// update known configurations now
globalConfig.controller = readAddrFromDeployConfig("controller");
globalConfig.finalOwner = readAddrFromDeployConfig("finalSystemOwner");
systemConfigConfig.owner = globalConfig.finalOwner;
systemConfigConfig.overhead = readUintFromDeployConfig("gasPriceOracleOverhead");
systemConfigConfig.scalar = readUintFromDeployConfig("gasPriceOracleScalar");
systemConfigConfig.batcherHash = bytes32(uint256(uint160(readAddrFromDeployConfig("batchSenderAddress"))));
systemConfigConfig.gasLimit = uint64(readUintFromDeployConfig("l2GenesisBlockGasLimit"));
systemConfigConfig.unsafeBlockSigner = readAddrFromDeployConfig("p2pSequencerAddress");
deployConfig.systemConfigConfig = systemConfigConfig;
}
function run() public {
// deploy proxies
deployProxies();
// deploy l1 cross domain messenger
(address l1cdm, ) = noRedeploy(deployL1CDM, "L1CrossDomainMessenger");
l1CDM = L1CrossDomainMessenger(l1cdm);
// deploy l1 standard bridge
(address l1sb, ) = noRedeploy(deployL1StandardBridge, "L1StandardBridge");
l1StandardBridge = L1StandardBridge(payable(l1sb));
// deploy l2 outout oracle
(address l2oo, ) = noRedeploy(deployL2OutputOracle, "L2OutputOracle");
l2OutputOracle = L2OutputOracle(l2oo);
// deploy optimism portal
(address opp, ) = noRedeploy(deployOptimismPortal, "OptimismPortal");
optimismPortal = OptimismPortal(payable(opp));
// deploy erc20 factory
(address omef, ) = noRedeploy(deployOptimismMintableERC20Factory, "OptimismMintableERC20Factory");
omERC20Factory = OptimismMintableERC20Factory(omef);
// deploy L1 erc721 bridge
(address l1eb, ) = noRedeploy(deployL1ERC721Bridge, "L1ERC721Bridge");
l1ERC721Bridge = L1ERC721Bridge(l1eb);
// deploy portal sender
(address ps, ) = noRedeploy(deployPortalSender, "PortalSender");
portalSender = PortalSender(ps);
// deploy system config
(address sysconf, ) = noRedeploy(deploySysConfig, "SystemConfig");
sysConfig = SystemConfig(sysconf);
// deploy system dictator
(address sysDict, ) = noRedeploy(deploySystemDictator, "SystemDictator");
systemDictator = SystemDictator(sysDict);
globalConfig.proxyAdmin = pa;
globalConfig.addressManager = am;
deployConfig.globalConfig = globalConfig;
proxyAddressConfig.l2OutputOracleProxy = address(l2OutputOracleProxy);
proxyAddressConfig.optimismPortalProxy = address(optimismPortalProxy);
proxyAddressConfig.l1CrossDomainMessengerProxy = address(l1CrossDomainMessengerProxy);
proxyAddressConfig.l1StandardBridgeProxy = address(l1StandardBridgeProxy);
proxyAddressConfig.optimismMintableERC20FactoryProxy = address(optimismMintableERC20FactoryProxy);
proxyAddressConfig.l1ERC721BridgeProxy = address(l1ERC721BridgeProxy);
proxyAddressConfig.systemConfigProxy = address(systemConfigProxy);
deployConfig.proxyAddressConfig = proxyAddressConfig;
implementationAddressConfig.l2OutputOracleImpl = l2OutputOracle;
implementationAddressConfig.optimismPortalImpl = optimismPortal;
implementationAddressConfig.l1StandardBridgeImpl = l1StandardBridge;
implementationAddressConfig.optimismMintableERC20FactoryImpl = omERC20Factory;
implementationAddressConfig.l1ERC721BridgeImpl = l1ERC721Bridge;
implementationAddressConfig.portalSenderImpl = portalSender;
implementationAddressConfig.systemConfigImpl = sysConfig;
deployConfig.implementationAddressConfig = implementationAddressConfig;
setupSystemDictator();
}
function readDeployConfig(string memory key) internal returns (bytes memory) {
bytes memory val = vm.parseJson(config_json, key);
return val;
}
function readUintFromDeployConfig(string memory key) internal returns (uint256) {
bytes memory val = readDeployConfig(key);
if (val.length > 0) {
return abi.decode(val, (uint256));
} else {
bytes memory default_conf = default_config[key];
if (default_conf.length > 0) {
return abi.decode(default_conf, (uint256));
} else {
return 0;
}
}
}
function readAddrFromDeployConfig(string memory key) internal returns (address) {
bytes memory val = readDeployConfig(key);
if (val.length > 0) {
return abi.decode(val, (address));
} else {
bytes memory default_conf = default_config[key];
if (default_conf.length > 0) {
return abi.decode(default_conf, (address));
} else {
return address(0);
}
}
}
// Prevents redeployment to a chain
function noRedeploy(function() internal returns (address) fn, string memory contractName) internal returns (address, bool) {
// check if the contract name is in deployments
try vm.parseJson(deployments, contractName) returns (bytes memory deployedTo) {
if (deployedTo.length > 0) {
address someContract = abi.decode(deployedTo, (address));
// some networks are ephemeral so we need to actually confirm it was deployed
// by checking if code is nonzero
if (someContract.code.length > 0) {
vm.label(someContract, contractName);
// we already have it deployed
return (someContract, false);
}
}
} catch {}
vm.startBroadcast(deployer);
address c = fn();
vm.stopBroadcast();
labelAndRecord(c, contractName);
return (c, true);
}
function labelAndRecord(address c, string memory contractName) internal {
vm.label(c, contractName);
string memory a = vm.serializeAddress(deployments, contractName, address(c));
vm.writeFile(deployments_path, a);
}
function deploySystemDictator() internal returns (address) {
systemDictator = new SystemDictator();
return address(systemDictator);
}
function deployL1CDM() internal returns (address) {
l1CDM = new L1CrossDomainMessenger(OptimismPortal(payable(address(optimismPortalProxy))));
require(address(l1CDM.PORTAL()) == address(optimismPortalProxy), "l1CDM.PORTAL != optimismPortalProxy");
require(l1CDM.owner() == address(0), "l1CDM.PORTAL != address(0)");
return address(l1CDM);
}
function deployL1StandardBridge() internal returns (address) {
l1StandardBridge = new L1StandardBridge(payable(address(l1CDM)));
require(l1StandardBridge.MESSENGER() == l1CDM, "l1StandardBridge.MESSENGER != l1CDM");
require(address(l1StandardBridge.OTHER_BRIDGE()) == Predeploys.L2StandardBridge, "l1StandardBridge.OTHER_BRIDGE != Predeploys.L2StandardBridge");
return address(l1StandardBridge);
}
function deployOptimismMintableERC20Factory() internal returns (address) {
omERC20Factory = new OptimismMintableERC20Factory(address(l1StandardBridge));
require(omERC20Factory.BRIDGE() == address(l1StandardBridge), "omERC20Factory.BRIDGE != l1StandardBridge");
return address(omERC20Factory);
}
function deployL1ERC721Bridge() internal returns (address) {
l1ERC721Bridge = new L1ERC721Bridge(address(l1CrossDomainMessengerProxy), Predeploys.L2ERC721Bridge);
require(l1ERC721Bridge.MESSENGER() == CrossDomainMessenger(address(l1CrossDomainMessengerProxy)), "l1ERC721Bridge.MESSENGER != l1CrossDomainMessengerProxy");
return address(l1ERC721Bridge);
}
function deployPortalSender() internal returns (address) {
portalSender = new PortalSender(OptimismPortal(payable(address(optimismPortalProxy))));
require(portalSender.PORTAL() == OptimismPortal(payable(address(optimismPortalProxy))), "portalSender.PORTAL != optimismPortalProxy");
return address(portalSender);
}
function deployL2OutputOracle() internal returns (address) {
l2OutputOracle = new L2OutputOracle(
readUintFromDeployConfig("l2OutputOracleSubmissionInterval"),
readUintFromDeployConfig("l2BlockTime"),
0,
0,
readAddrFromDeployConfig("l2OutputOracleProposer"),
readAddrFromDeployConfig("l2OutputOracleChallenger")
);
require(l2OutputOracle.SUBMISSION_INTERVAL() == readUintFromDeployConfig("l2OutputOracleSubmissionInterval"), "l2OutputOracle.SUBMISSION_INTERVAL != config.l2OutputOracleSubmissionInterval");
require(l2OutputOracle.L2_BLOCK_TIME() == readUintFromDeployConfig("l2BlockTime"), "l2OutputOracle.L2_BLOCK_TIME != config.l2BlockTime");
require(l2OutputOracle.PROPOSER() == readAddrFromDeployConfig("l2OutputOracleProposer"), "l2OutputOracle.L2_BLOCK_TIME != config.l2OutputOracleProposer");
require(l2OutputOracle.CHALLENGER() == readAddrFromDeployConfig("l2OutputOracleChallenger"), "l2OutputOracle.L2_BLOCK_TIME != config.l2OutputOracleChallenger");
return address(l2OutputOracle);
}
function deployOptimismPortal() internal returns (address) {
optimismPortal = new OptimismPortal(
L2OutputOracle(address(l2OutputOracleProxy)),
readUintFromDeployConfig("finalizationPeriodSeconds")
);
require(optimismPortal.L2_ORACLE() == L2OutputOracle(address(l2OutputOracleProxy)), "optimismPortal.L2_ORACLE != l2OutputOracleProxy");
require(optimismPortal.FINALIZATION_PERIOD_SECONDS() == readUintFromDeployConfig("finalizationPeriodSeconds"), "optimismPortal.L2_ORACLE != config.finalizationPeriodSeconds");
return address(optimismPortal);
}
function deploySysConfig() internal returns (address) {
sysConfig = new SystemConfig(
systemConfigConfig.owner,
systemConfigConfig.overhead,
systemConfigConfig.scalar,
systemConfigConfig.batcherHash,
systemConfigConfig.gasLimit,
systemConfigConfig.unsafeBlockSigner
);
require(sysConfig.owner() == systemConfigConfig.owner, "sysConfig.owner != config.finalSystemOwner");
require(sysConfig.overhead() == systemConfigConfig.overhead, "sysConfig.overhead != config.gasPriceOracleOverhead");
require(sysConfig.scalar() == systemConfigConfig.scalar, "sysConfig.scalaer != config.gasPriceOracleScalar");
require(sysConfig.batcherHash() == systemConfigConfig.batcherHash, "sysConfig.batcherHash != hexZeroPad(config.batchSenderAddress)");
require(sysConfig.unsafeBlockSigner() == systemConfigConfig.unsafeBlockSigner, "sysConfig.unsafeBlockSigner != config.p2pSequencerAddress");
return address(sysConfig);
}
function setupSystemDictator() internal {
vm.stopBroadcast();
SystemDictator proxyAsSysDict = SystemDictator(payable(address(systemDictatorProxy)));
vm.prank(address(0));
if (systemDictatorProxy.implementation() != address(systemDictator)) {
console2.log("Upgrading the SystemDictator proxy...");
vm.broadcast(deployer);
systemDictatorProxy.upgradeToAndCall(
address(systemDictator),
abi.encodeWithSelector(proxyAsSysDict.initialize.selector, deployConfig)
);
(
SystemDictator.GlobalConfig memory global,
SystemDictator.ProxyAddressConfig memory proxies,
SystemDictator.ImplementationAddressConfig memory impls,
SystemDictator.SystemConfigConfig memory sys
)= proxyAsSysDict.config();
compareGlobalConfigs(global);
compareProxyConfigs(proxies);
compareImplConfigs(impls);
compareSysConfigs(sys);
}
address controller = globalConfig.controller;
vm.prank(address(0));
if (systemDictatorProxy.admin() != controller) {
vm.broadcast(deployer);
proxyAsSysDict.transferOwnership(controller);
require(systemDictatorProxy.admin() == controller);
}
bool isLiveDeployer = deployer == controller;
if (pa.owner() != address(proxyAsSysDict)) {
console2.log("Setting ProxyAdmin owner to MSD");
vm.broadcast(deployer);
pa.transferOwnership(address(proxyAsSysDict));
} else {
console2.log("ProxyAdmin owner was already MSD");
}
bool needsProxyTransfer = proxyAsSysDict.currentStep() <= proxyAsSysDict.PROXY_TRANSFER_STEP();
if (needsProxyTransfer && am.owner() != address(proxyAsSysDict)) {
if (isLiveDeployer) {
console2.log("Setting AddressManager owner to MSD");
vm.broadcast(deployer);
am.transferOwnership(address(proxyAsSysDict));
} else {
console2.log("Please set AddressManager owner to MSD");
}
} else {
console2.log("AddressManager owner was already MSD");
}
if (
needsProxyTransfer
&& am.getAddress("OVM_L1CrossDomainMessenger") != address(0)
&& L1CrossDomainMessenger(address(l1CrossDomainMessengerProxy)).owner() != address(proxyAsSysDict)
) {
if (isLiveDeployer) {
console2.log("Setting L1CrossDomainMessenger owner to MSD");
vm.broadcast(deployer);
L1CrossDomainMessenger(address(l1CrossDomainMessengerProxy)).transferOwnership(address(proxyAsSysDict));
} else {
console2.log("Please set L1CrossDomainMessenger owner to MSD");
}
} else {
console2.log("L1CrossDomainMessenger owner was already MSD");
}
vm.prank(address(0));
if (
needsProxyTransfer
&& l1StandardBridgeProxy.getOwner() != address(proxyAsSysDict)
) {
if (isLiveDeployer) {
console2.log("Setting L1StandardBridge owner to MSD");
vm.broadcast(deployer);
l1StandardBridgeProxy.setOwner(address(proxyAsSysDict));
} else {
console2.log("Please set L1StandardBridge owner to MSD");
}
} else {
console2.log("L1StandardBridge owner was already MSD");
}
vm.prank(address(0));
if (
needsProxyTransfer
&& l1ERC721BridgeProxy.admin() != address(proxyAsSysDict)
) {
if (isLiveDeployer) {
console2.log("Setting L1ERC721Bridge owner to MSD");
vm.broadcast(deployer);
l1ERC721BridgeProxy.changeAdmin(address(proxyAsSysDict));
} else {
console2.log("Please set L1ERC721Bridge owner to MSD");
}
} else {
console2.log("L1ERC721Bridge owner was already MSD");
}
// do step 1
if (proxyAsSysDict.currentStep() == 1) {
if (isLiveDeployer) {
vm.broadcast(deployer);
proxyAsSysDict.step1();
require(pa.addressManager() == am, "pa addr mngr != addr mngr");
require(keccak256(abi.encodePacked(pa.implementationName(address(l1CrossDomainMessengerProxy)))) == keccak256("OVM_L1CrossDomainMessenger"), "incorrect l1 cross domain messenger proxy");
require(pa.proxyType(address(l1CrossDomainMessengerProxy)) == ProxyAdmin.ProxyType.RESOLVED, "incorrect l1 cross domain messenger proxy type");
require(pa.proxyType(address(l1StandardBridgeProxy)) == ProxyAdmin.ProxyType.CHUGSPLASH, "incorrect l1StandardBridgeProxy proxy type");
require(SystemConfig(address(systemConfigProxy)).owner() == systemConfigConfig.owner, "incorrect system owner");
require(SystemConfig(address(systemConfigProxy)).overhead() == systemConfigConfig.overhead, "incorrect system gas overhead");
require(SystemConfig(address(systemConfigProxy)).scalar() == systemConfigConfig.scalar, "incorrect system gas scalar");
require(SystemConfig(address(systemConfigProxy)).batcherHash() == systemConfigConfig.batcherHash, "incorrect system batcherHash");
require(SystemConfig(address(systemConfigProxy)).gasLimit() == systemConfigConfig.gasLimit, "incorrect system gasLimit");
}
}
if (proxyAsSysDict.currentStep() == 2) {
if (isLiveDeployer) {
vm.broadcast(deployer);
proxyAsSysDict.step2();
require(am.getAddress('OVM_L1CrossDomainMessenger') == address(0), "address manager wasnt updated");
}
}
}
function compareGlobalConfigs(SystemDictator.GlobalConfig memory global) internal {
require(global.addressManager == globalConfig.addressManager, "Mismatch global config");
require(global.proxyAdmin == globalConfig.proxyAdmin, "Mismatch global config");
require(global.controller == globalConfig.controller, "Mismatch global config");
require(global.finalOwner == globalConfig.finalOwner, "Mismatch global config");
}
function compareProxyConfigs(SystemDictator.ProxyAddressConfig memory proxies) internal {
require(proxies.l2OutputOracleProxy == proxyAddressConfig.l2OutputOracleProxy, "mismatch proxy config");
require(proxies.optimismPortalProxy == proxyAddressConfig.optimismPortalProxy, "mismatch proxy config");
require(proxies.l1CrossDomainMessengerProxy == proxyAddressConfig.l1CrossDomainMessengerProxy, "mismatch proxy config");
require(proxies.l1StandardBridgeProxy == proxyAddressConfig.l1StandardBridgeProxy, "mismatch proxy config");
require(proxies.optimismMintableERC20FactoryProxy == proxyAddressConfig.optimismMintableERC20FactoryProxy, "mismatch proxy config");
require(proxies.l1ERC721BridgeProxy == proxyAddressConfig.l1ERC721BridgeProxy, "mismatch proxy config");
require(proxies.systemConfigProxy == proxyAddressConfig.systemConfigProxy, "mismatch proxy config");
}
function compareSysConfigs(SystemDictator.SystemConfigConfig memory sys) internal {
require(sys.owner == systemConfigConfig.owner, "mismatch sys config");
require(sys.overhead == systemConfigConfig.overhead, "mismatch sys config");
require(sys.scalar == systemConfigConfig.scalar, "mismatch sys config");
require(sys.batcherHash == systemConfigConfig.batcherHash, "mismatch sys config");
require(sys.gasLimit == systemConfigConfig.gasLimit, "mismatch sys config");
require(sys.unsafeBlockSigner == systemConfigConfig.unsafeBlockSigner, "mismatch sys config");
}
function compareImplConfigs(SystemDictator.ImplementationAddressConfig memory impl) internal {
require(impl.l2OutputOracleImpl == implementationAddressConfig.l2OutputOracleImpl, "mismatch impl config");
require(impl.optimismPortalImpl == implementationAddressConfig.optimismPortalImpl, "mismatch impl config");
require(impl.l1CrossDomainMessengerImpl == implementationAddressConfig.l1CrossDomainMessengerImpl, "mismatch impl config");
require(impl.l1StandardBridgeImpl == implementationAddressConfig.l1StandardBridgeImpl, "mismatch impl config");
require(impl.optimismMintableERC20FactoryImpl == implementationAddressConfig.optimismMintableERC20FactoryImpl, "mismatch impl config");
require(impl.l1ERC721BridgeImpl == implementationAddressConfig.l1ERC721BridgeImpl, "mismatch impl config");
require(impl.portalSenderImpl == implementationAddressConfig.portalSenderImpl, "mismatch impl config");
require(impl.systemConfigImpl == implementationAddressConfig.systemConfigImpl, "mismatch impl config");
}
function deployProxies() internal {
// deploy proxy admin
pa = deployProxyAdmin(deployer);
// deploy address manager
am = deployAddressManager();
// deploy l1 standard bridge proxy
l1StandardBridgeProxy = deployChugSplashProxy("L1StandardBridgeProxy", deployer);
// deploy l2 Output Oracle proxy
l2OutputOracleProxy = deployProxy("L2OutputOracleProxy", address(pa));
// deploy l1 cross domain messenger proxy
(address l1cdmp, ) = noRedeploy(deployResolvedDelegateProxy, "L1CrossDomainMessengerProxy");
l1CrossDomainMessengerProxy = ResolvedDelegateProxy(payable(l1cdmp));
// deploy Optimism Portal proxy
optimismPortalProxy = deployProxy("OptimismPortalProxy", address(pa));
// deploy optimism mintable ERC20 factory proxy
optimismMintableERC20FactoryProxy = deployProxy("OptimismMintableERC20FactoryProxy", address(pa));
// deploy l1 ERC721 bridge proxy
l1ERC721BridgeProxy = deployProxy("L1ERC721BridgeProxy", deployer);
// deploy system config proxy
systemConfigProxy = deployProxy("SystemConfigProxy", address(pa));
// deploy system dictator proxy
systemDictatorProxy = deployProxy("SystemDictatorProxy", deployer);
}
function deployProxyAdmin(address admin) internal returns (ProxyAdmin) {
tmp_proxy_admin = admin;
(address pAdmin, bool newlyDeployed) = noRedeploy(deployProxyAdminInternal, "ProxyAdmin");
ProxyAdmin proxyAdmin = ProxyAdmin(payable(pAdmin));
if (newlyDeployed) {
vm.prank(address(0));
require(proxyAdmin.owner() == tmp_proxy_admin, "ProxyAdmin.owner != tmp_proxy_admin");
}
return proxyAdmin;
}
function deployProxyAdminInternal() internal returns (address) {
return address(new ProxyAdmin(tmp_proxy_admin));
}
function deployAddressManager() internal returns (AddressManager) {
(address addr, bool newlyDeployed) = noRedeploy(deployAddressManagerInternal, "AddressManager");
AddressManager addrMngr = AddressManager(payable(addr));
if (newlyDeployed) {
vm.prank(address(0));
require(addrMngr.owner() == deployer, "AddressManager.owner != deployer");
}
return addrMngr;
}
function deployAddressManagerInternal() internal returns (address) {
return address(new AddressManager());
}
function deployResolvedDelegateProxy() internal returns (address) {
return address(new ResolvedDelegateProxy(am, "OVM_L1CrossDomainMessenger"));
}
function deployChugSplashProxy(string memory name, address admin) internal returns (L1ChugSplashProxy) {
tmp_proxy_admin = admin;
(address csp, bool newlyDeployed) = noRedeploy(deployChugSplashProxyInternal, name);
L1ChugSplashProxy proxy = L1ChugSplashProxy(payable(csp));
if (newlyDeployed) {
vm.prank(address(0));
require(proxy.getOwner() == admin, "L1ChugSplashProxy.getOwner != deployer");
}
return proxy;
}
function deployChugSplashProxyInternal() internal returns (address) {
return address(new L1ChugSplashProxy(tmp_proxy_admin));
}
function deployProxy(string memory name, address admin) internal returns (Proxy) {
tmp_proxy_admin = admin;
(address p, bool newlyDeployed) = noRedeploy(deployProxyInternal, name);
Proxy proxy = Proxy(payable(p));
if (newlyDeployed) {
vm.prank(address(0));
require(proxy.admin() == tmp_proxy_admin, "proxy.admin != tmp_proxy_admin");
}
return proxy;
}
function deployProxyInternal() internal returns (address) {
return address(new Proxy(tmp_proxy_admin));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment