From e874c5ffa6045795718cfdb8ccb6fa016b9030b7 Mon Sep 17 00:00:00 2001 From: Kelvin Fichter Date: Wed, 11 Sep 2024 15:38:06 -0400 Subject: [PATCH] maint: add remaining L1 contract interfaces Adds interfaces for all remaining L1 contracts. L2 contracts are next! --- packages/contracts-bedrock/.gas-snapshot | 16 ++-- .../contracts-bedrock/scripts/L2Genesis.s.sol | 34 +++++---- .../scripts/checks/check-interfaces.sh | 4 +- .../scripts/deploy/ChainAssertions.sol | 18 ++--- .../scripts/deploy/Deploy.s.sol | 50 +++++-------- .../periphery/deploy/DeployPeriphery.s.sol | 1 - packages/contracts-bedrock/semver-lock.json | 6 +- .../src/L1/interfaces/IL1ERC721Bridge.sol | 40 ++++++++++ .../src/L1/interfaces/IL1StandardBridge.sol | 75 +++++++++++++++++++ .../src/L1/interfaces/IProtocolVersions.sol | 28 +++++++ .../L1/interfaces/ISystemConfigInterop.sol | 24 ++++++ .../src/L2/L2ERC721Bridge.sol | 13 +++- .../src/L2/L2StandardBridge.sol | 11 ++- .../src/L2/L2StandardBridgeInterop.sol | 7 +- .../universal/interfaces/IERC721Bridge.sol | 47 ++++++++++++ .../IOptimismMintableERC20Factory.sol | 36 +++++++++ .../universal/interfaces/IStandardBridge.sol | 64 ++++++++++++++++ .../test/L1/L1ERC721Bridge.t.sol | 16 ++-- .../test/L1/L1StandardBridge.t.sol | 22 +++--- .../test/L1/ProtocolVersions.t.sol | 18 ++--- .../test/L1/SystemConfigInterop.t.sol | 16 ++-- .../test/L2/L2ERC721Bridge.t.sol | 13 ++-- packages/contracts-bedrock/test/Specs.t.sol | 12 +-- .../contracts-bedrock/test/setup/Setup.sol | 49 ++++++------ .../OptimismMintableERC20Factory.t.sol | 11 +-- .../test/vendor/Initializable.t.sol | 8 +- 26 files changed, 483 insertions(+), 156 deletions(-) create mode 100644 packages/contracts-bedrock/src/L1/interfaces/IL1ERC721Bridge.sol create mode 100644 packages/contracts-bedrock/src/L1/interfaces/IL1StandardBridge.sol create mode 100644 packages/contracts-bedrock/src/L1/interfaces/IProtocolVersions.sol create mode 100644 packages/contracts-bedrock/src/L1/interfaces/ISystemConfigInterop.sol create mode 100644 packages/contracts-bedrock/src/universal/interfaces/IERC721Bridge.sol create mode 100644 packages/contracts-bedrock/src/universal/interfaces/IOptimismMintableERC20Factory.sol create mode 100644 packages/contracts-bedrock/src/universal/interfaces/IStandardBridge.sol diff --git a/packages/contracts-bedrock/.gas-snapshot b/packages/contracts-bedrock/.gas-snapshot index af4acca99719..f42bdc83dcb7 100644 --- a/packages/contracts-bedrock/.gas-snapshot +++ b/packages/contracts-bedrock/.gas-snapshot @@ -6,12 +6,12 @@ GasBenchMark_L1Block_SetValuesEcotone:test_setL1BlockValuesEcotone_benchmark() ( GasBenchMark_L1Block_SetValuesEcotone_Warm:test_setL1BlockValuesEcotone_benchmark() (gas: 7597) GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 369242) GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2967382) -GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 564365) -GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4076580) -GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 467007) -GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 3512689) -GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 72624) +GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 564356) +GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4076571) +GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 467019) +GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 3512701) +GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 72618) GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 92973) -GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 68320) -GasBenchMark_OptimismPortal:test_depositTransaction_benchmark_1() (gas: 68962) -GasBenchMark_OptimismPortal:test_proveWithdrawalTransaction_benchmark() (gas: 155618) \ No newline at end of file +GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 68312) +GasBenchMark_OptimismPortal:test_depositTransaction_benchmark_1() (gas: 68943) +GasBenchMark_OptimismPortal:test_proveWithdrawalTransaction_benchmark() (gas: 155610) \ No newline at end of file diff --git a/packages/contracts-bedrock/scripts/L2Genesis.s.sol b/packages/contracts-bedrock/scripts/L2Genesis.s.sol index e6040f4eec2f..1ab494b052f8 100644 --- a/packages/contracts-bedrock/scripts/L2Genesis.s.sol +++ b/packages/contracts-bedrock/scripts/L2Genesis.s.sol @@ -1,31 +1,39 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +// Testing import { Script } from "forge-std/Script.sol"; import { console2 as console } from "forge-std/console2.sol"; -import { Deployer } from "scripts/deploy/Deployer.sol"; +import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; +// Scripts +import { Deployer } from "scripts/deploy/Deployer.sol"; import { Config, OutputMode, OutputModeUtils, Fork, ForkUtils, LATEST_FORK } from "scripts/libraries/Config.sol"; import { Artifacts } from "scripts/Artifacts.s.sol"; import { DeployConfig } from "scripts/deploy/DeployConfig.s.sol"; -import { Predeploys } from "src/libraries/Predeploys.sol"; -import { Preinstalls } from "src/libraries/Preinstalls.sol"; +import { Process } from "scripts/libraries/Process.sol"; + +// Contracts import { L2CrossDomainMessenger } from "src/L2/L2CrossDomainMessenger.sol"; import { L1Block } from "src/L2/L1Block.sol"; import { GasPriceOracle } from "src/L2/GasPriceOracle.sol"; import { L2StandardBridge } from "src/L2/L2StandardBridge.sol"; import { L2ERC721Bridge } from "src/L2/L2ERC721Bridge.sol"; import { SequencerFeeVault } from "src/L2/SequencerFeeVault.sol"; -import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; -import { OptimismMintableERC721Factory } from "src/universal/OptimismMintableERC721Factory.sol"; import { BaseFeeVault } from "src/L2/BaseFeeVault.sol"; import { L1FeeVault } from "src/L2/L1FeeVault.sol"; -import { GovernanceToken } from "src/governance/GovernanceToken.sol"; +import { OptimismMintableERC721Factory } from "src/universal/OptimismMintableERC721Factory.sol"; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; -import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; +import { StandardBridge } from "src/universal/StandardBridge.sol"; import { FeeVault } from "src/universal/FeeVault.sol"; -import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; -import { Process } from "scripts/libraries/Process.sol"; +import { GovernanceToken } from "src/governance/GovernanceToken.sol"; + +// Libraries +import { Predeploys } from "src/libraries/Predeploys.sol"; +import { Preinstalls } from "src/libraries/Preinstalls.sol"; + +// Interfaces +import { IOptimismMintableERC20Factory } from "src/universal/interfaces/IOptimismMintableERC20Factory.sol"; interface IInitializable { function initialize(address _addr) external; @@ -296,10 +304,10 @@ contract L2Genesis is Deployer { impl = _setImplementationCode(Predeploys.L2_STANDARD_BRIDGE); } - L2StandardBridge(payable(impl)).initialize({ _otherBridge: L1StandardBridge(payable(address(0))) }); + L2StandardBridge(payable(impl)).initialize({ _otherBridge: StandardBridge(payable(address(0))) }); L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE)).initialize({ - _otherBridge: L1StandardBridge(_l1StandardBridgeProxy) + _otherBridge: StandardBridge(_l1StandardBridgeProxy) }); } @@ -333,9 +341,9 @@ contract L2Genesis is Deployer { function setOptimismMintableERC20Factory() public { address impl = _setImplementationCode(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY); - OptimismMintableERC20Factory(impl).initialize({ _bridge: address(0) }); + IOptimismMintableERC20Factory(impl).initialize({ _bridge: address(0) }); - OptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY).initialize({ + IOptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY).initialize({ _bridge: Predeploys.L2_STANDARD_BRIDGE }); } diff --git a/packages/contracts-bedrock/scripts/checks/check-interfaces.sh b/packages/contracts-bedrock/scripts/checks/check-interfaces.sh index 89a62e3c4ce0..df8c10238ca4 100755 --- a/packages/contracts-bedrock/scripts/checks/check-interfaces.sh +++ b/packages/contracts-bedrock/scripts/checks/check-interfaces.sh @@ -35,7 +35,6 @@ EXCLUDE_CONTRACTS=( "Vm" "VmSafe" "IMulticall3" - "IBeacon" "IERC721TokenReceiver" "IProxyCreationCallback" @@ -68,6 +67,9 @@ EXCLUDE_CONTRACTS=( "ISuperchainConfig" "IOptimismPortal" "IL1BlockIsthmus" + + # Need to make complex tweaks to the check script for this one + "ISystemConfigInterop" ) # Find all JSON files in the forge-artifacts folder diff --git a/packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol b/packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol index 0ebb848f23a3..efe20eb7343e 100644 --- a/packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol +++ b/packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol @@ -8,15 +8,12 @@ import { console2 as console } from "forge-std/console2.sol"; // Scripts import { DeployConfig } from "scripts/deploy/DeployConfig.s.sol"; import { Deployer } from "scripts/deploy/Deployer.sol"; +import { ISystemConfigV0 } from "scripts/interfaces/ISystemConfigV0.sol"; // Contracts import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; -import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; -import { ProtocolVersion, ProtocolVersions } from "src/L1/ProtocolVersions.sol"; -import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; -import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; // Libraries import { Constants } from "src/libraries/Constants.sol"; @@ -31,7 +28,10 @@ import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; import { IL1CrossDomainMessenger } from "src/L1/interfaces/IL1CrossDomainMessenger.sol"; import { IOptimismPortal } from "src/L1/interfaces/IOptimismPortal.sol"; import { IOptimismPortal2 } from "src/L1/interfaces/IOptimismPortal2.sol"; -import { ISystemConfigV0 } from "scripts/interfaces/ISystemConfigV0.sol"; +import { IL1ERC721Bridge } from "src/L1/interfaces/IL1ERC721Bridge.sol"; +import { IL1StandardBridge } from "src/L1/interfaces/IL1StandardBridge.sol"; +import { ProtocolVersion, IProtocolVersions } from "src/L1/interfaces/IProtocolVersions.sol"; +import { IOptimismMintableERC20Factory } from "src/universal/interfaces/IOptimismMintableERC20Factory.sol"; library ChainAssertions { Vm internal constant vm = Vm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); @@ -160,7 +160,7 @@ library ChainAssertions { /// @notice Asserts that the L1StandardBridge is setup correctly function checkL1StandardBridge(Types.ContractSet memory _contracts, bool _isProxy) internal view { console.log("Running chain assertions on the L1StandardBridge"); - L1StandardBridge bridge = L1StandardBridge(payable(_contracts.L1StandardBridge)); + IL1StandardBridge bridge = IL1StandardBridge(payable(_contracts.L1StandardBridge)); // Check that the contract is initialized assertSlotValueIsOne({ _contractAddress: address(bridge), _slot: 0, _offset: 0 }); @@ -291,7 +291,7 @@ library ChainAssertions { /// @notice Asserts that the OptimismMintableERC20Factory is setup correctly function checkOptimismMintableERC20Factory(Types.ContractSet memory _contracts, bool _isProxy) internal view { console.log("Running chain assertions on the OptimismMintableERC20Factory"); - OptimismMintableERC20Factory factory = OptimismMintableERC20Factory(_contracts.OptimismMintableERC20Factory); + IOptimismMintableERC20Factory factory = IOptimismMintableERC20Factory(_contracts.OptimismMintableERC20Factory); // Check that the contract is initialized assertSlotValueIsOne({ _contractAddress: address(factory), _slot: 0, _offset: 0 }); @@ -308,7 +308,7 @@ library ChainAssertions { /// @notice Asserts that the L1ERC721Bridge is setup correctly function checkL1ERC721Bridge(Types.ContractSet memory _contracts, bool _isProxy) internal view { console.log("Running chain assertions on the L1ERC721Bridge"); - L1ERC721Bridge bridge = L1ERC721Bridge(_contracts.L1ERC721Bridge); + IL1ERC721Bridge bridge = IL1ERC721Bridge(_contracts.L1ERC721Bridge); // Check that the contract is initialized assertSlotValueIsOne({ _contractAddress: address(bridge), _slot: 0, _offset: 0 }); @@ -405,7 +405,7 @@ library ChainAssertions { view { console.log("Running chain assertions on the ProtocolVersions"); - ProtocolVersions versions = ProtocolVersions(_contracts.ProtocolVersions); + IProtocolVersions versions = IProtocolVersions(_contracts.ProtocolVersions); // Check that the contract is initialized assertSlotValueIsOne({ _contractAddress: address(versions), _slot: 0, _offset: 0 }); diff --git a/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol b/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol index 3399ef09da15..b0cdcc4dcfe3 100644 --- a/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol @@ -28,12 +28,9 @@ import { ChainAssertions } from "scripts/deploy/ChainAssertions.sol"; import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; import { AddressManager } from "src/legacy/AddressManager.sol"; import { Proxy } from "src/universal/Proxy.sol"; -import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; import { StandardBridge } from "src/universal/StandardBridge.sol"; import { L1ChugSplashProxy } from "src/legacy/L1ChugSplashProxy.sol"; import { ResolvedDelegateProxy } from "src/legacy/ResolvedDelegateProxy.sol"; -import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; -import { SystemConfigInterop } from "src/L1/SystemConfigInterop.sol"; import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; import { PermissionedDisputeGame } from "src/dispute/PermissionedDisputeGame.sol"; @@ -41,8 +38,6 @@ import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; import { MIPS } from "src/cannon/MIPS.sol"; -import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; -import { ProtocolVersions, ProtocolVersion } from "src/L1/ProtocolVersions.sol"; import { StorageSetter } from "src/universal/StorageSetter.sol"; // Libraries @@ -61,8 +56,12 @@ import { IL2OutputOracle } from "src/L1/interfaces/IL2OutputOracle.sol"; import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; import { IDataAvailabilityChallenge } from "src/L1/interfaces/IDataAvailabilityChallenge.sol"; +import { IL1ERC721Bridge } from "src/L1/interfaces/IL1ERC721Bridge.sol"; +import { IL1StandardBridge } from "src/L1/interfaces/IL1StandardBridge.sol"; +import { IProtocolVersions, ProtocolVersion } from "src/L1/interfaces/IProtocolVersions.sol"; import { IBigStepper } from "src/dispute/interfaces/IBigStepper.sol"; import { IPreimageOracle } from "src/cannon/interfaces/IPreimageOracle.sol"; +import { IOptimismMintableERC20Factory } from "src/universal/interfaces/IOptimismMintableERC20Factory.sol"; /// @title Deploy /// @notice Script used to deploy a bedrock system. The entire system is deployed within the `run` function. @@ -751,11 +750,8 @@ contract Deploy is Deployer { /// @notice Deploy the OptimismMintableERC20Factory function deployOptimismMintableERC20Factory() public broadcast returns (address addr_) { - console.log("Deploying OptimismMintableERC20Factory implementation"); - OptimismMintableERC20Factory factory = new OptimismMintableERC20Factory{ salt: _implSalt() }(); - - save("OptimismMintableERC20Factory", address(factory)); - console.log("OptimismMintableERC20Factory deployed at %s", address(factory)); + IOptimismMintableERC20Factory factory = + IOptimismMintableERC20Factory(_deploy("OptimismMintableERC20Factory", hex"")); // Override the `OptimismMintableERC20Factory` contract to the deployed implementation. This is necessary // to check the `OptimismMintableERC20Factory` implementation alongside dependent contracts, which @@ -806,10 +802,7 @@ contract Deploy is Deployer { /// @notice Deploy the ProtocolVersions function deployProtocolVersions() public broadcast returns (address addr_) { - console.log("Deploying ProtocolVersions implementation"); - ProtocolVersions versions = new ProtocolVersions{ salt: _implSalt() }(); - save("ProtocolVersions", address(versions)); - console.log("ProtocolVersions deployed at %s", address(versions)); + IProtocolVersions versions = IProtocolVersions(_deploy("ProtocolVersions", hex"")); // Override the `ProtocolVersions` contract to the deployed implementation. This is necessary // to check the `ProtocolVersions` implementation alongside dependent contracts, which @@ -874,12 +867,7 @@ contract Deploy is Deployer { /// @notice Deploy the L1StandardBridge function deployL1StandardBridge() public broadcast returns (address addr_) { - console.log("Deploying L1StandardBridge implementation"); - - L1StandardBridge bridge = new L1StandardBridge{ salt: _implSalt() }(); - - save("L1StandardBridge", address(bridge)); - console.log("L1StandardBridge deployed at %s", address(bridge)); + IL1StandardBridge bridge = IL1StandardBridge(payable(_deploy("L1StandardBridge", hex""))); // Override the `L1StandardBridge` contract to the deployed implementation. This is necessary // to check the `L1StandardBridge` implementation alongside dependent contracts, which @@ -893,11 +881,7 @@ contract Deploy is Deployer { /// @notice Deploy the L1ERC721Bridge function deployL1ERC721Bridge() public broadcast returns (address addr_) { - console.log("Deploying L1ERC721Bridge implementation"); - L1ERC721Bridge bridge = new L1ERC721Bridge{ salt: _implSalt() }(); - - save("L1ERC721Bridge", address(bridge)); - console.log("L1ERC721Bridge deployed at %s", address(bridge)); + IL1ERC721Bridge bridge = IL1ERC721Bridge(_deploy("L1ERC721Bridge", hex"")); // Override the `L1ERC721Bridge` contract to the deployed implementation. This is necessary // to check the `L1ERC721Bridge` implementation alongside dependent contracts, which @@ -1137,7 +1121,7 @@ contract Deploy is Deployer { _proxy: payable(l1StandardBridgeProxy), _implementation: l1StandardBridge, _innerCallData: abi.encodeCall( - L1StandardBridge.initialize, + IL1StandardBridge.initialize, ( ICrossDomainMessenger(l1CrossDomainMessengerProxy), ISuperchainConfig(superchainConfigProxy), @@ -1146,7 +1130,7 @@ contract Deploy is Deployer { ) }); - string memory version = L1StandardBridge(payable(l1StandardBridgeProxy)).version(); + string memory version = IL1StandardBridge(payable(l1StandardBridgeProxy)).version(); console.log("L1StandardBridge version: %s", version); ChainAssertions.checkL1StandardBridge({ _contracts: _proxies(), _isProxy: true }); @@ -1164,12 +1148,12 @@ contract Deploy is Deployer { _proxy: payable(l1ERC721BridgeProxy), _implementation: l1ERC721Bridge, _innerCallData: abi.encodeCall( - L1ERC721Bridge.initialize, + IL1ERC721Bridge.initialize, (ICrossDomainMessenger(payable(l1CrossDomainMessengerProxy)), ISuperchainConfig(superchainConfigProxy)) ) }); - L1ERC721Bridge bridge = L1ERC721Bridge(l1ERC721BridgeProxy); + IL1ERC721Bridge bridge = IL1ERC721Bridge(l1ERC721BridgeProxy); string memory version = bridge.version(); console.log("L1ERC721Bridge version: %s", version); @@ -1186,10 +1170,10 @@ contract Deploy is Deployer { _upgradeAndCallViaSafe({ _proxy: payable(optimismMintableERC20FactoryProxy), _implementation: optimismMintableERC20Factory, - _innerCallData: abi.encodeCall(OptimismMintableERC20Factory.initialize, (l1StandardBridgeProxy)) + _innerCallData: abi.encodeCall(IOptimismMintableERC20Factory.initialize, (l1StandardBridgeProxy)) }); - OptimismMintableERC20Factory factory = OptimismMintableERC20Factory(optimismMintableERC20FactoryProxy); + IOptimismMintableERC20Factory factory = IOptimismMintableERC20Factory(optimismMintableERC20FactoryProxy); string memory version = factory.version(); console.log("OptimismMintableERC20Factory version: %s", version); @@ -1358,7 +1342,7 @@ contract Deploy is Deployer { _proxy: payable(protocolVersionsProxy), _implementation: protocolVersions, _innerCallData: abi.encodeCall( - ProtocolVersions.initialize, + IProtocolVersions.initialize, ( finalSystemOwner, ProtocolVersion.wrap(requiredProtocolVersion), @@ -1367,7 +1351,7 @@ contract Deploy is Deployer { ) }); - ProtocolVersions versions = ProtocolVersions(protocolVersionsProxy); + IProtocolVersions versions = IProtocolVersions(protocolVersionsProxy); string memory version = versions.version(); console.log("ProtocolVersions version: %s", version); diff --git a/packages/contracts-bedrock/scripts/periphery/deploy/DeployPeriphery.s.sol b/packages/contracts-bedrock/scripts/periphery/deploy/DeployPeriphery.s.sol index 856104eb2734..8f4b86b95d62 100644 --- a/packages/contracts-bedrock/scripts/periphery/deploy/DeployPeriphery.s.sol +++ b/packages/contracts-bedrock/scripts/periphery/deploy/DeployPeriphery.s.sol @@ -10,7 +10,6 @@ import { PeripheryDeployConfig } from "scripts/periphery/deploy/PeripheryDeployC import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; import { Proxy } from "src/universal/Proxy.sol"; -import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; import { Faucet } from "src/periphery/faucet/Faucet.sol"; import { Drippie } from "src/periphery/drippie/Drippie.sol"; import { CheckGelatoLow } from "src/periphery/drippie/dripchecks/CheckGelatoLow.sol"; diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 8f44a70958a7..8541285d0b74 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -97,15 +97,15 @@ }, "src/L2/L2ERC721Bridge.sol": { "initCodeHash": "0x827077e1a0ce6c8f9ee1196c409ea77d831efd440992b3969b05259083cdf0bd", - "sourceCodeHash": "0xdc5e08a5a9ee8d61e843ac630126629ccfedb49a3b0dd167863dd48d75629a95" + "sourceCodeHash": "0x51a44e1fcef9483cc58ba0c9895cb3eec675785145428ece9aa7acd1a1a5b57c" }, "src/L2/L2StandardBridge.sol": { "initCodeHash": "0x01692b613e3d4e649d877a0fd8f0798a26401ba8ccc4cda0e61f1f9079729320", - "sourceCodeHash": "0x5c8e8ba3ecdae116f98caf67cca5fb3594bf7085e186f0a14bad1d6f143b6bc8" + "sourceCodeHash": "0xca7d45b137fb66a941cbfe97a914c8bda78462c86ddd90085b6e2275cfb6da92" }, "src/L2/L2StandardBridgeInterop.sol": { "initCodeHash": "0x5c9ef6b0817f715d1b8b097f3fc19e33bc54453426ca12bb48e4cea143076339", - "sourceCodeHash": "0x5a2d206477d6ba84e93bf0e1545a5cf2c93a6bb80529c07927f53915bde298bf" + "sourceCodeHash": "0x6c814f4536d9fb8f384ed2195957f868abd15252e36d6dd243f3d60349a61994" }, "src/L2/L2ToL1MessagePasser.sol": { "initCodeHash": "0x13fe3729beb9ed966c97bef09acb9fe5043fe651d453145073d05f2567fa988d", diff --git a/packages/contracts-bedrock/src/L1/interfaces/IL1ERC721Bridge.sol b/packages/contracts-bedrock/src/L1/interfaces/IL1ERC721Bridge.sol new file mode 100644 index 000000000000..fd64f40fe5ac --- /dev/null +++ b/packages/contracts-bedrock/src/L1/interfaces/IL1ERC721Bridge.sol @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { IERC721Bridge } from "src/universal/interfaces/IERC721Bridge.sol"; +import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; +import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; + +interface IL1ERC721Bridge is IERC721Bridge { + function bridgeERC721( + address _localToken, + address _remoteToken, + uint256 _tokenId, + uint32 _minGasLimit, + bytes memory _extraData + ) + external; + function bridgeERC721To( + address _localToken, + address _remoteToken, + address _to, + uint256 _tokenId, + uint32 _minGasLimit, + bytes memory _extraData + ) + external; + function deposits(address, address, uint256) external view returns (bool); + function finalizeBridgeERC721( + address _localToken, + address _remoteToken, + address _from, + address _to, + uint256 _tokenId, + bytes memory _extraData + ) + external; + function initialize(ICrossDomainMessenger _messenger, ISuperchainConfig _superchainConfig) external; + function paused() external view returns (bool); + function superchainConfig() external view returns (ISuperchainConfig); + function version() external view returns (string memory); +} diff --git a/packages/contracts-bedrock/src/L1/interfaces/IL1StandardBridge.sol b/packages/contracts-bedrock/src/L1/interfaces/IL1StandardBridge.sol new file mode 100644 index 000000000000..119c8c1f1d8e --- /dev/null +++ b/packages/contracts-bedrock/src/L1/interfaces/IL1StandardBridge.sol @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { IStandardBridge } from "src/universal/interfaces/IStandardBridge.sol"; +import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; +import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; +import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; + +interface IL1StandardBridge is IStandardBridge { + event ERC20DepositInitiated( + address indexed l1Token, + address indexed l2Token, + address indexed from, + address to, + uint256 amount, + bytes extraData + ); + event ERC20WithdrawalFinalized( + address indexed l1Token, + address indexed l2Token, + address indexed from, + address to, + uint256 amount, + bytes extraData + ); + event ETHDepositInitiated(address indexed from, address indexed to, uint256 amount, bytes extraData); + event ETHWithdrawalFinalized(address indexed from, address indexed to, uint256 amount, bytes extraData); + + function depositERC20( + address _l1Token, + address _l2Token, + uint256 _amount, + uint32 _minGasLimit, + bytes memory _extraData + ) + external; + function depositERC20To( + address _l1Token, + address _l2Token, + address _to, + uint256 _amount, + uint32 _minGasLimit, + bytes memory _extraData + ) + external; + function depositETH(uint32 _minGasLimit, bytes memory _extraData) external payable; + function depositETHTo(address _to, uint32 _minGasLimit, bytes memory _extraData) external payable; + function finalizeERC20Withdrawal( + address _l1Token, + address _l2Token, + address _from, + address _to, + uint256 _amount, + bytes memory _extraData + ) + external; + function finalizeETHWithdrawal( + address _from, + address _to, + uint256 _amount, + bytes memory _extraData + ) + external + payable; + function initialize( + ICrossDomainMessenger _messenger, + ISuperchainConfig _superchainConfig, + ISystemConfig _systemConfig + ) + external; + function l2TokenBridge() external view returns (address); + function superchainConfig() external view returns (ISuperchainConfig); + function systemConfig() external view returns (ISystemConfig); + function version() external view returns (string memory); +} diff --git a/packages/contracts-bedrock/src/L1/interfaces/IProtocolVersions.sol b/packages/contracts-bedrock/src/L1/interfaces/IProtocolVersions.sol new file mode 100644 index 000000000000..0fbd8d1f2de6 --- /dev/null +++ b/packages/contracts-bedrock/src/L1/interfaces/IProtocolVersions.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +type ProtocolVersion is uint256; + +interface IProtocolVersions { + enum UpdateType { + REQUIRED_PROTOCOL_VERSION, + RECOMMENDED_PROTOCOL_VERSION + } + + event ConfigUpdate(uint256 indexed version, UpdateType indexed updateType, bytes data); + event Initialized(uint8 version); + event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + + function RECOMMENDED_SLOT() external view returns (bytes32); + function REQUIRED_SLOT() external view returns (bytes32); + function VERSION() external view returns (uint256); + function initialize(address _owner, ProtocolVersion _required, ProtocolVersion _recommended) external; + function owner() external view returns (address); + function recommended() external view returns (ProtocolVersion out_); + function renounceOwnership() external; + function required() external view returns (ProtocolVersion out_); + function setRecommended(ProtocolVersion _recommended) external; + function setRequired(ProtocolVersion _required) external; + function transferOwnership(address newOwner) external; + function version() external view returns (string memory); +} diff --git a/packages/contracts-bedrock/src/L1/interfaces/ISystemConfigInterop.sol b/packages/contracts-bedrock/src/L1/interfaces/ISystemConfigInterop.sol new file mode 100644 index 000000000000..3f6e6f723650 --- /dev/null +++ b/packages/contracts-bedrock/src/L1/interfaces/ISystemConfigInterop.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; +import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; + +interface ISystemConfigInterop is ISystemConfig { + function addDependency(uint256 _chainId) external; + function dependencyManager() external view returns (address); + function initialize( + address _owner, + uint32 _basefeeScalar, + uint32 _blobbasefeeScalar, + bytes32 _batcherHash, + uint64 _gasLimit, + address _unsafeBlockSigner, + IResourceMetering.ResourceConfig memory _config, + address _batchInbox, + Addresses memory _addresses, + address _dependencyManager + ) + external; + function removeDependency(uint256 _chainId) external; +} diff --git a/packages/contracts-bedrock/src/L2/L2ERC721Bridge.sol b/packages/contracts-bedrock/src/L2/L2ERC721Bridge.sol index 3ff30e8b7272..4f3231c677f0 100644 --- a/packages/contracts-bedrock/src/L2/L2ERC721Bridge.sol +++ b/packages/contracts-bedrock/src/L2/L2ERC721Bridge.sol @@ -1,14 +1,19 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +// Contracts import { ERC721Bridge } from "src/universal/ERC721Bridge.sol"; + +// Libraries import { ERC165Checker } from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; -import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; +import { Constants } from "src/libraries/Constants.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; + +// Interfaces +import { IL1ERC721Bridge } from "src/L1/interfaces/IL1ERC721Bridge.sol"; import { IOptimismMintableERC721 } from "src/universal/interfaces/IOptimismMintableERC721.sol"; import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; import { ISemver } from "src/universal/interfaces/ISemver.sol"; -import { Constants } from "src/libraries/Constants.sol"; -import { Predeploys } from "src/libraries/Predeploys.sol"; /// @custom:proxied true /// @custom:predeploy 0x4200000000000000000000000000000000000014 @@ -114,7 +119,7 @@ contract L2ERC721Bridge is ERC721Bridge, ISemver { IOptimismMintableERC721(_localToken).burn(_from, _tokenId); bytes memory message = abi.encodeWithSelector( - L1ERC721Bridge.finalizeBridgeERC721.selector, remoteToken, _localToken, _from, _to, _tokenId, _extraData + IL1ERC721Bridge.finalizeBridgeERC721.selector, remoteToken, _localToken, _from, _to, _tokenId, _extraData ); // Send message to L1 bridge diff --git a/packages/contracts-bedrock/src/L2/L2StandardBridge.sol b/packages/contracts-bedrock/src/L2/L2StandardBridge.sol index 063ee398f770..5cf6ebecfb5d 100644 --- a/packages/contracts-bedrock/src/L2/L2StandardBridge.sol +++ b/packages/contracts-bedrock/src/L2/L2StandardBridge.sol @@ -1,13 +1,18 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { Predeploys } from "src/libraries/Predeploys.sol"; +// Contracts import { StandardBridge } from "src/universal/StandardBridge.sol"; -import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; -import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; import { L1Block } from "src/L2/L1Block.sol"; +// Libraries +import { Predeploys } from "src/libraries/Predeploys.sol"; + +// Interfaces +import { ISemver } from "src/universal/interfaces/ISemver.sol"; +import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; + /// @custom:proxied true /// @custom:predeploy 0x4200000000000000000000000000000000000010 /// @title L2StandardBridge diff --git a/packages/contracts-bedrock/src/L2/L2StandardBridgeInterop.sol b/packages/contracts-bedrock/src/L2/L2StandardBridgeInterop.sol index f7a82fc2af3f..be6c9e4c878d 100644 --- a/packages/contracts-bedrock/src/L2/L2StandardBridgeInterop.sol +++ b/packages/contracts-bedrock/src/L2/L2StandardBridgeInterop.sol @@ -1,8 +1,13 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { Predeploys } from "src/libraries/Predeploys.sol"; +// Contracts import { L2StandardBridge } from "src/L2/L2StandardBridge.sol"; + +// Libraries +import { Predeploys } from "src/libraries/Predeploys.sol"; + +// Interfaces import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import { IOptimismERC20Factory } from "src/L2/interfaces/IOptimismERC20Factory.sol"; diff --git a/packages/contracts-bedrock/src/universal/interfaces/IERC721Bridge.sol b/packages/contracts-bedrock/src/universal/interfaces/IERC721Bridge.sol new file mode 100644 index 000000000000..ccb2d5f0a483 --- /dev/null +++ b/packages/contracts-bedrock/src/universal/interfaces/IERC721Bridge.sol @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; + +interface IERC721Bridge { + event ERC721BridgeFinalized( + address indexed localToken, + address indexed remoteToken, + address indexed from, + address to, + uint256 tokenId, + bytes extraData + ); + event ERC721BridgeInitiated( + address indexed localToken, + address indexed remoteToken, + address indexed from, + address to, + uint256 tokenId, + bytes extraData + ); + event Initialized(uint8 version); + + function MESSENGER() external view returns (ICrossDomainMessenger); + function OTHER_BRIDGE() external view returns (IERC721Bridge); + function bridgeERC721( + address _localToken, + address _remoteToken, + uint256 _tokenId, + uint32 _minGasLimit, + bytes memory _extraData + ) + external; + function bridgeERC721To( + address _localToken, + address _remoteToken, + address _to, + uint256 _tokenId, + uint32 _minGasLimit, + bytes memory _extraData + ) + external; + function messenger() external view returns (ICrossDomainMessenger); + function otherBridge() external view returns (IERC721Bridge); + function paused() external view returns (bool); +} diff --git a/packages/contracts-bedrock/src/universal/interfaces/IOptimismMintableERC20Factory.sol b/packages/contracts-bedrock/src/universal/interfaces/IOptimismMintableERC20Factory.sol new file mode 100644 index 000000000000..ecb52c94cada --- /dev/null +++ b/packages/contracts-bedrock/src/universal/interfaces/IOptimismMintableERC20Factory.sol @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IOptimismMintableERC20Factory { + event Initialized(uint8 version); + event OptimismMintableERC20Created(address indexed localToken, address indexed remoteToken, address deployer); + event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken); + + function BRIDGE() external view returns (address); + function bridge() external view returns (address); + function createOptimismMintableERC20( + address _remoteToken, + string memory _name, + string memory _symbol + ) + external + returns (address); + function createOptimismMintableERC20WithDecimals( + address _remoteToken, + string memory _name, + string memory _symbol, + uint8 _decimals + ) + external + returns (address); + function createStandardL2Token( + address _remoteToken, + string memory _name, + string memory _symbol + ) + external + returns (address); + function deployments(address) external view returns (address); + function initialize(address _bridge) external; + function version() external view returns (string memory); +} diff --git a/packages/contracts-bedrock/src/universal/interfaces/IStandardBridge.sol b/packages/contracts-bedrock/src/universal/interfaces/IStandardBridge.sol new file mode 100644 index 000000000000..b92aae27503b --- /dev/null +++ b/packages/contracts-bedrock/src/universal/interfaces/IStandardBridge.sol @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; + +interface IStandardBridge { + event ERC20BridgeFinalized( + address indexed localToken, + address indexed remoteToken, + address indexed from, + address to, + uint256 amount, + bytes extraData + ); + event ERC20BridgeInitiated( + address indexed localToken, + address indexed remoteToken, + address indexed from, + address to, + uint256 amount, + bytes extraData + ); + event ETHBridgeFinalized(address indexed from, address indexed to, uint256 amount, bytes extraData); + event ETHBridgeInitiated(address indexed from, address indexed to, uint256 amount, bytes extraData); + event Initialized(uint8 version); + + receive() external payable; + + function MESSENGER() external view returns (ICrossDomainMessenger); + function OTHER_BRIDGE() external view returns (IStandardBridge); + function bridgeERC20( + address _localToken, + address _remoteToken, + uint256 _amount, + uint32 _minGasLimit, + bytes memory _extraData + ) + external; + function bridgeERC20To( + address _localToken, + address _remoteToken, + address _to, + uint256 _amount, + uint32 _minGasLimit, + bytes memory _extraData + ) + external; + function bridgeETH(uint32 _minGasLimit, bytes memory _extraData) external payable; + function bridgeETHTo(address _to, uint32 _minGasLimit, bytes memory _extraData) external payable; + function deposits(address, address) external view returns (uint256); + function finalizeBridgeERC20( + address _localToken, + address _remoteToken, + address _from, + address _to, + uint256 _amount, + bytes memory _extraData + ) + external; + function finalizeBridgeETH(address _from, address _to, uint256 _amount, bytes memory _extraData) external payable; + function messenger() external view returns (ICrossDomainMessenger); + function otherBridge() external view returns (IStandardBridge); + function paused() external view returns (bool); +} diff --git a/packages/contracts-bedrock/test/L1/L1ERC721Bridge.t.sol b/packages/contracts-bedrock/test/L1/L1ERC721Bridge.t.sol index ce3d949e333e..f69b73e1fd5e 100644 --- a/packages/contracts-bedrock/test/L1/L1ERC721Bridge.t.sol +++ b/packages/contracts-bedrock/test/L1/L1ERC721Bridge.t.sol @@ -1,18 +1,20 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -// Testing utilities +// Testing import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; -import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; -// Target contract dependencies +// Contracts +import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import { L2ERC721Bridge } from "src/L2/L2ERC721Bridge.sol"; + +// Libraries import { Predeploys } from "src/libraries/Predeploys.sol"; + +// Interfaces import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; - -// Target contract -import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; +import { IL1ERC721Bridge } from "src/L1/interfaces/IL1ERC721Bridge.sol"; /// @dev Test ERC721 contract. contract TestERC721 is ERC721 { @@ -67,7 +69,7 @@ contract L1ERC721Bridge_Test is Bridge_Initializer { /// @notice Marked virtual to be overridden in /// test/kontrol/deployment/DeploymentSummary.t.sol function test_constructor_succeeds() public virtual { - L1ERC721Bridge impl = L1ERC721Bridge(deploy.mustGetAddress("L1ERC721Bridge")); + IL1ERC721Bridge impl = IL1ERC721Bridge(deploy.mustGetAddress("L1ERC721Bridge")); assertEq(address(impl.MESSENGER()), address(0)); assertEq(address(impl.messenger()), address(0)); assertEq(address(impl.OTHER_BRIDGE()), Predeploys.L2_ERC721_BRIDGE); diff --git a/packages/contracts-bedrock/test/L1/L1StandardBridge.t.sol b/packages/contracts-bedrock/test/L1/L1StandardBridge.t.sol index bcba92adf6ba..afc97afd0b43 100644 --- a/packages/contracts-bedrock/test/L1/L1StandardBridge.t.sol +++ b/packages/contracts-bedrock/test/L1/L1StandardBridge.t.sol @@ -1,31 +1,31 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -// Testing utilities +// Testing import { stdStorage, StdStorage } from "forge-std/Test.sol"; -import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; +// Contracts +import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import { StandardBridge } from "src/universal/StandardBridge.sol"; +import { L2StandardBridge } from "src/L2/L2StandardBridge.sol"; + // Libraries import { Predeploys } from "src/libraries/Predeploys.sol"; import { Constants } from "src/libraries/Constants.sol"; +import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; -// Target contract dependencies -import { StandardBridge } from "src/universal/StandardBridge.sol"; -import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; -import { L2StandardBridge } from "src/L2/L2StandardBridge.sol"; +// Interfaces import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; -import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; - -// Target contract import { IOptimismPortal } from "src/L1/interfaces/IOptimismPortal.sol"; +import { IL1StandardBridge } from "src/L1/interfaces/IL1StandardBridge.sol"; contract L1StandardBridge_Getter_Test is Bridge_Initializer { /// @dev Test that the accessors return the correct initialized values. function test_getters_succeeds() external view { assert(l1StandardBridge.l2TokenBridge() == address(l2StandardBridge)); - assert(l1StandardBridge.OTHER_BRIDGE() == l2StandardBridge); + assert(address(l1StandardBridge.OTHER_BRIDGE()) == address(l2StandardBridge)); assert(address(l1StandardBridge.messenger()) == address(l1CrossDomainMessenger)); assert(address(l1StandardBridge.MESSENGER()) == address(l1CrossDomainMessenger)); assert(l1StandardBridge.superchainConfig() == superchainConfig); @@ -38,7 +38,7 @@ contract L1StandardBridge_Initialize_Test is Bridge_Initializer { /// @notice Marked virtual to be overridden in /// test/kontrol/deployment/DeploymentSummary.t.sol function test_constructor_succeeds() external virtual { - L1StandardBridge impl = L1StandardBridge(deploy.mustGetAddress("L1StandardBridge")); + IL1StandardBridge impl = IL1StandardBridge(deploy.mustGetAddress("L1StandardBridge")); assertEq(address(impl.superchainConfig()), address(0)); assertEq(address(impl.MESSENGER()), address(0)); assertEq(address(impl.messenger()), address(0)); diff --git a/packages/contracts-bedrock/test/L1/ProtocolVersions.t.sol b/packages/contracts-bedrock/test/L1/ProtocolVersions.t.sol index 235654d38af6..957d2b914f38 100644 --- a/packages/contracts-bedrock/test/L1/ProtocolVersions.t.sol +++ b/packages/contracts-bedrock/test/L1/ProtocolVersions.t.sol @@ -12,10 +12,10 @@ import { Constants } from "src/libraries/Constants.sol"; import { Proxy } from "src/universal/Proxy.sol"; // Target contract -import { ProtocolVersions, ProtocolVersion } from "src/L1/ProtocolVersions.sol"; +import { IProtocolVersions, ProtocolVersion } from "src/L1/interfaces/IProtocolVersions.sol"; contract ProtocolVersions_Init is CommonTest { - event ConfigUpdate(uint256 indexed version, ProtocolVersions.UpdateType indexed updateType, bytes data); + event ConfigUpdate(uint256 indexed version, IProtocolVersions.UpdateType indexed updateType, bytes data); ProtocolVersion required; ProtocolVersion recommended; @@ -30,7 +30,7 @@ contract ProtocolVersions_Init is CommonTest { contract ProtocolVersions_Initialize_Test is ProtocolVersions_Init { /// @dev Tests that initialization sets the correct values. function test_initialize_values_succeeds() external view { - ProtocolVersions protocolVersionsImpl = ProtocolVersions(deploy.mustGetAddress("ProtocolVersions")); + IProtocolVersions protocolVersionsImpl = IProtocolVersions(deploy.mustGetAddress("ProtocolVersions")); address owner = deploy.cfg().finalSystemOwner(); assertEq(ProtocolVersion.unwrap(protocolVersions.required()), ProtocolVersion.unwrap(required)); @@ -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(deploy.mustGetAddress("ProtocolVersions")); + IProtocolVersions protocolVersionsImpl = IProtocolVersions(deploy.mustGetAddress("ProtocolVersions")); assertEq(protocolVersionsImpl.owner(), address(0xdEad)); // Wipe out the initialized slot so the proxy can be initialized again @@ -52,15 +52,15 @@ contract ProtocolVersions_Initialize_Test is ProtocolVersions_Init { // The order depends here vm.expectEmit(true, true, true, true, address(protocolVersions)); - emit ConfigUpdate(0, ProtocolVersions.UpdateType.REQUIRED_PROTOCOL_VERSION, abi.encode(required)); + emit ConfigUpdate(0, IProtocolVersions.UpdateType.REQUIRED_PROTOCOL_VERSION, abi.encode(required)); vm.expectEmit(true, true, true, true, address(protocolVersions)); - emit ConfigUpdate(0, ProtocolVersions.UpdateType.RECOMMENDED_PROTOCOL_VERSION, abi.encode(recommended)); + emit ConfigUpdate(0, IProtocolVersions.UpdateType.RECOMMENDED_PROTOCOL_VERSION, abi.encode(recommended)); vm.prank(EIP1967Helper.getAdmin(address(protocolVersions))); Proxy(payable(address(protocolVersions))).upgradeToAndCall( address(protocolVersionsImpl), abi.encodeCall( - ProtocolVersions.initialize, + IProtocolVersions.initialize, ( alice, // _owner required, // _required @@ -89,7 +89,7 @@ contract ProtocolVersions_Setters_Test is ProtocolVersions_Init { /// @dev Tests that `setRequired` updates the required protocol version successfully. function testFuzz_setRequired_succeeds(uint256 _version) external { vm.expectEmit(true, true, true, true); - emit ConfigUpdate(0, ProtocolVersions.UpdateType.REQUIRED_PROTOCOL_VERSION, abi.encode(_version)); + emit ConfigUpdate(0, IProtocolVersions.UpdateType.REQUIRED_PROTOCOL_VERSION, abi.encode(_version)); vm.prank(protocolVersions.owner()); protocolVersions.setRequired(ProtocolVersion.wrap(_version)); @@ -99,7 +99,7 @@ contract ProtocolVersions_Setters_Test is ProtocolVersions_Init { /// @dev Tests that `setRecommended` updates the recommended protocol version successfully. function testFuzz_setRecommended_succeeds(uint256 _version) external { vm.expectEmit(true, true, true, true); - emit ConfigUpdate(0, ProtocolVersions.UpdateType.RECOMMENDED_PROTOCOL_VERSION, abi.encode(_version)); + emit ConfigUpdate(0, IProtocolVersions.UpdateType.RECOMMENDED_PROTOCOL_VERSION, abi.encode(_version)); vm.prank(protocolVersions.owner()); protocolVersions.setRecommended(ProtocolVersion.wrap(_version)); diff --git a/packages/contracts-bedrock/test/L1/SystemConfigInterop.t.sol b/packages/contracts-bedrock/test/L1/SystemConfigInterop.t.sol index 191949e29f6f..6cd3c8b3145c 100644 --- a/packages/contracts-bedrock/test/L1/SystemConfigInterop.t.sol +++ b/packages/contracts-bedrock/test/L1/SystemConfigInterop.t.sol @@ -1,20 +1,22 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -// Testing utilities +// Testing import { CommonTest } from "test/setup/CommonTest.sol"; +// Contracts +import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import { ConfigType } from "src/L2/L1BlockIsthmus.sol"; + // Libraries import { Constants } from "src/libraries/Constants.sol"; import { StaticConfig } from "src/libraries/StaticConfig.sol"; import { GasPayingToken } from "src/libraries/GasPayingToken.sol"; -// Target contract dependencies +// Interfaces import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; -import { SystemConfigInterop } from "src/L1/SystemConfigInterop.sol"; +import { ISystemConfigInterop } from "src/L1/interfaces/ISystemConfigInterop.sol"; import { IOptimismPortalInterop } from "src/L1/interfaces/IOptimismPortalInterop.sol"; -import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; -import { ConfigType } from "src/L2/L1BlockIsthmus.sol"; contract SystemConfigInterop_Test is CommonTest { /// @notice Marked virtual to be overridden in @@ -132,7 +134,7 @@ contract SystemConfigInterop_Test is CommonTest { } /// @dev Returns the SystemConfigInterop instance. - function _systemConfigInterop() internal view returns (SystemConfigInterop) { - return SystemConfigInterop(address(systemConfig)); + function _systemConfigInterop() internal view returns (ISystemConfigInterop) { + return ISystemConfigInterop(address(systemConfig)); } } diff --git a/packages/contracts-bedrock/test/L2/L2ERC721Bridge.t.sol b/packages/contracts-bedrock/test/L2/L2ERC721Bridge.t.sol index b7a3e96bc44b..dc7490bd8136 100644 --- a/packages/contracts-bedrock/test/L2/L2ERC721Bridge.t.sol +++ b/packages/contracts-bedrock/test/L2/L2ERC721Bridge.t.sol @@ -1,18 +1,17 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +// Testing import { console } from "forge-std/console.sol"; - -// Testing utilities import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; -// Target contract dependencies +// Contracts import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; -import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; +import { L2ERC721Bridge } from "src/L2/L2ERC721Bridge.sol"; import { OptimismMintableERC721 } from "src/universal/OptimismMintableERC721.sol"; -// Target contract -import { L2ERC721Bridge } from "src/L2/L2ERC721Bridge.sol"; +// Interfaces +import { IL1ERC721Bridge } from "src/L1/interfaces/IL1ERC721Bridge.sol"; contract TestERC721 is ERC721 { constructor() ERC721("Test", "TST") { } @@ -175,7 +174,7 @@ contract L2ERC721Bridge_Test is Bridge_Initializer { ( address(l1ERC721Bridge), abi.encodeCall( - L1ERC721Bridge.finalizeBridgeERC721, + IL1ERC721Bridge.finalizeBridgeERC721, (address(remoteToken), address(localToken), alice, bob, tokenId, hex"5678") ), 1234 diff --git a/packages/contracts-bedrock/test/Specs.t.sol b/packages/contracts-bedrock/test/Specs.t.sol index d8b918acf8bc..419ffa69ece3 100644 --- a/packages/contracts-bedrock/test/Specs.t.sol +++ b/packages/contracts-bedrock/test/Specs.t.sol @@ -10,7 +10,6 @@ import { Executables } from "scripts/libraries/Executables.sol"; import { ForgeArtifacts, Abi, AbiEntry } from "scripts/libraries/ForgeArtifacts.sol"; // Contracts -import { ProtocolVersions } from "src/L1/ProtocolVersions.sol"; import { OPStackManager } from "src/L1/OPStackManager.sol"; // Interfaces @@ -19,6 +18,7 @@ import { IOptimismPortal2 } from "src/L1/interfaces/IOptimismPortal2.sol"; import { IOptimismPortalInterop } from "src/L1/interfaces/IOptimismPortalInterop.sol"; import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; import { IDataAvailabilityChallenge } from "src/L1/interfaces/IDataAvailabilityChallenge.sol"; +import { IProtocolVersions } from "src/L1/interfaces/IProtocolVersions.sol"; /// @title Specification_Test /// @dev Specifies common security properties of entrypoints to L1 contracts, including authorization and @@ -394,19 +394,19 @@ contract Specification_Test is CommonTest { _addSpec({ _name: "ProtocolVersions", _sel: _getSel("RECOMMENDED_SLOT()") }); _addSpec({ _name: "ProtocolVersions", _sel: _getSel("REQUIRED_SLOT()") }); _addSpec({ _name: "ProtocolVersions", _sel: _getSel("VERSION()") }); - _addSpec({ _name: "ProtocolVersions", _sel: ProtocolVersions.initialize.selector }); + _addSpec({ _name: "ProtocolVersions", _sel: IProtocolVersions.initialize.selector }); _addSpec({ _name: "ProtocolVersions", _sel: _getSel("owner()") }); - _addSpec({ _name: "ProtocolVersions", _sel: ProtocolVersions.recommended.selector }); + _addSpec({ _name: "ProtocolVersions", _sel: IProtocolVersions.recommended.selector }); _addSpec({ _name: "ProtocolVersions", _sel: _getSel("renounceOwnership()"), _auth: Role.SYSTEMCONFIGOWNER }); - _addSpec({ _name: "ProtocolVersions", _sel: ProtocolVersions.required.selector }); + _addSpec({ _name: "ProtocolVersions", _sel: IProtocolVersions.required.selector }); _addSpec({ _name: "ProtocolVersions", - _sel: ProtocolVersions.setRequired.selector, + _sel: IProtocolVersions.setRequired.selector, _auth: Role.SYSTEMCONFIGOWNER }); _addSpec({ _name: "ProtocolVersions", - _sel: ProtocolVersions.setRecommended.selector, + _sel: IProtocolVersions.setRecommended.selector, _auth: Role.SYSTEMCONFIGOWNER }); _addSpec({ _name: "ProtocolVersions", _sel: _getSel("transferOwnership(address)") }); diff --git a/packages/contracts-bedrock/test/setup/Setup.sol b/packages/contracts-bedrock/test/setup/Setup.sol index 0d8db00009cb..5bfd5328144c 100644 --- a/packages/contracts-bedrock/test/setup/Setup.sol +++ b/packages/contracts-bedrock/test/setup/Setup.sol @@ -25,19 +25,13 @@ import { GasPriceOracle } from "src/L2/GasPriceOracle.sol"; import { L1Block } from "src/L2/L1Block.sol"; import { LegacyMessagePasser } from "src/legacy/LegacyMessagePasser.sol"; import { GovernanceToken } from "src/governance/GovernanceToken.sol"; -import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; -import { StandardBridge } from "src/universal/StandardBridge.sol"; import { FeeVault } from "src/universal/FeeVault.sol"; -import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; -import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; -import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; -import { ProtocolVersions } from "src/L1/ProtocolVersions.sol"; -import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; -import { AddressManager } from "src/legacy/AddressManager.sol"; import { WETH } from "src/L2/WETH.sol"; import { SuperchainWETH } from "src/L2/SuperchainWETH.sol"; import { ETHLiquidity } from "src/L2/ETHLiquidity.sol"; -import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; +import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; +import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; +import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; // Libraries import { Predeploys } from "src/libraries/Predeploys.sol"; @@ -52,6 +46,11 @@ import { IL2OutputOracle } from "src/L1/interfaces/IL2OutputOracle.sol"; import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; import { IDataAvailabilityChallenge } from "src/L1/interfaces/IDataAvailabilityChallenge.sol"; +import { IL1StandardBridge } from "src/L1/interfaces/IL1StandardBridge.sol"; +import { IProtocolVersions } from "src/L1/interfaces/IProtocolVersions.sol"; +import { IL1ERC721Bridge } from "src/L1/interfaces/IL1ERC721Bridge.sol"; +import { IOptimismMintableERC20Factory } from "src/universal/interfaces/IOptimismMintableERC20Factory.sol"; +import { IAddressManager } from "src/legacy/interfaces/IAddressManager.sol"; /// @title Setup /// @dev This contact is responsible for setting up the contracts in state. It currently @@ -74,28 +73,30 @@ contract Setup { // @notice Allows users of Setup to override what L2 genesis is being created. Fork l2Fork = LATEST_FORK; - IOptimismPortal optimismPortal; - IOptimismPortal2 optimismPortal2; + // L1 contracts DisputeGameFactory disputeGameFactory; + AnchorStateRegistry anchorStateRegistry; DelayedWETH delayedWeth; + IOptimismPortal optimismPortal; + IOptimismPortal2 optimismPortal2; IL2OutputOracle l2OutputOracle; ISystemConfig systemConfig; - L1StandardBridge l1StandardBridge; + IL1StandardBridge l1StandardBridge; IL1CrossDomainMessenger l1CrossDomainMessenger; - AddressManager addressManager; - L1ERC721Bridge l1ERC721Bridge; - OptimismMintableERC20Factory l1OptimismMintableERC20Factory; - ProtocolVersions protocolVersions; + IAddressManager addressManager; + IL1ERC721Bridge l1ERC721Bridge; + IOptimismMintableERC20Factory l1OptimismMintableERC20Factory; + IProtocolVersions protocolVersions; ISuperchainConfig superchainConfig; IDataAvailabilityChallenge dataAvailabilityChallenge; - AnchorStateRegistry anchorStateRegistry; + // L2 contracts L2CrossDomainMessenger l2CrossDomainMessenger = L2CrossDomainMessenger(payable(Predeploys.L2_CROSS_DOMAIN_MESSENGER)); L2StandardBridgeInterop l2StandardBridge = L2StandardBridgeInterop(payable(Predeploys.L2_STANDARD_BRIDGE)); L2ToL1MessagePasser l2ToL1MessagePasser = L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)); - OptimismMintableERC20Factory l2OptimismMintableERC20Factory = - OptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY); + IOptimismMintableERC20Factory l2OptimismMintableERC20Factory = + IOptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY); L2ERC721Bridge l2ERC721Bridge = L2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE); BaseFeeVault baseFeeVault = BaseFeeVault(payable(Predeploys.BASE_FEE_VAULT)); SequencerFeeVault sequencerFeeVault = SequencerFeeVault(payable(Predeploys.SEQUENCER_FEE_WALLET)); @@ -146,13 +147,13 @@ contract Setup { delayedWeth = DelayedWETH(deploy.mustGetAddress("DelayedWETHProxy")); l2OutputOracle = IL2OutputOracle(deploy.mustGetAddress("L2OutputOracleProxy")); systemConfig = ISystemConfig(deploy.mustGetAddress("SystemConfigProxy")); - l1StandardBridge = L1StandardBridge(deploy.mustGetAddress("L1StandardBridgeProxy")); + l1StandardBridge = IL1StandardBridge(deploy.mustGetAddress("L1StandardBridgeProxy")); l1CrossDomainMessenger = IL1CrossDomainMessenger(deploy.mustGetAddress("L1CrossDomainMessengerProxy")); - addressManager = AddressManager(deploy.mustGetAddress("AddressManager")); - l1ERC721Bridge = L1ERC721Bridge(deploy.mustGetAddress("L1ERC721BridgeProxy")); + addressManager = IAddressManager(deploy.mustGetAddress("AddressManager")); + l1ERC721Bridge = IL1ERC721Bridge(deploy.mustGetAddress("L1ERC721BridgeProxy")); l1OptimismMintableERC20Factory = - OptimismMintableERC20Factory(deploy.mustGetAddress("OptimismMintableERC20FactoryProxy")); - protocolVersions = ProtocolVersions(deploy.mustGetAddress("ProtocolVersionsProxy")); + IOptimismMintableERC20Factory(deploy.mustGetAddress("OptimismMintableERC20FactoryProxy")); + protocolVersions = IProtocolVersions(deploy.mustGetAddress("ProtocolVersionsProxy")); superchainConfig = ISuperchainConfig(deploy.mustGetAddress("SuperchainConfigProxy")); anchorStateRegistry = AnchorStateRegistry(deploy.mustGetAddress("AnchorStateRegistryProxy")); diff --git a/packages/contracts-bedrock/test/universal/OptimismMintableERC20Factory.t.sol b/packages/contracts-bedrock/test/universal/OptimismMintableERC20Factory.t.sol index 85dc4e0d3e9b..07aa2c61958d 100644 --- a/packages/contracts-bedrock/test/universal/OptimismMintableERC20Factory.t.sol +++ b/packages/contracts-bedrock/test/universal/OptimismMintableERC20Factory.t.sol @@ -1,17 +1,18 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -// Testing utilities +// Testing import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; import { NextImpl } from "test/mocks/NextImpl.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; -// Target contract dependencies +// Contracts import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; +import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; import { Proxy } from "src/universal/Proxy.sol"; -// Target contract -import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; +// Interfaces +import { IOptimismMintableERC20Factory } from "src/universal/interfaces/IOptimismMintableERC20Factory.sol"; contract OptimismMintableTokenFactory_Test is Bridge_Initializer { event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken); @@ -19,7 +20,7 @@ contract OptimismMintableTokenFactory_Test is Bridge_Initializer { /// @notice Tests that the constructor is initialized correctly. function test_constructor_succeeds() external { - OptimismMintableERC20Factory impl = new OptimismMintableERC20Factory(); + IOptimismMintableERC20Factory impl = IOptimismMintableERC20Factory(address(new OptimismMintableERC20Factory())); assertEq(address(impl.BRIDGE()), address(0)); assertEq(address(impl.bridge()), address(0)); } diff --git a/packages/contracts-bedrock/test/vendor/Initializable.t.sol b/packages/contracts-bedrock/test/vendor/Initializable.t.sol index 52566f95ec1b..df9231a27627 100644 --- a/packages/contracts-bedrock/test/vendor/Initializable.t.sol +++ b/packages/contracts-bedrock/test/vendor/Initializable.t.sol @@ -7,9 +7,9 @@ import { Executables } from "scripts/libraries/Executables.sol"; import { Constants } from "src/libraries/Constants.sol"; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; +import { StandardBridge } from "src/universal/StandardBridge.sol"; import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; -import { SystemConfigInterop } from "src/L1/SystemConfigInterop.sol"; import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; @@ -17,7 +17,7 @@ import { PermissionedDisputeGame } from "src/dispute/PermissionedDisputeGame.sol import { GameTypes } from "src/dispute/lib/Types.sol"; import { ForgeArtifacts, StorageSlot } from "scripts/libraries/ForgeArtifacts.sol"; import { Process } from "scripts/libraries/Process.sol"; -import "src/L1/ProtocolVersions.sol"; +import { ProtocolVersion } from "src/L1/interfaces/IProtocolVersions.sol"; import "src/dispute/lib/Types.sol"; import "scripts/deploy/Deployer.sol"; @@ -296,7 +296,7 @@ contract Initializer_Test is Bridge_Initializer { InitializeableContract({ name: "L2StandardBridge", target: address(l2StandardBridge), - initCalldata: abi.encodeCall(l2StandardBridge.initialize, (l1StandardBridge)) + initCalldata: abi.encodeCall(l2StandardBridge.initialize, (StandardBridge(payable(l1StandardBridge)))) }) ); // L2StandardBridgeInterop @@ -304,7 +304,7 @@ contract Initializer_Test is Bridge_Initializer { InitializeableContract({ name: "L2StandardBridgeInterop", target: address(l2StandardBridge), - initCalldata: abi.encodeCall(l2StandardBridge.initialize, (l1StandardBridge)) + initCalldata: abi.encodeCall(l2StandardBridge.initialize, (StandardBridge(payable(l1StandardBridge)))) }) ); // L1ERC721BridgeImpl