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

contracts-bedrock: refactor Initializable.t.sol (#8911)

* contracts-bedrock: update Deployer's loadInitializedSlot

if contract is a proxy, it now gets the implementation address using either EIP1967Helper or AddressManager (for ResolvedDelegateProxy)

* contracts-bedrock: drop isProxy argument of loadInitializedSlot

* contracts-bedrock: improve logic in loadInitializedSlot

* contracts-bedrock: add tests in Initializable.t.sol for L1 implementations

* contracts-bedrock: update logic in Initializable.t.sol to count implementations in assertion

* forge install: solady

v0.0.158

* contracts-bedrock: add solady to foundry.toml remappings

* contracts-bedrock: drop vendor of solady sort

* contracts-bedrock: use solady LibString in loadInitializedSlot

* contracts-bedrock: define constants in EIP1967Helper and drop Constants import

this allows us to not have to update the version of Arithmetic, ResourceMetering, and Burn, which would otherwise clash with Deployer.sol

* contracts-bedrock: use interface for AddressManager instead of updating version directly

* contracts-bedrock: use native solidity concat in loadInitializedSlot

* op-bindings: make for MIP, PreimageOracle, and WETH9
parent a779009b
......@@ -17,3 +17,6 @@
path = packages/contracts-bedrock/lib/safe-contracts
url = https://github.com/safe-global/safe-contracts
branch = v1.4.0
[submodule "packages/contracts-bedrock/lib/solady"]
path = packages/contracts-bedrock/lib/solady
url = https://github.com/Vectorized/solady
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -13,7 +13,7 @@ const WETH9StorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src
var WETH9StorageLayout = new(solc.StorageLayout)
var WETH9DeployedBin = "0x6080604052600436106100bc5760003560e01c8063313ce56711610074578063a9059cbb1161004e578063a9059cbb146102cb578063d0e30db0146100bc578063dd62ed3e14610311576100bc565b8063313ce5671461024b57806370a082311461027657806395d89b41146102b6576100bc565b806318160ddd116100a557806318160ddd146101aa57806323b872dd146101d15780632e1a7d4d14610221576100bc565b806306fdde03146100c6578063095ea7b314610150575b6100c4610359565b005b3480156100d257600080fd5b506100db6103a8565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101155781810151838201526020016100fd565b50505050905090810190601f1680156101425780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015c57600080fd5b506101966004803603604081101561017357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610454565b604080519115158252519081900360200190f35b3480156101b657600080fd5b506101bf6104c7565b60408051918252519081900360200190f35b3480156101dd57600080fd5b50610196600480360360608110156101f457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013590911690604001356104cb565b34801561022d57600080fd5b506100c46004803603602081101561024457600080fd5b503561066b565b34801561025757600080fd5b50610260610700565b6040805160ff9092168252519081900360200190f35b34801561028257600080fd5b506101bf6004803603602081101561029957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610709565b3480156102c257600080fd5b506100db61071b565b3480156102d757600080fd5b50610196600480360360408110156102ee57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610793565b34801561031d57600080fd5b506101bf6004803603604081101561033457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166107a7565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b820191906000526020600020905b81548152906001019060200180831161042f57829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120548211156104fd57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610573575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156105ed5773ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020548211156105b557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020805483900390555b73ffffffffffffffffffffffffffffffffffffffff808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561068757600080fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106c6573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b60006107a03384846104cb565b9392505050565b60046020908152600092835260408084209091529082529020548156fea265627a7a723158203b5b5adf37f507cc9ca5ac0b72acf7873b794171cc0eeb888a5f850e69fe540d64736f6c63430005110032"
var WETH9DeployedBin = "0x6080604052600436106100bc5760003560e01c8063313ce56711610074578063a9059cbb1161004e578063a9059cbb146102cb578063d0e30db0146100bc578063dd62ed3e14610311576100bc565b8063313ce5671461024b57806370a082311461027657806395d89b41146102b6576100bc565b806318160ddd116100a557806318160ddd146101aa57806323b872dd146101d15780632e1a7d4d14610221576100bc565b806306fdde03146100c6578063095ea7b314610150575b6100c4610359565b005b3480156100d257600080fd5b506100db6103a8565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101155781810151838201526020016100fd565b50505050905090810190601f1680156101425780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015c57600080fd5b506101966004803603604081101561017357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610454565b604080519115158252519081900360200190f35b3480156101b657600080fd5b506101bf6104c7565b60408051918252519081900360200190f35b3480156101dd57600080fd5b50610196600480360360608110156101f457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013590911690604001356104cb565b34801561022d57600080fd5b506100c46004803603602081101561024457600080fd5b503561066b565b34801561025757600080fd5b50610260610700565b6040805160ff9092168252519081900360200190f35b34801561028257600080fd5b506101bf6004803603602081101561029957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610709565b3480156102c257600080fd5b506100db61071b565b3480156102d757600080fd5b50610196600480360360408110156102ee57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610793565b34801561031d57600080fd5b506101bf6004803603604081101561033457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166107a7565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b820191906000526020600020905b81548152906001019060200180831161042f57829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120548211156104fd57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610573575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156105ed5773ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020548211156105b557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020805483900390555b73ffffffffffffffffffffffffffffffffffffffff808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561068757600080fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106c6573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b60006107a03384846104cb565b9392505050565b60046020908152600092835260408084209091529082529020548156fea265627a7a72315820815b4d576ed6382f69c32a261321b184a7fbc2b81b87c3a52e66efdb3ee9602164736f6c63430005110032"
func init() {
......
......@@ -17,7 +17,8 @@ remappings = [
'@cwia/=lib/clones-with-immutable-args/src',
'forge-std/=lib/forge-std/src',
'ds-test/=lib/forge-std/lib/ds-test/src',
'safe-contracts/=lib/safe-contracts/contracts'
'safe-contracts/=lib/safe-contracts/contracts',
'solady/=lib/solady/src',
]
extra_output = ['devdoc', 'userdoc', 'metadata', 'storageLayout']
bytecode_hash = 'none'
......
Subproject commit 502cc1ea718e6fa73b380635ee0868b0740595f0
......@@ -474,7 +474,7 @@ contract Deploy is Deployer {
contracts.L1CrossDomainMessenger = address(messenger);
ChainAssertions.checkL1CrossDomainMessenger({ _contracts: contracts, _vm: vm, _isProxy: false });
require(loadInitializedSlot("L1CrossDomainMessenger", false) == 1, "L1CrossDomainMessenger is not initialized");
require(loadInitializedSlot("L1CrossDomainMessenger") == 1, "L1CrossDomainMessenger is not initialized");
addr_ = address(messenger);
}
......@@ -499,7 +499,7 @@ contract Deploy is Deployer {
contracts.OptimismPortal = address(portal);
ChainAssertions.checkOptimismPortal({ _contracts: contracts, _cfg: cfg, _isProxy: false });
require(loadInitializedSlot("OptimismPortal", false) == 1, "OptimismPortal is not initialized");
require(loadInitializedSlot("OptimismPortal") == 1, "OptimismPortal is not initialized");
addr_ = address(portal);
}
......@@ -527,7 +527,7 @@ contract Deploy is Deployer {
contracts.L2OutputOracle = address(oracle);
ChainAssertions.checkL2OutputOracle(contracts, cfg, 0, 0);
require(loadInitializedSlot("L2OutputOracle", false) == 1, "L2OutputOracle is not initialized");
require(loadInitializedSlot("L2OutputOracle") == 1, "L2OutputOracle is not initialized");
addr_ = address(oracle);
}
......@@ -576,7 +576,7 @@ contract Deploy is Deployer {
contracts.ProtocolVersions = address(versions);
ChainAssertions.checkProtocolVersions({ _contracts: contracts, _cfg: cfg, _isProxy: false });
require(loadInitializedSlot("ProtocolVersions", false) == 1, "ProtocolVersions is not initialized");
require(loadInitializedSlot("ProtocolVersions") == 1, "ProtocolVersions is not initialized");
addr_ = address(versions);
}
......@@ -626,7 +626,7 @@ contract Deploy is Deployer {
contracts.SystemConfig = address(config);
ChainAssertions.checkSystemConfig({ _contracts: contracts, _cfg: cfg, _isProxy: false });
require(loadInitializedSlot("SystemConfig", false) == 1, "SystemConfig is not initialized");
require(loadInitializedSlot("SystemConfig") == 1, "SystemConfig is not initialized");
addr_ = address(config);
}
......@@ -750,7 +750,7 @@ contract Deploy is Deployer {
ChainAssertions.checkSystemConfig({ _contracts: _proxies(), _cfg: cfg, _isProxy: true });
require(loadInitializedSlot("SystemConfig", true) == 1, "SystemConfigProxy is not initialized");
require(loadInitializedSlot("SystemConfigProxy") == 1, "SystemConfigProxy is not initialized");
}
/// @notice Initialize the L1StandardBridge
......@@ -866,7 +866,7 @@ contract Deploy is Deployer {
ChainAssertions.checkL1CrossDomainMessenger({ _contracts: _proxies(), _vm: vm, _isProxy: true });
require(
loadInitializedSlot("L1CrossDomainMessenger", true) == 1, "L1CrossDomainMessengerProxy is not initialized"
loadInitializedSlot("L1CrossDomainMessengerProxy") == 1, "L1CrossDomainMessengerProxy is not initialized"
);
}
......@@ -895,7 +895,7 @@ contract Deploy is Deployer {
_l2OutputOracleStartingTimestamp: cfg.l2OutputOracleStartingTimestamp()
});
require(loadInitializedSlot("L2OutputOracle", true) == 1, "L2OutputOracleProxy is not initialized");
require(loadInitializedSlot("L2OutputOracleProxy") == 1, "L2OutputOracleProxy is not initialized");
}
/// @notice Initialize the OptimismPortal
......@@ -917,7 +917,7 @@ contract Deploy is Deployer {
ChainAssertions.checkOptimismPortal({ _contracts: _proxies(), _cfg: cfg, _isProxy: true });
require(loadInitializedSlot("OptimismPortal", true) == 1, "OptimismPortalProxy is not initialized");
require(loadInitializedSlot("OptimismPortalProxy") == 1, "OptimismPortalProxy is not initialized");
}
function initializeProtocolVersions() public broadcast {
......@@ -948,7 +948,7 @@ contract Deploy is Deployer {
ChainAssertions.checkProtocolVersions({ _contracts: _proxiesUnstrict(), _cfg: cfg, _isProxy: true });
require(loadInitializedSlot("ProtocolVersions", true) == 1, "ProtocolVersionsProxy is not initialized");
require(loadInitializedSlot("ProtocolVersionsProxy") == 1, "ProtocolVersionsProxy is not initialized");
}
/// @notice Transfer ownership of the DisputeGameFactory contract to the final system owner
......
......@@ -7,6 +7,9 @@ import { console2 as console } from "forge-std/console2.sol";
import { Executables } from "scripts/Executables.sol";
import { Chains } from "scripts/Chains.sol";
import { Predeploys } from "src/libraries/Predeploys.sol";
import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol";
import { IAddressManager } from "scripts/interfaces/IAddressManager.sol";
import { LibString } from "solady/utils/LibString.sol";
/// @notice store the new deployment to be saved
struct Deployment {
......@@ -573,12 +576,23 @@ abstract contract Deployer is Script {
}
/// @dev Returns the value of the internal `_initialized` storage slot for a given contract.
function loadInitializedSlot(string memory _contractName, bool _isProxy) public returns (uint8 initialized_) {
StorageSlot memory slot = getInitializedSlot(_contractName);
if (_isProxy) {
_contractName = string.concat(_contractName, "Proxy");
function loadInitializedSlot(string memory _contractName) public returns (uint8 initialized_) {
address contractAddress;
// Check if the contract name ends with `Proxy` and, if so, get the implementation address
if (LibString.endsWith(_contractName, "Proxy")) {
contractAddress = EIP1967Helper.getImplementation(getAddress(_contractName));
_contractName = LibString.slice(_contractName, 0, bytes(_contractName).length - 5);
// If the EIP1967 implementation address is 0, we try to get the implementation address from legacy
// AddressManager, which would work if the proxy is ResolvedDelegateProxy like L1CrossDomainMessengerProxy.
if (contractAddress == address(0)) {
contractAddress =
IAddressManager(mustGetAddress("AddressManager")).getAddress(string.concat("OVM_", _contractName));
}
} else {
contractAddress = mustGetAddress(_contractName);
}
bytes32 slotVal = vm.load(mustGetAddress(_contractName), bytes32(vm.parseUint(slot.slot)));
StorageSlot memory slot = getInitializedSlot(_contractName);
bytes32 slotVal = vm.load(contractAddress, bytes32(vm.parseUint(slot.slot)));
initialized_ = uint8((uint256(slotVal) >> (slot.offset * 8)) & 0xFF);
}
......
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
/// @title IAddressManager
/// @notice Minimal interface of the Legacy AddressManager.
interface IAddressManager {
/// @notice Emitted when an address is modified in the registry.
/// @param name String name being set in the registry.
/// @param newAddress Address set for the given name.
/// @param oldAddress Address that was previously set for the given name.
event AddressSet(string indexed name, address newAddress, address oldAddress);
/// @notice Changes the address associated with a particular name.
/// @param _name String name to associate an address with.
/// @param _address Address to associate with the name.
function setAddress(string memory _name, address _address) external;
/// @notice Retrieves the address associated with a given name.
/// @param _name Name to retrieve an address for.
/// @return Address associated with the given name.
function getAddress(string memory _name) external view returns (address);
}
......@@ -4,7 +4,7 @@ pragma solidity 0.8.15;
import { console } from "forge-std/console.sol";
import { IMulticall3 } from "forge-std/interfaces/IMulticall3.sol";
import { LibSort } from "../libraries/LibSort.sol";
import { LibSort } from "solady/utils/LibSort.sol";
import { IGnosisSafe, Enum } from "../interfaces/IGnosisSafe.sol";
import { EnhancedScript } from "../universal/EnhancedScript.sol";
import { GlobalConstants } from "../universal/GlobalConstants.sol";
......
......@@ -2,18 +2,26 @@
pragma solidity ^0.8.0;
import { Vm } from "forge-std/Vm.sol";
import { Constants } from "src/libraries/Constants.sol";
/// @title EIP1967Helper
/// @dev Testing library to help with reading EIP 1967 variables from state
library EIP1967Helper {
/// @notice The storage slot that holds the address of a proxy implementation.
/// @dev `bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)`
bytes32 internal constant PROXY_IMPLEMENTATION_ADDRESS =
0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
/// @notice The storage slot that holds the address of the owner.
/// @dev `bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)`
bytes32 internal constant PROXY_OWNER_ADDRESS = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
Vm internal constant vm = Vm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);
function getAdmin(address _proxy) internal view returns (address) {
return address(uint160(uint256(vm.load(address(_proxy), Constants.PROXY_OWNER_ADDRESS))));
return address(uint160(uint256(vm.load(address(_proxy), PROXY_OWNER_ADDRESS))));
}
function getImplementation(address _proxy) internal view returns (address) {
return address(uint160(uint256(vm.load(address(_proxy), Constants.PROXY_IMPLEMENTATION_ADDRESS))));
return address(uint160(uint256(vm.load(address(_proxy), PROXY_IMPLEMENTATION_ADDRESS))));
}
}
......@@ -2,7 +2,7 @@
pragma solidity >=0.7.0 <0.9.0;
import "forge-std/Test.sol";
import "scripts/libraries/LibSort.sol";
import { LibSort } from "solady/utils/LibSort.sol";
import { Safe as GnosisSafe, OwnerManager, ModuleManager, GuardManager } from "safe-contracts/Safe.sol";
import { SafeProxyFactory as GnosisSafeProxyFactory } from "safe-contracts/proxies/SafeProxyFactory.sol";
import { Enum } from "safe-contracts/common/Enum.sol";
......
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