github.com/ethereum-optimism/optimism@v1.7.2/packages/contracts-bedrock/src/universal/OptimismMintableERC20.sol (about)

     1  // SPDX-License-Identifier: MIT
     2  pragma solidity 0.8.15;
     3  
     4  import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
     5  import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
     6  import { ILegacyMintableERC20, IOptimismMintableERC20 } from "src/universal/IOptimismMintableERC20.sol";
     7  import { ISemver } from "src/universal/ISemver.sol";
     8  
     9  /// @title OptimismMintableERC20
    10  /// @notice OptimismMintableERC20 is a standard extension of the base ERC20 token contract designed
    11  ///         to allow the StandardBridge contracts to mint and burn tokens. This makes it possible to
    12  ///         use an OptimismMintablERC20 as the L2 representation of an L1 token, or vice-versa.
    13  ///         Designed to be backwards compatible with the older StandardL2ERC20 token which was only
    14  ///         meant for use on L2.
    15  contract OptimismMintableERC20 is IOptimismMintableERC20, ILegacyMintableERC20, ERC20, ISemver {
    16      /// @notice Address of the corresponding version of this token on the remote chain.
    17      address public immutable REMOTE_TOKEN;
    18  
    19      /// @notice Address of the StandardBridge on this network.
    20      address public immutable BRIDGE;
    21  
    22      /// @notice Decimals of the token
    23      uint8 private immutable DECIMALS;
    24  
    25      /// @notice Emitted whenever tokens are minted for an account.
    26      /// @param account Address of the account tokens are being minted for.
    27      /// @param amount  Amount of tokens minted.
    28      event Mint(address indexed account, uint256 amount);
    29  
    30      /// @notice Emitted whenever tokens are burned from an account.
    31      /// @param account Address of the account tokens are being burned from.
    32      /// @param amount  Amount of tokens burned.
    33      event Burn(address indexed account, uint256 amount);
    34  
    35      /// @notice A modifier that only allows the bridge to call
    36      modifier onlyBridge() {
    37          require(msg.sender == BRIDGE, "OptimismMintableERC20: only bridge can mint and burn");
    38          _;
    39      }
    40  
    41      /// @notice Semantic version.
    42      /// @custom:semver 1.3.0
    43      string public constant version = "1.3.0";
    44  
    45      /// @param _bridge      Address of the L2 standard bridge.
    46      /// @param _remoteToken Address of the corresponding L1 token.
    47      /// @param _name        ERC20 name.
    48      /// @param _symbol      ERC20 symbol.
    49      constructor(
    50          address _bridge,
    51          address _remoteToken,
    52          string memory _name,
    53          string memory _symbol,
    54          uint8 _decimals
    55      )
    56          ERC20(_name, _symbol)
    57      {
    58          REMOTE_TOKEN = _remoteToken;
    59          BRIDGE = _bridge;
    60          DECIMALS = _decimals;
    61      }
    62  
    63      /// @notice Allows the StandardBridge on this network to mint tokens.
    64      /// @param _to     Address to mint tokens to.
    65      /// @param _amount Amount of tokens to mint.
    66      function mint(
    67          address _to,
    68          uint256 _amount
    69      )
    70          external
    71          virtual
    72          override(IOptimismMintableERC20, ILegacyMintableERC20)
    73          onlyBridge
    74      {
    75          _mint(_to, _amount);
    76          emit Mint(_to, _amount);
    77      }
    78  
    79      /// @notice Allows the StandardBridge on this network to burn tokens.
    80      /// @param _from   Address to burn tokens from.
    81      /// @param _amount Amount of tokens to burn.
    82      function burn(
    83          address _from,
    84          uint256 _amount
    85      )
    86          external
    87          virtual
    88          override(IOptimismMintableERC20, ILegacyMintableERC20)
    89          onlyBridge
    90      {
    91          _burn(_from, _amount);
    92          emit Burn(_from, _amount);
    93      }
    94  
    95      /// @notice ERC165 interface check function.
    96      /// @param _interfaceId Interface ID to check.
    97      /// @return Whether or not the interface is supported by this contract.
    98      function supportsInterface(bytes4 _interfaceId) external pure virtual returns (bool) {
    99          bytes4 iface1 = type(IERC165).interfaceId;
   100          // Interface corresponding to the legacy L2StandardERC20.
   101          bytes4 iface2 = type(ILegacyMintableERC20).interfaceId;
   102          // Interface corresponding to the updated OptimismMintableERC20 (this contract).
   103          bytes4 iface3 = type(IOptimismMintableERC20).interfaceId;
   104          return _interfaceId == iface1 || _interfaceId == iface2 || _interfaceId == iface3;
   105      }
   106  
   107      /// @custom:legacy
   108      /// @notice Legacy getter for the remote token. Use REMOTE_TOKEN going forward.
   109      function l1Token() public view returns (address) {
   110          return REMOTE_TOKEN;
   111      }
   112  
   113      /// @custom:legacy
   114      /// @notice Legacy getter for the bridge. Use BRIDGE going forward.
   115      function l2Bridge() public view returns (address) {
   116          return BRIDGE;
   117      }
   118  
   119      /// @custom:legacy
   120      /// @notice Legacy getter for REMOTE_TOKEN.
   121      function remoteToken() public view returns (address) {
   122          return REMOTE_TOKEN;
   123      }
   124  
   125      /// @custom:legacy
   126      /// @notice Legacy getter for BRIDGE.
   127      function bridge() public view returns (address) {
   128          return BRIDGE;
   129      }
   130  
   131      /// @dev Returns the number of decimals used to get its user representation.
   132      /// For example, if `decimals` equals `2`, a balance of `505` tokens should
   133      /// be displayed to a user as `5.05` (`505 / 10 ** 2`).
   134      /// NOTE: This information is only used for _display_ purposes: it in
   135      /// no way affects any of the arithmetic of the contract, including
   136      /// {IERC20-balanceOf} and {IERC20-transfer}.
   137      function decimals() public view override returns (uint8) {
   138          return DECIMALS;
   139      }
   140  }