Commit d2325e70 authored by clabby's avatar clabby

Start modularizing post deployment checks further

parent 8cd36c2f
...@@ -20,10 +20,12 @@ import { ISystemConfigV0 } from "scripts/interfaces/ISystemConfigV0.sol"; ...@@ -20,10 +20,12 @@ import { ISystemConfigV0 } from "scripts/interfaces/ISystemConfigV0.sol";
import { console2 as console } from "forge-std/console2.sol"; import { console2 as console } from "forge-std/console2.sol";
library ChainAssertions { library ChainAssertions {
/// @notice Asserts the correctness of an L1 deployment /// @notice Asserts the correctness of an L1 deployment. This function expects that all contracts
/// within the `prox` ContractSet are proxies that have been setup and initialized.
function postDeployAssertions( function postDeployAssertions(
Types.ContractSet memory prox, Types.ContractSet memory prox,
DeployConfig cfg, DeployConfig cfg,
uint256 l2OutputOracleStartingBlockNumber,
uint256 l2OutputOracleStartingTimestamp, uint256 l2OutputOracleStartingTimestamp,
Vm vm Vm vm
) )
...@@ -34,26 +36,42 @@ library ChainAssertions { ...@@ -34,26 +36,42 @@ library ChainAssertions {
ResourceMetering.ResourceConfig memory dflt = Constants.DEFAULT_RESOURCE_CONFIG(); ResourceMetering.ResourceConfig memory dflt = Constants.DEFAULT_RESOURCE_CONFIG();
require(keccak256(abi.encode(rcfg)) == keccak256(abi.encode(dflt))); require(keccak256(abi.encode(rcfg)) == keccak256(abi.encode(dflt)));
checkSystemConfig(prox, cfg); checkSystemConfig(prox, cfg, true);
checkL1CrossDomainMessenger(prox, vm); checkL1CrossDomainMessenger(prox, vm);
checkL1StandardBridge(prox); checkL1StandardBridge(prox);
checkL2OutputOracle(prox, cfg, l2OutputOracleStartingTimestamp); checkL2OutputOracle(prox, cfg, l2OutputOracleStartingTimestamp, l2OutputOracleStartingBlockNumber);
checkOptimismMintableERC20Factory(prox); checkOptimismMintableERC20Factory(prox);
checkL1ERC721Bridge(prox); checkL1ERC721Bridge(prox);
checkOptimismPortal(prox, cfg); checkOptimismPortal(prox, cfg, false);
checkProtocolVersions(prox, cfg); checkProtocolVersions(prox, cfg, true);
} }
/// @notice Asserts that the SystemConfig is setup correctly /// @notice Asserts that the SystemConfig is setup correctly
function checkSystemConfig(Types.ContractSet memory proxies, DeployConfig cfg) internal view { function checkSystemConfig(
ISystemConfigV0 config = ISystemConfigV0(proxies.SystemConfig); Types.ContractSet memory _contracts,
require(config.owner() == cfg.finalSystemOwner()); DeployConfig _cfg,
require(config.overhead() == cfg.gasPriceOracleOverhead()); bool _initialized
require(config.scalar() == cfg.gasPriceOracleScalar()); )
require(config.batcherHash() == bytes32(uint256(uint160(cfg.batchSenderAddress())))); internal
require(config.unsafeBlockSigner() == cfg.p2pSequencerAddress()); view
{
ISystemConfigV0 config = ISystemConfigV0(_contracts.SystemConfig);
ResourceMetering.ResourceConfig memory rconfig = Constants.DEFAULT_RESOURCE_CONFIG(); ResourceMetering.ResourceConfig memory rconfig = Constants.DEFAULT_RESOURCE_CONFIG();
if (_initialized) {
require(config.owner() == _cfg.finalSystemOwner());
require(config.overhead() == _cfg.gasPriceOracleOverhead());
require(config.scalar() == _cfg.gasPriceOracleScalar());
require(config.batcherHash() == bytes32(uint256(uint160(_cfg.batchSenderAddress()))));
require(config.unsafeBlockSigner() == _cfg.p2pSequencerAddress());
} else {
require(config.owner() == address(0xdead));
require(config.overhead() == 0);
require(config.scalar() == 0);
require(config.batcherHash() == bytes32(0));
require(config.unsafeBlockSigner() == address(0));
}
ResourceMetering.ResourceConfig memory resourceConfig = config.resourceConfig(); ResourceMetering.ResourceConfig memory resourceConfig = config.resourceConfig();
require(resourceConfig.maxResourceLimit == rconfig.maxResourceLimit); require(resourceConfig.maxResourceLimit == rconfig.maxResourceLimit);
require(resourceConfig.elasticityMultiplier == rconfig.elasticityMultiplier); require(resourceConfig.elasticityMultiplier == rconfig.elasticityMultiplier);
...@@ -64,86 +82,107 @@ library ChainAssertions { ...@@ -64,86 +82,107 @@ library ChainAssertions {
} }
/// @notice Asserts that the L1CrossDomainMessenger is setup correctly /// @notice Asserts that the L1CrossDomainMessenger is setup correctly
function checkL1CrossDomainMessenger(Types.ContractSet memory proxies, Vm vm) internal view { function checkL1CrossDomainMessenger(Types.ContractSet memory _contracts, Vm _vm) internal view {
L1CrossDomainMessenger messenger = L1CrossDomainMessenger(proxies.L1CrossDomainMessenger); L1CrossDomainMessenger messenger = L1CrossDomainMessenger(_contracts.L1CrossDomainMessenger);
require(address(messenger.portal()) == proxies.OptimismPortal); require(address(messenger.portal()) == _contracts.OptimismPortal);
require(address(messenger.PORTAL()) == proxies.OptimismPortal); require(address(messenger.PORTAL()) == _contracts.OptimismPortal);
bytes32 xdmSenderSlot = vm.load(address(messenger), bytes32(uint256(204))); bytes32 xdmSenderSlot = _vm.load(address(messenger), bytes32(uint256(204)));
require(address(uint160(uint256(xdmSenderSlot))) == Constants.DEFAULT_L2_SENDER); require(address(uint160(uint256(xdmSenderSlot))) == Constants.DEFAULT_L2_SENDER);
} }
/// @notice Asserts that the L1StandardBridge is setup correctly /// @notice Asserts that the L1StandardBridge is setup correctly
function checkL1StandardBridge(Types.ContractSet memory proxies) internal view { function checkL1StandardBridge(Types.ContractSet memory _contracts) internal view {
L1StandardBridge bridge = L1StandardBridge(payable(proxies.L1StandardBridge)); L1StandardBridge bridge = L1StandardBridge(payable(_contracts.L1StandardBridge));
require(address(bridge.MESSENGER()) == proxies.L1CrossDomainMessenger); require(address(bridge.MESSENGER()) == _contracts.L1CrossDomainMessenger);
require(address(bridge.messenger()) == proxies.L1CrossDomainMessenger); require(address(bridge.messenger()) == _contracts.L1CrossDomainMessenger);
require(address(bridge.OTHER_BRIDGE()) == Predeploys.L2_STANDARD_BRIDGE); require(address(bridge.OTHER_BRIDGE()) == Predeploys.L2_STANDARD_BRIDGE);
require(address(bridge.otherBridge()) == Predeploys.L2_STANDARD_BRIDGE); require(address(bridge.otherBridge()) == Predeploys.L2_STANDARD_BRIDGE);
} }
/// @notice Asserts that the L2OutputOracle is setup correctly /// @notice Asserts that the L2OutputOracle is setup correctly
function checkL2OutputOracle( function checkL2OutputOracle(
Types.ContractSet memory proxies, Types.ContractSet memory _contracts,
DeployConfig cfg, DeployConfig _cfg,
uint256 l2OutputOracleStartingTimestamp uint256 _l2OutputOracleStartingBlockNumber,
uint256 _l2OutputOracleStartingTimestamp
) )
internal internal
view view
{ {
L2OutputOracle oracle = L2OutputOracle(proxies.L2OutputOracle); L2OutputOracle oracle = L2OutputOracle(_contracts.L2OutputOracle);
require(oracle.SUBMISSION_INTERVAL() == cfg.l2OutputOracleSubmissionInterval()); require(oracle.SUBMISSION_INTERVAL() == _cfg.l2OutputOracleSubmissionInterval());
require(oracle.submissionInterval() == cfg.l2OutputOracleSubmissionInterval()); require(oracle.submissionInterval() == _cfg.l2OutputOracleSubmissionInterval());
require(oracle.L2_BLOCK_TIME() == cfg.l2BlockTime()); require(oracle.L2_BLOCK_TIME() == _cfg.l2BlockTime());
require(oracle.l2BlockTime() == cfg.l2BlockTime()); require(oracle.l2BlockTime() == _cfg.l2BlockTime());
require(oracle.PROPOSER() == cfg.l2OutputOracleProposer()); require(oracle.PROPOSER() == _cfg.l2OutputOracleProposer());
require(oracle.proposer() == cfg.l2OutputOracleProposer()); require(oracle.proposer() == _cfg.l2OutputOracleProposer());
require(oracle.CHALLENGER() == cfg.l2OutputOracleChallenger()); require(oracle.CHALLENGER() == _cfg.l2OutputOracleChallenger());
require(oracle.challenger() == cfg.l2OutputOracleChallenger()); require(oracle.challenger() == _cfg.l2OutputOracleChallenger());
require(oracle.FINALIZATION_PERIOD_SECONDS() == cfg.finalizationPeriodSeconds()); require(oracle.FINALIZATION_PERIOD_SECONDS() == _cfg.finalizationPeriodSeconds());
require(oracle.finalizationPeriodSeconds() == cfg.finalizationPeriodSeconds()); require(oracle.finalizationPeriodSeconds() == _cfg.finalizationPeriodSeconds());
require(oracle.startingBlockNumber() == cfg.l2OutputOracleStartingBlockNumber()); require(oracle.startingBlockNumber() == _l2OutputOracleStartingBlockNumber);
require(oracle.startingTimestamp() == l2OutputOracleStartingTimestamp); require(oracle.startingTimestamp() == _l2OutputOracleStartingTimestamp);
} }
/// @notice Asserts that the OptimismMintableERC20Factory is setup correctly /// @notice Asserts that the OptimismMintableERC20Factory is setup correctly
function checkOptimismMintableERC20Factory(Types.ContractSet memory proxies) internal view { function checkOptimismMintableERC20Factory(Types.ContractSet memory _contracts) internal view {
OptimismMintableERC20Factory factory = OptimismMintableERC20Factory(proxies.OptimismMintableERC20Factory); OptimismMintableERC20Factory factory = OptimismMintableERC20Factory(_contracts.OptimismMintableERC20Factory);
require(factory.BRIDGE() == proxies.L1StandardBridge); require(factory.BRIDGE() == _contracts.L1StandardBridge);
require(factory.bridge() == proxies.L1StandardBridge); require(factory.bridge() == _contracts.L1StandardBridge);
} }
/// @notice Asserts that the L1ERC721Bridge is setup correctly /// @notice Asserts that the L1ERC721Bridge is setup correctly
function checkL1ERC721Bridge(Types.ContractSet memory proxies) internal view { function checkL1ERC721Bridge(Types.ContractSet memory _contracts) internal view {
L1ERC721Bridge bridge = L1ERC721Bridge(proxies.L1ERC721Bridge); L1ERC721Bridge bridge = L1ERC721Bridge(_contracts.L1ERC721Bridge);
require(address(bridge.MESSENGER()) == proxies.L1CrossDomainMessenger); require(address(bridge.MESSENGER()) == _contracts.L1CrossDomainMessenger);
require(address(bridge.messenger()) == proxies.L1CrossDomainMessenger); require(address(bridge.messenger()) == _contracts.L1CrossDomainMessenger);
require(bridge.OTHER_BRIDGE() == Predeploys.L2_ERC721_BRIDGE); require(bridge.OTHER_BRIDGE() == Predeploys.L2_ERC721_BRIDGE);
require(bridge.otherBridge() == Predeploys.L2_ERC721_BRIDGE); require(bridge.otherBridge() == Predeploys.L2_ERC721_BRIDGE);
} }
/// @notice Asserts the OptimismPortal is setup correctly /// @notice Asserts the OptimismPortal is setup correctly
function checkOptimismPortal(Types.ContractSet memory proxies, DeployConfig cfg) internal view { function checkOptimismPortal(
OptimismPortal portal = OptimismPortal(payable(proxies.OptimismPortal)); Types.ContractSet memory _contracts,
DeployConfig _cfg,
bool _isPaused
)
internal
view
{
OptimismPortal portal = OptimismPortal(payable(_contracts.OptimismPortal));
address guardian = cfg.portalGuardian(); address guardian = _cfg.portalGuardian();
if (guardian.code.length == 0) { if (guardian.code.length == 0) {
console.log("Portal guardian has no code: %s", guardian); console.log("Portal guardian has no code: %s", guardian);
} }
require(address(portal.L2_ORACLE()) == proxies.L2OutputOracle); require(address(portal.L2_ORACLE()) == _contracts.L2OutputOracle);
require(address(portal.l2Oracle()) == proxies.L2OutputOracle); require(address(portal.l2Oracle()) == _contracts.L2OutputOracle);
require(portal.GUARDIAN() == cfg.portalGuardian()); require(portal.GUARDIAN() == _cfg.portalGuardian());
require(portal.guardian() == cfg.portalGuardian()); require(portal.guardian() == _cfg.portalGuardian());
require(address(portal.SYSTEM_CONFIG()) == proxies.SystemConfig); require(address(portal.SYSTEM_CONFIG()) == _contracts.SystemConfig);
require(address(portal.systemConfig()) == proxies.SystemConfig); require(address(portal.systemConfig()) == _contracts.SystemConfig);
require(portal.paused() == false); require(portal.paused() == _isPaused);
} }
/// @notice Asserts that the ProtocolVersions is setup correctly /// @notice Asserts that the ProtocolVersions is setup correctly
function checkProtocolVersions(Types.ContractSet memory proxies, DeployConfig cfg) internal view { function checkProtocolVersions(
ProtocolVersions versions = ProtocolVersions(proxies.ProtocolVersions); Types.ContractSet memory _proxies,
require(versions.owner() == cfg.finalSystemOwner()); DeployConfig _cfg,
require(ProtocolVersion.unwrap(versions.required()) == cfg.requiredProtocolVersion()); bool _initialized
require(ProtocolVersion.unwrap(versions.recommended()) == cfg.recommendedProtocolVersion()); )
internal
view
{
ProtocolVersions versions = ProtocolVersions(_proxies.ProtocolVersions);
if (_initialized) {
require(versions.owner() == _cfg.finalSystemOwner());
require(ProtocolVersion.unwrap(versions.required()) == _cfg.requiredProtocolVersion());
require(ProtocolVersion.unwrap(versions.recommended()) == _cfg.recommendedProtocolVersion());
} else {
require(versions.owner() == address(0xdead));
require(ProtocolVersion.unwrap(versions.required()) == 0);
require(ProtocolVersion.unwrap(versions.recommended()) == 0);
}
} }
} }
...@@ -376,15 +376,13 @@ contract Deploy is Deployer { ...@@ -376,15 +376,13 @@ contract Deploy is Deployer {
_portal: OptimismPortal(payable(portal)) _portal: OptimismPortal(payable(portal))
}); });
require(address(messenger.PORTAL()) == portal);
require(address(messenger.portal()) == portal);
bytes32 xdmSenderSlot = vm.load(address(messenger), bytes32(uint256(204)));
require(address(uint160(uint256(xdmSenderSlot))) == Constants.DEFAULT_L2_SENDER);
save("L1CrossDomainMessenger", address(messenger)); save("L1CrossDomainMessenger", address(messenger));
console.log("L1CrossDomainMessenger deployed at %s", address(messenger)); console.log("L1CrossDomainMessenger deployed at %s", address(messenger));
Types.ContractSet memory contracts = _proxiesUnstrict();
contracts.L1CrossDomainMessenger = address(messenger);
ChainAssertions.checkL1CrossDomainMessenger(contracts, vm);
addr_ = address(messenger); addr_ = address(messenger);
} }
...@@ -405,17 +403,13 @@ contract Deploy is Deployer { ...@@ -405,17 +403,13 @@ contract Deploy is Deployer {
_systemConfig: systemConfig _systemConfig: systemConfig
}); });
require(address(portal.L2_ORACLE()) == address(l2OutputOracle));
require(address(portal.l2Oracle()) == address(l2OutputOracle));
require(portal.GUARDIAN() == guardian);
require(portal.guardian() == guardian);
require(address(portal.SYSTEM_CONFIG()) == address(systemConfig));
require(address(portal.systemConfig()) == address(systemConfig));
require(portal.paused() == true);
save("OptimismPortal", address(portal)); save("OptimismPortal", address(portal));
console.log("OptimismPortal deployed at %s", address(portal)); console.log("OptimismPortal deployed at %s", address(portal));
Types.ContractSet memory contracts = _proxiesUnstrict();
contracts.OptimismPortal = address(portal);
ChainAssertions.checkOptimismPortal(contracts, cfg, true);
addr_ = address(portal); addr_ = address(portal);
} }
...@@ -431,22 +425,13 @@ contract Deploy is Deployer { ...@@ -431,22 +425,13 @@ contract Deploy is Deployer {
_finalizationPeriodSeconds: cfg.finalizationPeriodSeconds() _finalizationPeriodSeconds: cfg.finalizationPeriodSeconds()
}); });
require(oracle.SUBMISSION_INTERVAL() == cfg.l2OutputOracleSubmissionInterval());
require(oracle.submissionInterval() == cfg.l2OutputOracleSubmissionInterval());
require(oracle.L2_BLOCK_TIME() == cfg.l2BlockTime());
require(oracle.l2BlockTime() == cfg.l2BlockTime());
require(oracle.PROPOSER() == cfg.l2OutputOracleProposer());
require(oracle.proposer() == cfg.l2OutputOracleProposer());
require(oracle.CHALLENGER() == cfg.l2OutputOracleChallenger());
require(oracle.challenger() == cfg.l2OutputOracleChallenger());
require(oracle.FINALIZATION_PERIOD_SECONDS() == cfg.finalizationPeriodSeconds());
require(oracle.finalizationPeriodSeconds() == cfg.finalizationPeriodSeconds());
require(oracle.startingBlockNumber() == 0);
require(oracle.startingTimestamp() == 0);
save("L2OutputOracle", address(oracle)); save("L2OutputOracle", address(oracle));
console.log("L2OutputOracle deployed at %s", address(oracle)); console.log("L2OutputOracle deployed at %s", address(oracle));
Types.ContractSet memory contracts = _proxiesUnstrict();
contracts.L2OutputOracle = address(oracle);
ChainAssertions.checkL2OutputOracle(contracts, cfg, 0, 0);
addr_ = address(oracle); addr_ = address(oracle);
} }
...@@ -456,12 +441,13 @@ contract Deploy is Deployer { ...@@ -456,12 +441,13 @@ contract Deploy is Deployer {
OptimismMintableERC20Factory factory = OptimismMintableERC20Factory factory =
new OptimismMintableERC20Factory{ salt: implSalt() }({_bridge: l1standardBridgeProxy}); new OptimismMintableERC20Factory{ salt: implSalt() }({_bridge: l1standardBridgeProxy});
require(factory.BRIDGE() == l1standardBridgeProxy);
require(factory.bridge() == l1standardBridgeProxy);
save("OptimismMintableERC20Factory", address(factory)); save("OptimismMintableERC20Factory", address(factory));
console.log("OptimismMintableERC20Factory deployed at %s", address(factory)); console.log("OptimismMintableERC20Factory deployed at %s", address(factory));
Types.ContractSet memory contracts = _proxiesUnstrict();
contracts.OptimismMintableERC20Factory = address(factory);
ChainAssertions.checkOptimismMintableERC20Factory(contracts);
addr_ = address(factory); addr_ = address(factory);
} }
...@@ -489,6 +475,10 @@ contract Deploy is Deployer { ...@@ -489,6 +475,10 @@ contract Deploy is Deployer {
save("ProtocolVersions", address(versions)); save("ProtocolVersions", address(versions));
console.log("ProtocolVersions deployed at %s", address(versions)); console.log("ProtocolVersions deployed at %s", address(versions));
Types.ContractSet memory contracts = _proxiesUnstrict();
contracts.ProtocolVersions = address(versions);
ChainAssertions.checkProtocolVersions(contracts, cfg, false);
addr_ = address(versions); addr_ = address(versions);
} }
...@@ -524,24 +514,13 @@ contract Deploy is Deployer { ...@@ -524,24 +514,13 @@ contract Deploy is Deployer {
_config: defaultConfig _config: defaultConfig
}); });
require(config.owner() == address(0xdEaD));
require(config.overhead() == 0);
require(config.scalar() == 0);
require(config.unsafeBlockSigner() == address(0));
require(config.batcherHash() == bytes32(0));
require(config.gasLimit() == minimumGasLimit);
ResourceMetering.ResourceConfig memory resourceConfig = config.resourceConfig();
require(resourceConfig.maxResourceLimit == defaultConfig.maxResourceLimit);
require(resourceConfig.elasticityMultiplier == defaultConfig.elasticityMultiplier);
require(resourceConfig.baseFeeMaxChangeDenominator == defaultConfig.baseFeeMaxChangeDenominator);
require(resourceConfig.systemTxMaxGas == defaultConfig.systemTxMaxGas);
require(resourceConfig.minimumBaseFee == defaultConfig.minimumBaseFee);
require(resourceConfig.maximumBaseFee == defaultConfig.maximumBaseFee);
save("SystemConfig", address(config)); save("SystemConfig", address(config));
console.log("SystemConfig deployed at %s", address(config)); console.log("SystemConfig deployed at %s", address(config));
Types.ContractSet memory contracts = _proxiesUnstrict();
contracts.SystemConfig = address(config);
ChainAssertions.checkSystemConfig(contracts, cfg, false);
addr_ = address(config); addr_ = address(config);
} }
...@@ -553,14 +532,13 @@ contract Deploy is Deployer { ...@@ -553,14 +532,13 @@ contract Deploy is Deployer {
_messenger: payable(l1CrossDomainMessengerProxy) _messenger: payable(l1CrossDomainMessengerProxy)
}); });
require(address(bridge.MESSENGER()) == l1CrossDomainMessengerProxy);
require(address(bridge.messenger()) == l1CrossDomainMessengerProxy);
require(address(bridge.OTHER_BRIDGE()) == Predeploys.L2_STANDARD_BRIDGE);
require(address(bridge.otherBridge()) == Predeploys.L2_STANDARD_BRIDGE);
save("L1StandardBridge", address(bridge)); save("L1StandardBridge", address(bridge));
console.log("L1StandardBridge deployed at %s", address(bridge)); console.log("L1StandardBridge deployed at %s", address(bridge));
Types.ContractSet memory contracts = _proxiesUnstrict();
contracts.L1StandardBridge = address(bridge);
ChainAssertions.checkL1StandardBridge(contracts);
addr_ = address(bridge); addr_ = address(bridge);
} }
...@@ -572,14 +550,13 @@ contract Deploy is Deployer { ...@@ -572,14 +550,13 @@ contract Deploy is Deployer {
_otherBridge: Predeploys.L2_ERC721_BRIDGE _otherBridge: Predeploys.L2_ERC721_BRIDGE
}); });
require(address(bridge.MESSENGER()) == l1CrossDomainMessengerProxy);
require(address(bridge.messenger()) == l1CrossDomainMessengerProxy);
require(bridge.OTHER_BRIDGE() == Predeploys.L2_ERC721_BRIDGE);
require(bridge.otherBridge() == Predeploys.L2_ERC721_BRIDGE);
save("L1ERC721Bridge", address(bridge)); save("L1ERC721Bridge", address(bridge));
console.log("L1ERC721Bridge deployed at %s", address(bridge)); console.log("L1ERC721Bridge deployed at %s", address(bridge));
Types.ContractSet memory contracts = _proxiesUnstrict();
contracts.L1ERC721Bridge = address(bridge);
ChainAssertions.checkL1ERC721Bridge(contracts);
addr_ = address(bridge); addr_ = address(bridge);
} }
...@@ -670,7 +647,7 @@ contract Deploy is Deployer { ...@@ -670,7 +647,7 @@ contract Deploy is Deployer {
string memory version = config.version(); string memory version = config.version();
console.log("SystemConfig version: %s", version); console.log("SystemConfig version: %s", version);
ChainAssertions.checkSystemConfig(_proxies(), cfg); ChainAssertions.checkSystemConfig(_proxies(), cfg, true);
} }
/// @notice Initialize the L1StandardBridge /// @notice Initialize the L1StandardBridge
...@@ -795,7 +772,9 @@ contract Deploy is Deployer { ...@@ -795,7 +772,9 @@ contract Deploy is Deployer {
string memory version = oracle.version(); string memory version = oracle.version();
console.log("L2OutputOracle version: %s", version); console.log("L2OutputOracle version: %s", version);
ChainAssertions.checkL2OutputOracle(_proxies(), cfg, cfg.l2OutputOracleStartingTimestamp()); ChainAssertions.checkL2OutputOracle(
_proxies(), cfg, cfg.l2OutputOracleStartingTimestamp(), cfg.l2OutputOracleStartingBlockNumber()
);
} }
/// @notice Initialize the OptimismPortal /// @notice Initialize the OptimismPortal
...@@ -813,7 +792,7 @@ contract Deploy is Deployer { ...@@ -813,7 +792,7 @@ contract Deploy is Deployer {
string memory version = portal.version(); string memory version = portal.version();
console.log("OptimismPortal version: %s", version); console.log("OptimismPortal version: %s", version);
ChainAssertions.checkOptimismPortal(_proxies(), cfg); ChainAssertions.checkOptimismPortal(_proxies(), cfg, false);
} }
function initializeProtocolVersions() public broadcast { function initializeProtocolVersions() public broadcast {
...@@ -841,7 +820,7 @@ contract Deploy is Deployer { ...@@ -841,7 +820,7 @@ contract Deploy is Deployer {
string memory version = versions.version(); string memory version = versions.version();
console.log("ProtocolVersions version: %s", version); console.log("ProtocolVersions version: %s", version);
ChainAssertions.checkProtocolVersions(_proxies(), cfg); ChainAssertions.checkProtocolVersions(_proxies(), cfg, true);
} }
/// @notice Transfer ownership of the ProxyAdmin contract to the final system owner /// @notice Transfer ownership of the ProxyAdmin contract to the final system owner
...@@ -976,4 +955,18 @@ contract Deploy is Deployer { ...@@ -976,4 +955,18 @@ contract Deploy is Deployer {
ProtocolVersions: mustGetAddress("ProtocolVersionsProxy") ProtocolVersions: mustGetAddress("ProtocolVersionsProxy")
}); });
} }
/// @notice Returns the proxy addresses, not reverting if any are unset.
function _proxiesUnstrict() private view returns (Types.ContractSet memory proxies_) {
proxies_ = Types.ContractSet({
L1CrossDomainMessenger: getAddress("L1CrossDomainMessengerProxy"),
L1StandardBridge: getAddress("L1StandardBridgeProxy"),
L2OutputOracle: getAddress("L2OutputOracleProxy"),
OptimismMintableERC20Factory: getAddress("OptimismMintableERC20FactoryProxy"),
OptimismPortal: getAddress("OptimismPortalProxy"),
SystemConfig: getAddress("SystemConfigProxy"),
L1ERC721Bridge: getAddress("L1ERC721BridgeProxy"),
ProtocolVersions: getAddress("ProtocolVersionsProxy")
});
}
} }
...@@ -30,6 +30,17 @@ struct Artifact { ...@@ -30,6 +30,17 @@ struct Artifact {
string userdoc; string userdoc;
} }
/// @notice Contains information about a storage slot. Mirrors the layout of the storage
/// slot object in Forge artifacts so that we can deserialize JSON into this struct.
struct StorageSlot {
uint256 astId;
string _contract;
string label;
uint256 offset;
string slot;
string _type;
}
/// @title Deployer /// @title Deployer
/// @author tynes /// @author tynes
/// @notice A contract that can make deploying and interacting with deployments easy. /// @notice A contract that can make deploying and interacting with deployments easy.
...@@ -427,6 +438,26 @@ abstract contract Deployer is Script { ...@@ -427,6 +438,26 @@ abstract contract Deployer is Script {
return string(res); return string(res);
} }
/// @dev Pulls the `_initialized` storage slot information from the Forge artifacts for a given contract.
function getInitializedSlot(string memory _contractName) internal returns (StorageSlot memory slot_) {
string memory storageLayout = getStorageLayout(_contractName);
string[] memory command = new string[](3);
command[0] = Executables.bash;
command[1] = "-c";
command[2] = string.concat(
Executables.echo,
" '",
storageLayout,
"'",
" | ",
Executables.jq,
" '.storage[] | select(.label == \"_initialized\" and .type == \"t_uint8\")'"
);
bytes memory rawSlot = vm.parseJson(string(vm.ffi(command)));
slot_ = abi.decode(rawSlot, (StorageSlot));
}
/// @notice Adds a deployment to the temp deployments file /// @notice Adds a deployment to the temp deployments file
function _writeTemp(string memory _name, address _deployed) internal { function _writeTemp(string memory _name, address _deployed) internal {
vm.writeJson({ json: stdJson.serialize("", _name, _deployed), path: tempDeploymentsPath }); vm.writeJson({ json: stdJson.serialize("", _name, _deployed), path: tempDeploymentsPath });
......
...@@ -9,6 +9,7 @@ import { SystemConfig } from "src/L1/SystemConfig.sol"; ...@@ -9,6 +9,7 @@ import { SystemConfig } from "src/L1/SystemConfig.sol";
import { ResourceMetering } from "src/L1/ResourceMetering.sol"; import { ResourceMetering } from "src/L1/ResourceMetering.sol";
import { OptimismPortal } from "src/L1/OptimismPortal.sol"; import { OptimismPortal } from "src/L1/OptimismPortal.sol";
import "src/L1/ProtocolVersions.sol"; import "src/L1/ProtocolVersions.sol";
import "scripts/Deployer.sol";
/// @title Initializer_Test /// @title Initializer_Test
/// @dev Ensures that the `initialize()` function on contracts cannot be called more than /// @dev Ensures that the `initialize()` function on contracts cannot be called more than
...@@ -23,17 +24,6 @@ contract Initializer_Test is Bridge_Initializer { ...@@ -23,17 +24,6 @@ contract Initializer_Test is Bridge_Initializer {
StorageSlot initializedSlot; StorageSlot initializedSlot;
} }
/// @notice Contains information about a storage slot. Mirrors the layout of the storage
/// slot object in Forge artifacts so that we can deserialize JSON into this struct.
struct StorageSlot {
uint256 astId;
string _contract;
string label;
uint256 offset;
string slot;
string _type;
}
/// @notice Contains the addresses of the contracts to test as well as the calldata /// @notice Contains the addresses of the contracts to test as well as the calldata
/// used to initialize them. /// used to initialize them.
InitializeableContract[] contracts; InitializeableContract[] contracts;
...@@ -50,7 +40,7 @@ contract Initializer_Test is Bridge_Initializer { ...@@ -50,7 +40,7 @@ contract Initializer_Test is Bridge_Initializer {
InitializeableContract({ InitializeableContract({
target: address(l1CrossDomainMessenger), target: address(l1CrossDomainMessenger),
initCalldata: abi.encodeCall(l1CrossDomainMessenger.initialize, ()), initCalldata: abi.encodeCall(l1CrossDomainMessenger.initialize, ()),
initializedSlot: _getInitializedSlot("L1CrossDomainMessenger") initializedSlot: getInitializedSlot("L1CrossDomainMessenger")
}) })
); );
// L2OutputOracle // L2OutputOracle
...@@ -58,7 +48,7 @@ contract Initializer_Test is Bridge_Initializer { ...@@ -58,7 +48,7 @@ contract Initializer_Test is Bridge_Initializer {
InitializeableContract({ InitializeableContract({
target: address(l2OutputOracle), target: address(l2OutputOracle),
initCalldata: abi.encodeCall(l2OutputOracle.initialize, (0, 0)), initCalldata: abi.encodeCall(l2OutputOracle.initialize, (0, 0)),
initializedSlot: _getInitializedSlot("L2OutputOracle") initializedSlot: getInitializedSlot("L2OutputOracle")
}) })
); );
// OptimismPortal // OptimismPortal
...@@ -66,7 +56,7 @@ contract Initializer_Test is Bridge_Initializer { ...@@ -66,7 +56,7 @@ contract Initializer_Test is Bridge_Initializer {
InitializeableContract({ InitializeableContract({
target: address(optimismPortal), target: address(optimismPortal),
initCalldata: abi.encodeCall(optimismPortal.initialize, (false)), initCalldata: abi.encodeCall(optimismPortal.initialize, (false)),
initializedSlot: _getInitializedSlot("OptimismPortal") initializedSlot: getInitializedSlot("OptimismPortal")
}) })
); );
// SystemConfig // SystemConfig
...@@ -92,7 +82,7 @@ contract Initializer_Test is Bridge_Initializer { ...@@ -92,7 +82,7 @@ contract Initializer_Test is Bridge_Initializer {
}) })
) )
), ),
initializedSlot: _getInitializedSlot("SystemConfig") initializedSlot: getInitializedSlot("SystemConfig")
}) })
); );
// ProtocolVersions // ProtocolVersions
...@@ -102,7 +92,7 @@ contract Initializer_Test is Bridge_Initializer { ...@@ -102,7 +92,7 @@ contract Initializer_Test is Bridge_Initializer {
initCalldata: abi.encodeCall( initCalldata: abi.encodeCall(
protocolVersions.initialize, (address(0), ProtocolVersion.wrap(1), ProtocolVersion.wrap(2)) protocolVersions.initialize, (address(0), ProtocolVersion.wrap(1), ProtocolVersion.wrap(2))
), ),
initializedSlot: _getInitializedSlot("ProtocolVersions") initializedSlot: getInitializedSlot("ProtocolVersions")
}) })
); );
} }
...@@ -137,26 +127,6 @@ contract Initializer_Test is Bridge_Initializer { ...@@ -137,26 +127,6 @@ contract Initializer_Test is Bridge_Initializer {
} }
} }
/// @dev Pulls the `_initialized` storage slot information from the Forge artifacts for a given contract.
function _getInitializedSlot(string memory _contractName) internal returns (StorageSlot memory slot_) {
string memory storageLayout = getStorageLayout(_contractName);
string[] memory command = new string[](3);
command[0] = Executables.bash;
command[1] = "-c";
command[2] = string.concat(
Executables.echo,
" '",
storageLayout,
"'",
" | ",
Executables.jq,
" '.storage[] | select(.label == \"_initialized\" and .type == \"t_uint8\")'"
);
bytes memory rawSlot = vm.parseJson(string(vm.ffi(command)));
slot_ = abi.decode(rawSlot, (StorageSlot));
}
/// @dev Returns the number of contracts that are `Initializable` in `src/L1`. /// @dev Returns the number of contracts that are `Initializable` in `src/L1`.
function _getNumL1Initializable() internal returns (uint256 numContracts_) { function _getNumL1Initializable() internal returns (uint256 numContracts_) {
string[] memory command = new string[](3); string[] memory command = new string[](3);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment