Commit b0f845c2 authored by Diego's avatar Diego Committed by GitHub

contracts-bedrock: add initialized var checks in ChainAssertions (#9276)

* contracts-bedrock: check initialized value in ChainAssertions

* contracts-bedrock: check initialized value in ChainAssertions

* contracts-bedrock: update Deploy script to pass vm in ChainAssertions calls

* contracts-bedrock: create assertSlotIsOne in ChainAssertions

* contracts-bedrock: replace initialized check logic by assertSlotIsOne in ChainAssertions

* contracts-bedrock: drop unnecessary _vm argument in ChainAssertions functions

* contracts-bedrock: drop redundant loadInitializedSlot in Deploy.s.sol

* contracts-bedrock: reintroduce call to checkOptimismPortal2 in ChainAssertions

* contracts-bedrock: improve error log for assertSlotIsOne in ChainAssertions

* contracts-bedrock: prepended with an underscore inputs to assertSlotIsOne in ChainAssertions

* contracts-bedrock: relabel assertSlotIsOne to assertSlotValueIsOne in ChainAssertions

* contracts-bedrock: update snapshots

* contracts-bedrock: fix error log for assertSlotValueIsOne in ChainAssertions

* contracts-bedrock: improve error string for assertSlotValueIsOne in ChainAssertions
parent 0c618389
......@@ -23,6 +23,8 @@ import { ISystemConfigV0 } from "scripts/interfaces/ISystemConfigV0.sol";
import { console2 as console } from "forge-std/console2.sol";
library ChainAssertions {
Vm internal constant vm = Vm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);
/// @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(
......@@ -60,6 +62,9 @@ library ChainAssertions {
console.log("Running chain assertions on the SystemConfig");
SystemConfig config = SystemConfig(_contracts.SystemConfig);
// Check that the contract is initialized
assertSlotValueIsOne({ _contractAddress: address(config), _slot: 0, _offset: 0 });
ResourceMetering.ResourceConfig memory resourceConfig = config.resourceConfig();
if (_isProxy) {
......@@ -119,6 +124,9 @@ library ChainAssertions {
console.log("Running chain assertions on the L1CrossDomainMessenger");
L1CrossDomainMessenger messenger = L1CrossDomainMessenger(_contracts.L1CrossDomainMessenger);
// Check that the contract is initialized
assertSlotValueIsOne({ _contractAddress: address(messenger), _slot: 0, _offset: 20 });
require(address(messenger.OTHER_MESSENGER()) == Predeploys.L2_CROSS_DOMAIN_MESSENGER);
require(address(messenger.otherMessenger()) == Predeploys.L2_CROSS_DOMAIN_MESSENGER);
......@@ -140,6 +148,9 @@ library ChainAssertions {
console.log("Running chain assertions on the L1StandardBridge");
L1StandardBridge bridge = L1StandardBridge(payable(_contracts.L1StandardBridge));
// Check that the contract is initialized
assertSlotValueIsOne({ _contractAddress: address(bridge), _slot: 0, _offset: 0 });
if (_isProxy) {
require(address(bridge.MESSENGER()) == _contracts.L1CrossDomainMessenger);
require(address(bridge.messenger()) == _contracts.L1CrossDomainMessenger);
......@@ -168,6 +179,9 @@ library ChainAssertions {
console.log("Running chain assertions on the L2OutputOracle");
L2OutputOracle oracle = L2OutputOracle(_contracts.L2OutputOracle);
// Check that the contract is initialized
assertSlotValueIsOne({ _contractAddress: address(oracle), _slot: 0, _offset: 0 });
if (_isProxy) {
require(oracle.SUBMISSION_INTERVAL() == _cfg.l2OutputOracleSubmissionInterval());
require(oracle.submissionInterval() == _cfg.l2OutputOracleSubmissionInterval());
......@@ -202,6 +216,9 @@ library ChainAssertions {
console.log("Running chain assertions on the OptimismMintableERC20Factory");
OptimismMintableERC20Factory factory = OptimismMintableERC20Factory(_contracts.OptimismMintableERC20Factory);
// Check that the contract is initialized
assertSlotValueIsOne({ _contractAddress: address(factory), _slot: 0, _offset: 0 });
if (_isProxy) {
require(factory.BRIDGE() == _contracts.L1StandardBridge);
require(factory.bridge() == _contracts.L1StandardBridge);
......@@ -216,6 +233,9 @@ library ChainAssertions {
console.log("Running chain assertions on the L1ERC721Bridge");
L1ERC721Bridge bridge = L1ERC721Bridge(_contracts.L1ERC721Bridge);
// Check that the contract is initialized
assertSlotValueIsOne({ _contractAddress: address(bridge), _slot: 0, _offset: 0 });
require(address(bridge.OTHER_BRIDGE()) == Predeploys.L2_ERC721_BRIDGE);
require(address(bridge.otherBridge()) == Predeploys.L2_ERC721_BRIDGE);
......@@ -236,6 +256,9 @@ library ChainAssertions {
OptimismPortal portal = OptimismPortal(payable(_contracts.OptimismPortal));
// Check that the contract is initialized
assertSlotValueIsOne({ _contractAddress: address(portal), _slot: 0, _offset: 0 });
address guardian = _cfg.superchainConfigGuardian();
if (guardian.code.length == 0) {
console.log("Guardian has no code: %s", guardian);
......@@ -274,6 +297,9 @@ library ChainAssertions {
OptimismPortal2 portal = OptimismPortal2(payable(_contracts.OptimismPortal2));
// Check that the contract is initialized
assertSlotValueIsOne({ _contractAddress: address(portal), _slot: 0, _offset: 0 });
address guardian = _cfg.superchainConfigGuardian();
if (guardian.code.length == 0) {
console.log("Guardian has no code: %s", guardian);
......@@ -308,6 +334,10 @@ library ChainAssertions {
{
console.log("Running chain assertions on the ProtocolVersions");
ProtocolVersions versions = ProtocolVersions(_contracts.ProtocolVersions);
// Check that the contract is initialized
assertSlotValueIsOne({ _contractAddress: address(versions), _slot: 0, _offset: 0 });
if (_isProxy) {
require(versions.owner() == _cfg.finalSystemOwner());
require(ProtocolVersion.unwrap(versions.required()) == _cfg.requiredProtocolVersion());
......@@ -330,7 +360,20 @@ library ChainAssertions {
{
console.log("Running chain assertions on the SuperchainConfig");
SuperchainConfig superchainConfig = SuperchainConfig(_contracts.SuperchainConfig);
// Check that the contract is initialized
assertSlotValueIsOne({ _contractAddress: address(superchainConfig), _slot: 0, _offset: 0 });
require(superchainConfig.guardian() == _cfg.superchainConfigGuardian());
require(superchainConfig.paused() == _isPaused);
}
/// @dev Asserts that for a given contract the value of a storage slot at an offset is 1.
function assertSlotValueIsOne(address _contractAddress, uint256 _slot, uint256 _offset) internal view {
bytes32 slotVal = vm.load(_contractAddress, bytes32(_slot));
require(
uint8((uint256(slotVal) >> (_offset * 8)) & 0xFF) == uint8(1),
"Storage value is not 1 at the given slot and offset"
);
}
}
......@@ -542,8 +542,6 @@ contract Deploy is Deployer {
contracts.L1CrossDomainMessenger = address(messenger);
ChainAssertions.checkL1CrossDomainMessenger({ _contracts: contracts, _vm: vm, _isProxy: false });
require(loadInitializedSlot("L1CrossDomainMessenger") == 1, "L1CrossDomainMessenger is not initialized");
addr_ = address(messenger);
}
......@@ -563,8 +561,6 @@ contract Deploy is Deployer {
contracts.OptimismPortal = address(portal);
ChainAssertions.checkOptimismPortal({ _contracts: contracts, _cfg: cfg, _isProxy: false });
require(loadInitializedSlot("OptimismPortal") == 1, "OptimismPortal is not initialized");
addr_ = address(portal);
}
......@@ -593,8 +589,6 @@ contract Deploy is Deployer {
contracts.OptimismPortal2 = address(portal);
ChainAssertions.checkOptimismPortal2({ _contracts: contracts, _cfg: cfg, _isProxy: false });
require(loadInitializedSlot("OptimismPortal2") == 1, "OptimismPortal2 is not initialized");
addr_ = address(portal);
}
......@@ -618,8 +612,6 @@ contract Deploy is Deployer {
_isProxy: false
});
require(loadInitializedSlot("L2OutputOracle") == 1, "L2OutputOracle is not initialized");
addr_ = address(oracle);
}
......@@ -667,8 +659,6 @@ contract Deploy is Deployer {
contracts.ProtocolVersions = address(versions);
ChainAssertions.checkProtocolVersions({ _contracts: contracts, _cfg: cfg, _isProxy: false });
require(loadInitializedSlot("ProtocolVersions") == 1, "ProtocolVersions is not initialized");
addr_ = address(versions);
}
......@@ -711,8 +701,6 @@ contract Deploy is Deployer {
contracts.SystemConfig = address(config);
ChainAssertions.checkSystemConfig({ _contracts: contracts, _cfg: cfg, _isProxy: false });
require(loadInitializedSlot("SystemConfig") == 1, "SystemConfig is not initialized");
addr_ = address(config);
}
......@@ -842,8 +830,6 @@ contract Deploy is Deployer {
console.log("SystemConfig version: %s", version);
ChainAssertions.checkSystemConfig({ _contracts: _proxies(), _cfg: cfg, _isProxy: true });
require(loadInitializedSlot("SystemConfigProxy") == 1, "SystemConfigProxy is not initialized");
}
/// @notice Initialize the L1StandardBridge
......@@ -968,10 +954,6 @@ contract Deploy is Deployer {
console.log("L1CrossDomainMessenger version: %s", version);
ChainAssertions.checkL1CrossDomainMessenger({ _contracts: _proxies(), _vm: vm, _isProxy: true });
require(
loadInitializedSlot("L1CrossDomainMessengerProxy") == 1, "L1CrossDomainMessengerProxy is not initialized"
);
}
/// @notice Initialize the L2OutputOracle
......@@ -1007,8 +989,6 @@ contract Deploy is Deployer {
_l2OutputOracleStartingTimestamp: cfg.l2OutputOracleStartingTimestamp(),
_isProxy: true
});
require(loadInitializedSlot("L2OutputOracleProxy") == 1, "L2OutputOracleProxy is not initialized");
}
/// @notice Initialize the OptimismPortal
......@@ -1038,8 +1018,6 @@ contract Deploy is Deployer {
console.log("OptimismPortal version: %s", version);
ChainAssertions.checkOptimismPortal({ _contracts: _proxies(), _cfg: cfg, _isProxy: true });
require(loadInitializedSlot("OptimismPortalProxy") == 1, "OptimismPortalProxy is not initialized");
}
/// @notice Initialize the OptimismPortal2
......@@ -1069,8 +1047,6 @@ contract Deploy is Deployer {
console.log("OptimismPortal2 version: %s", version);
ChainAssertions.checkOptimismPortal2({ _contracts: _proxies(), _cfg: cfg, _isProxy: true });
require(loadInitializedSlot("OptimismPortalProxy") == 1, "OptimismPortalProxy is not initialized");
}
function initializeProtocolVersions() public broadcast {
......@@ -1100,8 +1076,6 @@ contract Deploy is Deployer {
console.log("ProtocolVersions version: %s", version);
ChainAssertions.checkProtocolVersions({ _contracts: _proxiesUnstrict(), _cfg: cfg, _isProxy: true });
require(loadInitializedSlot("ProtocolVersionsProxy") == 1, "ProtocolVersionsProxy is not initialized");
}
/// @notice Transfer ownership of the DisputeGameFactory contract to the final system owner
......
......@@ -10880,32 +10880,6 @@
],
"value": 0
},
{
"accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38",
"account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3",
"chainInfo": {
"chainId": 31337,
"forkId": 0
},
"data": "0xbf40fac10000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001a4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000",
"deployedCode": "0x",
"initialized": true,
"kind": "StaticCall",
"newBalance": 0,
"oldBalance": 0,
"reverted": false,
"storageAccesses": [
{
"account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3",
"isWrite": false,
"newValue": "0x00000000000000000000000071fa82ea96672797954c28032b337aa40aafc99f",
"previousValue": "0x00000000000000000000000071fa82ea96672797954c28032b337aa40aafc99f",
"reverted": false,
"slot": "0x515216935740e67dfdda5cf8e248ea32b3277787818ab59153061ac875c9385e"
}
],
"value": 0
},
{
"accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496",
"account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D",
......
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