diff --git a/packages/contracts-bedrock/src/L2/IOptimismERC20Factory.sol b/packages/contracts-bedrock/src/L2/IOptimismERC20Factory.sol new file mode 100644 index 000000000000..0286a8f7b34e --- /dev/null +++ b/packages/contracts-bedrock/src/L2/IOptimismERC20Factory.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/// @title IOptimismERC20Factory +/// @notice Generic interface for IOptimismMintableERC20Factory and ISuperchainERC20Factory. Used to +/// determine if a ERC20 contract is deployed by a factory. +interface IOptimismERC20Factory { + /// @notice Checks if a ERC20 token is deployed by the factory. + /// @param _token The address of the ERC20 token to check the deployment. + /// @return _remoteToken The address of the remote token if it is deployed or `address(0)` if not. + function deployments(address _token) external view returns (address _remoteToken); +} diff --git a/packages/contracts-bedrock/src/L2/L2StandardBridgeInterop.sol b/packages/contracts-bedrock/src/L2/L2StandardBridgeInterop.sol index 13059150e366..75f7f854b401 100644 --- a/packages/contracts-bedrock/src/L2/L2StandardBridgeInterop.sol +++ b/packages/contracts-bedrock/src/L2/L2StandardBridgeInterop.sol @@ -5,6 +5,7 @@ import { Predeploys } from "src/libraries/Predeploys.sol"; import { L2StandardBridge } from "src/L2/L2StandardBridge.sol"; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; +import { IOptimismERC20Factory } from "src/L2/IOptimismERC20Factory.sol"; /// @notice Thrown when the decimals of the tokens are not the same. error InvalidDecimals(); @@ -18,16 +19,6 @@ error InvalidSuperchainAddress(); /// @notice Thrown when the remote addresses of the tokens are not the same. error InvalidTokenPair(); -// TODO: Use OptimismMintableERC20Factory contract instead of interface -interface IOptimismMintableERC20Factory { - function deployments(address) external view returns (address); -} - -// TODO: Move to a separate file -interface ISuperchainERC20Factory { - function deployments(address) external view returns (address); -} - // TODO: Use an existing interface with `mint` and `burn`? interface MintableAndBurnable is IERC20 { function mint(address, uint256) external; @@ -82,12 +73,12 @@ contract L2StandardBridgeInterop is L2StandardBridge { function _validateFactories(address _legacyAddr, address _superAddr) internal view { // 2. Valid legacy check address _legacyRemoteToken = - IOptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY).deployments(_legacyAddr); + IOptimismERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY).deployments(_legacyAddr); if (_legacyRemoteToken == address(0)) revert InvalidLegacyAddress(); // 3. Valid SuperchainERC20 check address _superRemoteToken = - ISuperchainERC20Factory(Predeploys.OPTIMISM_SUPERCHAIN_ERC20_FACTORY).deployments(_superAddr); + IOptimismERC20Factory(Predeploys.OPTIMISM_SUPERCHAIN_ERC20_FACTORY).deployments(_superAddr); if (_superRemoteToken == address(0)) revert InvalidSuperchainAddress(); // 4. Same remote address check diff --git a/packages/contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol b/packages/contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol index a9966f12d55e..db065764eab3 100644 --- a/packages/contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol +++ b/packages/contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol @@ -12,7 +12,7 @@ import { InvalidLegacyAddress, InvalidSuperchainAddress, InvalidTokenPair, - IOptimismMintableERC20Factory, + IOptimismERC20Factory, MintableAndBurnable } from "src/L2/L2StandardBridgeInterop.sol"; import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; @@ -47,9 +47,7 @@ contract L2StandardBridgeInterop_Test is Bridge_Initializer { /// @notice Mock factory deployment function _mockDeployments(address _factory, address _token, address _deployed) internal { _mockAndExpect( - _factory, - abi.encodeWithSelector(IOptimismMintableERC20Factory.deployments.selector, _token), - abi.encode(_deployed) + _factory, abi.encodeWithSelector(IOptimismERC20Factory.deployments.selector, _token), abi.encode(_deployed) ); } }