Commit 70cb6d94 authored by Mark Tyneway's avatar Mark Tyneway

contracts-bedrock: fix compile time

Reduces the compile time to about 80s on my machine. The compile time
was greatly increased as part of the migration to using the deploy
script to set up the tests. Can we have our cake and eat it to? This
commit seems to say yes.

The call to `broadcast` now needs to include `msg.sender` because the
contract doing all of the deployments is no longer the top level
contract. This assumes that the deploy contract is not nested deeper
than the 2nd callframe. The deployments would fail if that was not the
case.

The `cfg` now is behind a public getter on the deploy script, so the
majority of the commit is updating places where the deploy config is
referenced to change it into calls.
parent bbf2c5b7
......@@ -53,7 +53,7 @@ import { Types } from "scripts/Types.sol";
/// Then add a call to that function inside of `run`. Be sure to call the `save` function after each
/// deployment so that hardhat-deploy style artifacts can be generated using a call to `sync()`.
contract Deploy is Deployer {
DeployConfig cfg;
DeployConfig public cfg;
////////////////////////////////////////////////////////////////
// Modifiers //
......@@ -61,7 +61,7 @@ contract Deploy is Deployer {
/// @notice Modifier that wraps a function in broadcasting.
modifier broadcast() {
vm.startBroadcast();
vm.startBroadcast(msg.sender);
_;
vm.stopBroadcast();
}
......
......@@ -409,7 +409,7 @@ abstract contract Deployer is Script {
}
/// @notice Returns the abi for a deployed contract.
function getAbi(string memory _name) internal returns (string memory) {
function getAbi(string memory _name) public returns (string memory) {
string[] memory cmd = new string[](3);
cmd[0] = Executables.bash;
cmd[1] = "-c";
......@@ -459,7 +459,7 @@ 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) internal returns (uint8 initialized_) {
function loadInitializedSlot(string memory _contractName, bool _isProxy) public returns (uint8 initialized_) {
StorageSlot memory slot = getInitializedSlot(_contractName);
if (_isProxy) {
_contractName = string.concat(_contractName, "Proxy");
......
......@@ -201,7 +201,7 @@ contract GasBenchMark_L2OutputOracle is CommonTest {
super.setUp();
nextBlockNumber = l2OutputOracle.nextBlockNumber();
warpToProposeTime(nextBlockNumber);
address proposer = cfg.l2OutputOracleProposer();
address proposer = deploy.cfg().l2OutputOracleProposer();
vm.startPrank(proposer);
}
......
......@@ -11,15 +11,15 @@ import { FeeVault } from "src/universal/FeeVault.sol";
contract FeeVault_Test is Bridge_Initializer {
/// @dev Tests that the constructor sets the correct values.
function test_constructor_l1FeeVault_succeeds() external {
assertEq(l1FeeVault.RECIPIENT(), cfg.l1FeeVaultRecipient());
assertEq(l1FeeVault.MIN_WITHDRAWAL_AMOUNT(), cfg.l1FeeVaultMinimumWithdrawalAmount());
assertEq(l1FeeVault.RECIPIENT(), deploy.cfg().l1FeeVaultRecipient());
assertEq(l1FeeVault.MIN_WITHDRAWAL_AMOUNT(), deploy.cfg().l1FeeVaultMinimumWithdrawalAmount());
assertEq(uint8(l1FeeVault.WITHDRAWAL_NETWORK()), uint8(FeeVault.WithdrawalNetwork.L1));
}
/// @dev Tests that the constructor sets the correct values.
function test_constructor_baseFeeVault_succeeds() external {
assertEq(baseFeeVault.RECIPIENT(), cfg.baseFeeVaultRecipient());
assertEq(baseFeeVault.MIN_WITHDRAWAL_AMOUNT(), cfg.baseFeeVaultMinimumWithdrawalAmount());
assertEq(baseFeeVault.RECIPIENT(), deploy.cfg().baseFeeVaultRecipient());
assertEq(baseFeeVault.MIN_WITHDRAWAL_AMOUNT(), deploy.cfg().baseFeeVaultMinimumWithdrawalAmount());
assertEq(uint8(baseFeeVault.WITHDRAWAL_NETWORK()), uint8(FeeVault.WithdrawalNetwork.L1));
}
}
......@@ -40,7 +40,7 @@ contract Initializer_Test is Bridge_Initializer {
InitializeableContract({
target: address(l1CrossDomainMessenger),
initCalldata: abi.encodeCall(l1CrossDomainMessenger.initialize, ()),
initializedSlotVal: loadInitializedSlot("L1CrossDomainMessenger", true)
initializedSlotVal: deploy.loadInitializedSlot("L1CrossDomainMessenger", true)
})
);
// L2OutputOracle
......@@ -48,7 +48,7 @@ contract Initializer_Test is Bridge_Initializer {
InitializeableContract({
target: address(l2OutputOracle),
initCalldata: abi.encodeCall(l2OutputOracle.initialize, (0, 0)),
initializedSlotVal: loadInitializedSlot("L2OutputOracle", true)
initializedSlotVal: deploy.loadInitializedSlot("L2OutputOracle", true)
})
);
// OptimismPortal
......@@ -56,7 +56,7 @@ contract Initializer_Test is Bridge_Initializer {
InitializeableContract({
target: address(optimismPortal),
initCalldata: abi.encodeCall(optimismPortal.initialize, (false)),
initializedSlotVal: loadInitializedSlot("OptimismPortal", true)
initializedSlotVal: deploy.loadInitializedSlot("OptimismPortal", true)
})
);
// SystemConfig
......@@ -82,7 +82,7 @@ contract Initializer_Test is Bridge_Initializer {
})
)
),
initializedSlotVal: loadInitializedSlot("SystemConfig", true)
initializedSlotVal: deploy.loadInitializedSlot("SystemConfig", true)
})
);
// ProtocolVersions
......@@ -92,7 +92,7 @@ contract Initializer_Test is Bridge_Initializer {
initCalldata: abi.encodeCall(
protocolVersions.initialize, (address(0), ProtocolVersion.wrap(1), ProtocolVersion.wrap(2))
),
initializedSlotVal: loadInitializedSlot("ProtocolVersions", true)
initializedSlotVal: deploy.loadInitializedSlot("ProtocolVersions", true)
})
);
}
......@@ -139,7 +139,7 @@ contract Initializer_Test is Bridge_Initializer {
for (uint256 i; i < contractNames.length; i++) {
string memory contractName = contractNames[i];
string memory contractAbi = getAbi(contractName);
string memory contractAbi = deploy.getAbi(contractName);
// Query the contract's ABI for an `initialize()` function.
command[2] = string.concat(
......
......@@ -33,7 +33,7 @@ contract OptimismPortal_Test is CommonTest {
/// @dev Tests that the constructor sets the correct values.
function test_constructor_succeeds() external {
address guardian = cfg.portalGuardian();
address guardian = deploy.cfg().portalGuardian();
assertEq(address(optimismPortal.L2_ORACLE()), address(l2OutputOracle));
assertEq(address(optimismPortal.l2Oracle()), address(l2OutputOracle));
assertEq(optimismPortal.GUARDIAN(), guardian);
......@@ -270,7 +270,7 @@ contract OptimismPortal_Test is CommonTest {
/// @dev Tests that `isOutputFinalized` succeeds for an EOA depositing a tx with ETH and data.
function test_simple_isOutputFinalized_succeeds() external {
uint256 startingBlockNumber = cfg.l2OutputOracleStartingBlockNumber();
uint256 startingBlockNumber = deploy.cfg().l2OutputOracleStartingBlockNumber();
uint256 ts = block.timestamp;
vm.mockCall(
......@@ -904,7 +904,7 @@ contract OptimismPortalUpgradeable_Test is CommonTest {
/// @dev Tests that the implementation cannot be initialized twice.
function test_initialize_cannotInitImpl_reverts() external {
address opImpl = mustGetAddress("OptimismPortal");
address opImpl = deploy.mustGetAddress("OptimismPortal");
vm.expectRevert("Initializable: contract is already initialized");
OptimismPortal(payable(opImpl)).initialize({ _paused: false });
}
......
......@@ -22,16 +22,16 @@ contract ProtocolVersions_Init is CommonTest {
function setUp() public virtual override {
super.setUp();
required = ProtocolVersion.wrap(cfg.requiredProtocolVersion());
recommended = ProtocolVersion.wrap(cfg.recommendedProtocolVersion());
required = ProtocolVersion.wrap(deploy.cfg().requiredProtocolVersion());
recommended = ProtocolVersion.wrap(deploy.cfg().recommendedProtocolVersion());
}
}
contract ProtocolVersions_Initialize_Test is ProtocolVersions_Init {
/// @dev Tests that initialization sets the correct values.
function test_initialize_values_succeeds() external {
ProtocolVersions protocolVersionsImpl = ProtocolVersions(mustGetAddress("ProtocolVersions"));
address owner = cfg.finalSystemOwner();
ProtocolVersions protocolVersionsImpl = ProtocolVersions(deploy.mustGetAddress("ProtocolVersions"));
address owner = deploy.cfg().finalSystemOwner();
assertEq(ProtocolVersion.unwrap(protocolVersions.required()), ProtocolVersion.unwrap(required));
assertEq(ProtocolVersion.unwrap(protocolVersions.recommended()), ProtocolVersion.unwrap(recommended));
......@@ -44,7 +44,7 @@ contract ProtocolVersions_Initialize_Test is ProtocolVersions_Init {
/// @dev Ensures that the events are emitted during initialization.
function test_initialize_events_succeeds() external {
ProtocolVersions protocolVersionsImpl = ProtocolVersions(mustGetAddress("ProtocolVersions"));
ProtocolVersions protocolVersionsImpl = ProtocolVersions(deploy.mustGetAddress("ProtocolVersions"));
assertEq(protocolVersionsImpl.owner(), address(0xdEad));
// Wipe out the initialized slot so the proxy can be initialized again
......
......@@ -22,12 +22,12 @@ contract SequencerFeeVault_Test is CommonTest {
/// @dev Sets up the test suite.
function setUp() public override {
super.setUp();
recipient = cfg.sequencerFeeVaultRecipient();
recipient = deploy.cfg().sequencerFeeVaultRecipient();
}
/// @dev Tests that the minimum withdrawal amount is correct.
function test_minWithdrawalAmount_succeeds() external {
assertEq(sequencerFeeVault.MIN_WITHDRAWAL_AMOUNT(), cfg.sequencerFeeVaultMinimumWithdrawalAmount());
assertEq(sequencerFeeVault.MIN_WITHDRAWAL_AMOUNT(), deploy.cfg().sequencerFeeVaultMinimumWithdrawalAmount());
}
/// @dev Tests that the l1 fee wallet is correct.
......@@ -103,11 +103,11 @@ contract SequencerFeeVault_L2Withdrawal_Test is CommonTest {
vm.etch(
EIP1967Helper.getImplementation(Predeploys.SEQUENCER_FEE_WALLET),
address(
new SequencerFeeVault(cfg.sequencerFeeVaultRecipient(), cfg.sequencerFeeVaultMinimumWithdrawalAmount(), FeeVault.WithdrawalNetwork.L2)
new SequencerFeeVault(deploy.cfg().sequencerFeeVaultRecipient(), deploy.cfg().sequencerFeeVaultMinimumWithdrawalAmount(), FeeVault.WithdrawalNetwork.L2)
).code
);
recipient = cfg.sequencerFeeVaultRecipient();
recipient = deploy.cfg().sequencerFeeVaultRecipient();
}
/// @dev Tests that `withdraw` successfully initiates a withdrawal to L2.
......
......@@ -32,15 +32,15 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init {
function setUp() public virtual override {
super.setUp();
batchInbox = cfg.batchInboxAddress();
owner = cfg.finalSystemOwner();
overhead = cfg.gasPriceOracleOverhead();
scalar = cfg.gasPriceOracleScalar();
batcherHash = bytes32(uint256(uint160(cfg.batchSenderAddress())));
gasLimit = uint64(cfg.l2GenesisBlockGasLimit());
unsafeBlockSigner = cfg.p2pSequencerAddress();
systemConfigImpl = mustGetAddress("SystemConfig");
optimismMintableERC20Factory = mustGetAddress("OptimismMintableERC20FactoryProxy");
batchInbox = deploy.cfg().batchInboxAddress();
owner = deploy.cfg().finalSystemOwner();
overhead = deploy.cfg().gasPriceOracleOverhead();
scalar = deploy.cfg().gasPriceOracleScalar();
batcherHash = bytes32(uint256(uint160(deploy.cfg().batchSenderAddress())));
gasLimit = uint64(deploy.cfg().l2GenesisBlockGasLimit());
unsafeBlockSigner = deploy.cfg().p2pSequencerAddress();
systemConfigImpl = deploy.mustGetAddress("SystemConfig");
optimismMintableERC20Factory = deploy.mustGetAddress("OptimismMintableERC20FactoryProxy");
}
/// @dev Tests that initailization sets the correct values.
......@@ -66,7 +66,7 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init {
contract SystemConfig_Initialize_TestFail is SystemConfig_Init {
/// @dev Tests that initialization reverts if the gas limit is too low.
function test_initialize_lowGasLimit_reverts() external {
address systemConfigImpl = mustGetAddress("SystemConfig");
address systemConfigImpl = deploy.mustGetAddress("SystemConfig");
uint64 minimumGasLimit = systemConfig.minimumGasLimit();
// Wipe out the initialized slot so the proxy can be initialized again
......
......@@ -24,8 +24,8 @@ contract CommonTest is Setup, Test, Events {
vm.fee(1 gwei);
// Set sane initialize block numbers
vm.warp(cfg.l2OutputOracleStartingTimestamp() + 1);
vm.roll(cfg.l2OutputOracleStartingBlockNumber() + 1);
vm.warp(deploy.cfg().l2OutputOracleStartingTimestamp() + 1);
vm.roll(deploy.cfg().l2OutputOracleStartingBlockNumber() + 1);
alice = makeAddr("alice");
bob = makeAddr("bob");
......@@ -35,7 +35,7 @@ contract CommonTest is Setup, Test, Events {
// Deploy L1
Setup.L1();
// Deploy L2
Setup.L2({ cfg: cfg });
Setup.L2({ cfg: deploy.cfg() });
}
/// @dev Helper function that wraps `TransactionDeposited` event.
......@@ -67,7 +67,7 @@ contract CommonTest is Setup, Test, Events {
warpToProposeTime(nextBlockNumber);
uint256 proposedNumber = l2OutputOracle.latestBlockNumber();
uint256 submissionInterval = cfg.l2OutputOracleSubmissionInterval();
uint256 submissionInterval = deploy.cfg().l2OutputOracleSubmissionInterval();
// Ensure the submissionInterval is enforced
assertEq(nextBlockNumber, proposedNumber + submissionInterval);
......@@ -76,7 +76,7 @@ contract CommonTest is Setup, Test, Events {
vm.expectEmit(true, true, true, true);
emit OutputProposed(proposedOutput2, nextOutputIndex, nextBlockNumber, block.timestamp);
address proposer = cfg.l2OutputOracleProposer();
address proposer = deploy.cfg().l2OutputOracleProposer();
vm.prank(proposer);
l2OutputOracle.proposeL2Output(proposedOutput2, nextBlockNumber, 0, 0);
}
......
......@@ -29,13 +29,18 @@ import { AddressManager } from "src/legacy/AddressManager.sol";
import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol";
import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol";
import { Executables } from "scripts/Executables.sol";
import { Vm } from "forge-std/Vm.sol";
/// @title Setup
/// @dev This contact is responsible for setting up the contracts in state. It currently
/// sets the L2 contracts directly at the predeploy addresses instead of setting them
/// up behind proxies. In the future we will migrate to importing the genesis JSON
/// file that is created to set up the L2 contracts instead of setting them up manually.
contract Setup is Deploy {
contract Setup {
Vm private constant vm = Vm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);
Deploy internal deploy;
OptimismPortal optimismPortal;
L2OutputOracle l2OutputOracle;
SystemConfig systemConfig;
......@@ -62,8 +67,20 @@ contract Setup is Deploy {
GovernanceToken governanceToken = GovernanceToken(Predeploys.GOVERNANCE_TOKEN);
LegacyERC20ETH legacyERC20ETH = LegacyERC20ETH(Predeploys.LEGACY_ERC20_ETH);
function setUp() public virtual override {
Deploy.setUp();
/// @dev Deploys the Deploy contract without including its bytecode in the bytecode
/// of this contract by fetching the bytecode dynamically using `vm.getCode()`.
/// Without this, it greatly increases the compile time.
function setUp() public virtual {
deploy = Deploy(_create(vm.getCode("Deploy.s.sol:Deploy")));
deploy.setUp();
}
/// @dev Simple wrapper around the `create` opcode
function _create(bytes memory _code) internal returns (address addr_) {
assembly {
addr_ := create(0, add(_code, 0x20), mload(_code))
}
require(addr_ != address(0), "Setup: cannot create");
}
/// @dev Sets up the L1 contracts.
......@@ -74,36 +91,36 @@ contract Setup is Deploy {
hex"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3"
);
Deploy.run();
deploy.run();
optimismPortal = OptimismPortal(mustGetAddress("OptimismPortalProxy"));
l2OutputOracle = L2OutputOracle(mustGetAddress("L2OutputOracleProxy"));
systemConfig = SystemConfig(mustGetAddress("SystemConfigProxy"));
l1StandardBridge = L1StandardBridge(mustGetAddress("L1StandardBridgeProxy"));
l1CrossDomainMessenger = L1CrossDomainMessenger(mustGetAddress("L1CrossDomainMessengerProxy"));
addressManager = AddressManager(mustGetAddress("AddressManager"));
l1ERC721Bridge = L1ERC721Bridge(mustGetAddress("L1ERC721BridgeProxy"));
optimismPortal = OptimismPortal(deploy.mustGetAddress("OptimismPortalProxy"));
l2OutputOracle = L2OutputOracle(deploy.mustGetAddress("L2OutputOracleProxy"));
systemConfig = SystemConfig(deploy.mustGetAddress("SystemConfigProxy"));
l1StandardBridge = L1StandardBridge(deploy.mustGetAddress("L1StandardBridgeProxy"));
l1CrossDomainMessenger = L1CrossDomainMessenger(deploy.mustGetAddress("L1CrossDomainMessengerProxy"));
addressManager = AddressManager(deploy.mustGetAddress("AddressManager"));
l1ERC721Bridge = L1ERC721Bridge(deploy.mustGetAddress("L1ERC721BridgeProxy"));
l1OptimismMintableERC20Factory =
OptimismMintableERC20Factory(mustGetAddress("OptimismMintableERC20FactoryProxy"));
protocolVersions = ProtocolVersions(mustGetAddress("ProtocolVersionsProxy"));
OptimismMintableERC20Factory(deploy.mustGetAddress("OptimismMintableERC20FactoryProxy"));
protocolVersions = ProtocolVersions(deploy.mustGetAddress("ProtocolVersionsProxy"));
vm.label(address(l2OutputOracle), "L2OutputOracle");
vm.label(mustGetAddress("L2OutputOracleProxy"), "L2OutputOracleProxy");
vm.label(deploy.mustGetAddress("L2OutputOracleProxy"), "L2OutputOracleProxy");
vm.label(address(optimismPortal), "OptimismPortal");
vm.label(mustGetAddress("OptimismPortalProxy"), "OptimismPortalProxy");
vm.label(deploy.mustGetAddress("OptimismPortalProxy"), "OptimismPortalProxy");
vm.label(address(systemConfig), "SystemConfig");
vm.label(mustGetAddress("SystemConfigProxy"), "SystemConfigProxy");
vm.label(deploy.mustGetAddress("SystemConfigProxy"), "SystemConfigProxy");
vm.label(address(l1StandardBridge), "L1StandardBridge");
vm.label(mustGetAddress("L1StandardBridgeProxy"), "L1StandardBridgeProxy");
vm.label(deploy.mustGetAddress("L1StandardBridgeProxy"), "L1StandardBridgeProxy");
vm.label(address(l1CrossDomainMessenger), "L1CrossDomainMessenger");
vm.label(mustGetAddress("L1CrossDomainMessengerProxy"), "L1CrossDomainMessengerProxy");
vm.label(deploy.mustGetAddress("L1CrossDomainMessengerProxy"), "L1CrossDomainMessengerProxy");
vm.label(address(addressManager), "AddressManager");
vm.label(address(l1ERC721Bridge), "L1ERC721Bridge");
vm.label(mustGetAddress("L1ERC721BridgeProxy"), "L1ERC721BridgeProxy");
vm.label(deploy.mustGetAddress("L1ERC721BridgeProxy"), "L1ERC721BridgeProxy");
vm.label(address(l1OptimismMintableERC20Factory), "OptimismMintableERC20Factory");
vm.label(mustGetAddress("OptimismMintableERC20FactoryProxy"), "OptimismMintableERC20FactoryProxy");
vm.label(deploy.mustGetAddress("OptimismMintableERC20FactoryProxy"), "OptimismMintableERC20FactoryProxy");
vm.label(address(protocolVersions), "ProtocolVersions");
vm.label(mustGetAddress("ProtocolVersionsProxy"), "ProtocolVersionsProxy");
vm.label(deploy.mustGetAddress("ProtocolVersionsProxy"), "ProtocolVersionsProxy");
vm.label(AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)), "L1CrossDomainMessenger_aliased");
}
......
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