Last active
December 22, 2024 02:10
-
-
Save brockelmore/76f445bab01c2479f011e66332df7f82 to your computer and use it in GitHub Desktop.
Optimism-Bedrock deployment with foundry
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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