diff --git a/packages/contracts-bedrock/src/L2/L2StandardBridgeInterop.sol b/packages/contracts-bedrock/src/L2/L2StandardBridgeInterop.sol index 3383bd0d2733..f01a66dacc47 100644 --- a/packages/contracts-bedrock/src/L2/L2StandardBridgeInterop.sol +++ b/packages/contracts-bedrock/src/L2/L2StandardBridgeInterop.sol @@ -30,7 +30,7 @@ error InvalidTokenPair(); /// @title L2StandardBridgeInterop /// @notice The L2StandardBridgeInterop is an extension of the L2StandardBridge that allows for /// the conversion of tokens between legacy tokens (OptimismMintableERC20 or StandardL2ERC20) -/// and SuperchainERC20 tokens. +/// and OptimismSuperchainERC20 tokens. contract L2StandardBridgeInterop is L2StandardBridge { /// @notice Emitted when a conversion is made. /// @param from The token being converted from. @@ -40,9 +40,9 @@ contract L2StandardBridgeInterop is L2StandardBridge { event Converted(address indexed from, address indexed to, address indexed caller, uint256 amount); /// @notice Semantic version. - /// @custom:semver +interop-beta.2 + /// @custom:semver +interop-beta.1 function version() public pure override returns (string memory) { - return string.concat(super.version(), "+interop-beta.2"); + return string.concat(super.version(), "+interop-beta.1"); } /// @notice Converts `amount` of `from` token to `to` token. @@ -52,8 +52,8 @@ contract L2StandardBridgeInterop is L2StandardBridge { function convert(address _from, address _to, uint256 _amount) external { _validatePair(_from, _to); - IMintableAndBurnableERC20(_from).mint(msg.sender, _amount); - IMintableAndBurnableERC20(_to).burn(msg.sender, _amount); + IMintableAndBurnableERC20(_from).burn(msg.sender, _amount); + IMintableAndBurnableERC20(_to).mint(msg.sender, _amount); emit Converted(_from, _to, msg.sender, _amount); } @@ -75,14 +75,14 @@ contract L2StandardBridgeInterop is L2StandardBridge { /// @notice Validates that the tokens are deployed by the correct factory. /// @param _legacyAddr The legacy token address (OptimismMintableERC20 or StandardL2ERC20). - /// @param _superAddr The SuperchainERC20 address. + /// @param _superAddr The OptimismSuperchainERC20 address. function _validateFactories(address _legacyAddr, address _superAddr) internal view { // 2. Valid legacy check address _legacyRemoteToken = IOptimismERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY).deployments(_legacyAddr); if (_legacyRemoteToken == address(0)) revert InvalidLegacyERC20Address(); - // 3. Valid SuperchainERC20 check + // 3. Valid OptimismSuperchainERC20 check address _superRemoteToken = IOptimismERC20Factory(Predeploys.OPTIMISM_SUPERCHAIN_ERC20_FACTORY).deployments(_superAddr); if (_superRemoteToken == address(0)) revert InvalidSuperchainERC20Address(); diff --git a/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20.sol b/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20.sol index 93f7e18664f5..193c900b8bbd 100644 --- a/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20.sol +++ b/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20.sol @@ -1,10 +1,12 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.25; -import { Predeploys } from "src/libraries/Predeploys.sol"; -import { SuperchainERC20 } from "src/L2/SuperchainERC20.sol"; import { IOptimismSuperchainERC20Extension } from "src/L2/interfaces/IOptimismSuperchainERC20.sol"; +import { IL2ToL2CrossDomainMessenger } from "src/L2/interfaces/IL2ToL2CrossDomainMessenger.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; import { ERC165 } from "@openzeppelin/contracts-v5/utils/introspection/ERC165.sol"; +import { SuperchainERC20 } from "src/L2/SuperchainERC20.sol"; import { Initializable } from "@openzeppelin/contracts-v5/proxy/utils/Initializable.sol"; /// @custom:proxied true @@ -16,14 +18,14 @@ import { Initializable } from "@openzeppelin/contracts-v5/proxy/utils/Initializa /// also enables the inverse conversion path. /// Moreover, it builds on top of the L2ToL2CrossDomainMessenger for both replay protection and domain binding. contract OptimismSuperchainERC20 is SuperchainERC20, Initializable, ERC165, IOptimismSuperchainERC20Extension { - /// @notice Storage slot that the SuperchainERC20Metadata struct is stored at. - /// keccak256(abi.encode(uint256(keccak256("SuperchainERC20.metadata")) - 1)) & ~bytes32(uint256(0xff)); + /// @notice Storage slot that the OptimismSuperchainERC20Metadata struct is stored at. + /// keccak256(abi.encode(uint256(keccak256("optimismSuperchainERC20.metadata")) - 1)) & ~bytes32(uint256(0xff)); bytes32 internal constant OPTIMISM_SUPERCHAIN_ERC20_METADATA_SLOT = 0x07f04e84143df95a6373fcf376312ae41da81a193a3089073a54f47a74d8fb00; - /// @notice Storage struct for the SuperchainERC20 metadata. - /// @custom:storage-location erc7201:SuperchainERC20.metadata - struct SuperchainERC20Metadata { + /// @notice Storage struct for the OptimismSuperchainERC20 metadata. + /// @custom:storage-location erc7201:optimismSuperchainERC20.metadata + struct OptimismSuperchainERC20Metadata { /// @notice Address of the corresponding version of this token on the remote chain. address remoteToken; /// @notice Name of the token @@ -34,18 +36,30 @@ contract OptimismSuperchainERC20 is SuperchainERC20, Initializable, ERC165, IOpt uint8 decimals; } - /// @notice Constructs the SuperchainERC20 contract. - constructor() { - _disableInitializers(); - } - - /// @notice Returns the storage for the SuperchainERC20Metadata. - function _getStorage() internal pure returns (SuperchainERC20Metadata storage _storage) { + /// @notice Returns the storage for the OptimismSuperchainERC20Metadata. + function _getStorage() private pure returns (OptimismSuperchainERC20Metadata storage _storage) { assembly { _storage.slot := OPTIMISM_SUPERCHAIN_ERC20_METADATA_SLOT } } + /// @notice A modifier that only allows the L2StandardBridge to call + modifier onlyL2StandardBridge() { + if (msg.sender != Predeploys.L2_STANDARD_BRIDGE) { + revert OnlyL2StandardBridge(); + } + _; + } + + /// @notice Semantic version. + /// @custom:semver 1.0.0-beta.6 + string public constant override version = "1.0.0-beta.6"; + + /// @notice Constructs the OptimismSuperchainERC20 contract. + constructor() { + _disableInitializers(); + } + /// @notice Initializes the contract. /// @param _remoteToken Address of the corresponding remote token. /// @param _name ERC20 name. @@ -60,23 +74,14 @@ contract OptimismSuperchainERC20 is SuperchainERC20, Initializable, ERC165, IOpt external initializer { - SuperchainERC20Metadata storage _storage = _getStorage(); + OptimismSuperchainERC20Metadata storage _storage = _getStorage(); _storage.remoteToken = _remoteToken; _storage.name = _name; _storage.symbol = _symbol; _storage.decimals = _decimals; } - /// @notice Semantic version. - /// @custom:semver 1.0.0-beta - string public constant override version = "1.0.0-beta"; - - modifier onlyL2StandardBridge() { - if (msg.sender != Predeploys.L2_STANDARD_BRIDGE) revert OnlyL2StandardBridge(); - _; - } - - /// @notice Allows the L2StandardBridge and SuperchainERC20Bridge to mint tokens. + /// @notice Allows the L2StandardBridge to mint tokens. /// @param _to Address to mint tokens to. /// @param _amount Amount of tokens to mint. function mint(address _to, uint256 _amount) external virtual onlyL2StandardBridge { @@ -87,7 +92,7 @@ contract OptimismSuperchainERC20 is SuperchainERC20, Initializable, ERC165, IOpt emit Mint(_to, _amount); } - /// @notice Allows the L2StandardBridge and SuperchainERC20Bridge to burn tokens. + /// @notice Allows the L2StandardBridge to burn tokens. /// @param _from Address to burn tokens from. /// @param _amount Amount of tokens to burn. function burn(address _from, uint256 _amount) external virtual onlyL2StandardBridge { diff --git a/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20Beacon.sol b/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20Beacon.sol index 6935793a4765..d1160819a2ec 100644 --- a/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20Beacon.sol +++ b/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20Beacon.sol @@ -7,9 +7,9 @@ import { ISemver } from "src/universal/interfaces/ISemver.sol"; /// @custom:proxied /// @custom:predeployed 0x4200000000000000000000000000000000000027 /// @title OptimismSuperchainERC20Beacon -/// @notice OptimismSuperchainERC20Beacon is the beacon proxy for the SuperchainERC20 implementation. +/// @notice OptimismSuperchainERC20Beacon is the beacon proxy for the OptimismSuperchainERC20 implementation. contract OptimismSuperchainERC20Beacon is IBeacon, ISemver { - /// @notice Address of the SuperchainERC20 implementation. + /// @notice Address of the OptimismSuperchainERC20 implementation. address internal immutable IMPLEMENTATION; /// @notice Semantic version. diff --git a/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20Factory.sol b/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20Factory.sol index f34d06d8505d..8e61dca87b76 100644 --- a/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20Factory.sol +++ b/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20Factory.sol @@ -11,15 +11,15 @@ import { CREATE3 } from "@rari-capital/solmate/src/utils/CREATE3.sol"; /// @custom:proxied /// @custom:predeployed 0x4200000000000000000000000000000000000026 /// @title OptimismSuperchainERC20Factory -/// @notice OptimismSuperchainERC20Factory is a factory contract that deploys SuperchainERC20 Beacon Proxies +/// @notice OptimismSuperchainERC20Factory is a factory contract that deploys OptimismSuperchainERC20 Beacon Proxies /// using CREATE3. contract OptimismSuperchainERC20Factory is IOptimismSuperchainERC20Factory, ISemver { - /// @notice Mapping of the deployed SuperchainERC20 to the remote token address. + /// @notice Mapping of the deployed OptimismSuperchainERC20 to the remote token address. /// This is used to keep track of the token deployments. mapping(address superchainToken => address remoteToken) public deployments; - /// @notice Emitted when an SuperchainERC20 is deployed. - /// @param superchainToken Address of the SuperchainERC20 deployment. + /// @notice Emitted when an OptimismSuperchainERC20 is deployed. + /// @param superchainToken Address of the OptimismSuperchainERC20 deployment. /// @param remoteToken Address of the corresponding token on the remote chain. /// @param deployer Address of the account that deployed the token. event OptimismSuperchainERC20Created( @@ -30,12 +30,12 @@ contract OptimismSuperchainERC20Factory is IOptimismSuperchainERC20Factory, ISem /// @custom:semver 1.0.0-beta.3 string public constant version = "1.0.0-beta.3"; - /// @notice Deploys a SuperchainERC20 Beacon Proxy using CREATE3. + /// @notice Deploys a OptimismSuperchainERC20 Beacon Proxy using CREATE3. /// @param _remoteToken Address of the remote token. - /// @param _name Name of the SuperchainERC20. - /// @param _symbol Symbol of the SuperchainERC20. - /// @param _decimals Decimals of the SuperchainERC20. - /// @return _superchainERC20 Address of the SuperchainERC20 deployment. + /// @param _name Name of the OptimismSuperchainERC20. + /// @param _symbol Symbol of the OptimismSuperchainERC20. + /// @param _decimals Decimals of the OptimismSuperchainERC20. + /// @return _superchainERC20 Address of the OptimismSuperchainERC20 deployment. function deploy( address _remoteToken, string memory _name, diff --git a/packages/contracts-bedrock/src/L2/SuperchainERC20.sol b/packages/contracts-bedrock/src/L2/SuperchainERC20.sol index 9661e3406bde..c67cb8240621 100644 --- a/packages/contracts-bedrock/src/L2/SuperchainERC20.sol +++ b/packages/contracts-bedrock/src/L2/SuperchainERC20.sol @@ -8,22 +8,19 @@ import { ERC20 } from "@solady/tokens/ERC20.sol"; /// @title SuperchainERC20 /// @notice SuperchainERC20 is a standard extension of the base ERC20 token contract that unifies ERC20 token -/// bridging to make it fungible across the Superchain. This construction allows the L2StandardBridge to burn -/// and mint tokens. This makes it possible to convert a valid OptimismMintableERC20 token to a -/// SuperchainERC20 token, turning it fungible and interoperable across the superchain. Likewise, it -/// also enables the inverse conversion path. -/// Moreover, it builds on top of the L2ToL2CrossDomainMessenger for both replay protection and domain binding. +/// bridging to make it fungible across the Superchain. This construction allows the SuperchainERC20Bridge to +/// burn and mint tokens. abstract contract SuperchainERC20 is ERC20, ISuperchainERC20Extension, ISemver { - /// @notice A modifier that only allows the bridge to call + /// @notice A modifier that only allows the SuperchainERC20Bridge to call modifier onlySuperchainERC20Bridge() { if (msg.sender != Predeploys.SUPERCHAIN_ERC20_BRIDGE) revert OnlySuperchainERC20Bridge(); _; } /// @notice Semantic version. - /// @custom:semver 1.0.0-beta.6 + /// @custom:semver 1.0.0-beta.1 function version() external pure virtual returns (string memory) { - return "1.0.0-beta.6"; + return "1.0.0-beta.1"; } /// @notice Allows the SuperchainERC20Bridge to mint tokens. diff --git a/packages/contracts-bedrock/src/L2/interfaces/IOptimismSuperchainERC20Factory.sol b/packages/contracts-bedrock/src/L2/interfaces/IOptimismSuperchainERC20Factory.sol index 9934a6dee877..aa23405fa527 100644 --- a/packages/contracts-bedrock/src/L2/interfaces/IOptimismSuperchainERC20Factory.sol +++ b/packages/contracts-bedrock/src/L2/interfaces/IOptimismSuperchainERC20Factory.sol @@ -6,12 +6,12 @@ import { IOptimismERC20Factory } from "./IOptimismERC20Factory.sol"; /// @title IOptimismSuperchainERC20Factory /// @notice Interface for OptimismSuperchainERC20Factory. interface IOptimismSuperchainERC20Factory is IOptimismERC20Factory { - /// @notice Deploys a SuperchainERC20 Beacon Proxy using CREATE3. + /// @notice Deploys a OptimismSuperchainERC20 Beacon Proxy using CREATE3. /// @param _remoteToken Address of the remote token. - /// @param _name Name of the SuperchainERC20. - /// @param _symbol Symbol of the SuperchainERC20. - /// @param _decimals Decimals of the SuperchainERC20. - /// @return _superchainERC20 Address of the SuperchainERC20 deployment. + /// @param _name Name of the OptimismSuperchainERC20. + /// @param _symbol Symbol of the OptimismSuperchainERC20. + /// @param _decimals Decimals of the OptimismSuperchainERC20. + /// @return _superchainERC20 Address of the OptimismSuperchainERC20 deployment. function deploy( address _remoteToken, string memory _name, diff --git a/packages/contracts-bedrock/src/libraries/Predeploys.sol b/packages/contracts-bedrock/src/libraries/Predeploys.sol index 891ab78c648f..5bc1d75a1f06 100644 --- a/packages/contracts-bedrock/src/libraries/Predeploys.sol +++ b/packages/contracts-bedrock/src/libraries/Predeploys.sol @@ -102,7 +102,7 @@ library Predeploys { address internal constant OPTIMISM_SUPERCHAIN_ERC20_BEACON = 0x4200000000000000000000000000000000000027; // TODO: Precalculate the address of the implementation contract - /// @notice Arbitrary address of the SuperchainERC20 implementation contract. + /// @notice Arbitrary address of the OptimismSuperchainERC20 implementation contract. address internal constant OPTIMISM_SUPERCHAIN_ERC20 = 0xB9415c6cA93bdC545D4c5177512FCC22EFa38F28; /// @notice Address of the SuperchainERC20Bridge predeploy. diff --git a/packages/contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol b/packages/contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol index dce9ba3774d5..96f4ad4ba61f 100644 --- a/packages/contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol +++ b/packages/contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol @@ -58,9 +58,9 @@ contract L2StandardBridgeInterop_Test is Bridge_Initializer { } } -/// @notice Test suite when converting from a legacy token to a SuperchainERC20 token +/// @notice Test suite when converting from a legacy token to a OptimismSuperchainERC20 token contract L2StandardBridgeInterop_LegacyToSuper_Test is L2StandardBridgeInterop_Test { - /// @notice Set up the test for converting from a legacy token to a SuperchainERC20 token + /// @notice Set up the test for converting from a legacy token to a OptimismSuperchainERC20 token function _setUpLegacyToSuper(address _from, address _to) internal { // Assume _assumeAddress(_from); @@ -215,9 +215,9 @@ contract L2StandardBridgeInterop_LegacyToSuper_Test is L2StandardBridgeInterop_T } } -/// @notice Test suite when converting from a SuperchainERC20 token to a legacy token +/// @notice Test suite when converting from a OptimismSuperchainERC20 token to a legacy token contract L2StandardBridgeInterop_SuperToLegacy_Test is L2StandardBridgeInterop_Test { - /// @notice Set up the test for converting from a SuperchainERC20 token to a legacy token + /// @notice Set up the test for converting from a OptimismSuperchainERC20 token to a legacy token function _setUpSuperToLegacy(address _from, address _to) internal { // Assume _assumeAddress(_from);