// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; import "./AbstractToken.sol"; import "@eth-optimism/contracts-bedrock/contracts/universal/IOptimismMintableERC20.sol"; contract L2Token is AbstractToken, IOptimismMintableERC20 { /// @notice Address of the corresponding version of this token on the remote chain. address public immutable REMOTE_TOKEN; /// @notice Address of the StandardBridge on this network. address public immutable BRIDGE; /// @notice Emitted whenever tokens are minted for an account. /// @param account Address of the account tokens are being minted for. /// @param amount Amount of tokens minted. event Mint(address indexed account, uint256 amount); /// @notice Emitted whenever tokens are burned from an account. /// @param account Address of the account tokens are being burned from. /// @param amount Amount of tokens burned. event Burn(address indexed account, uint256 amount); /// @notice A modifier that only allows the bridge to call modifier onlyBridge() { require(_msgSender() == BRIDGE, "OptimismMintableERC20: only bridge can mint and burn"); _; } constructor(string memory _name, string memory _symbol, address _bridge, address _remoteToken) AbstractToken(_name, _symbol) { BRIDGE = _bridge; REMOTE_TOKEN = _remoteToken; } function balanceOf(address account) public view virtual override(AbstractToken) returns (uint256) { return AbstractToken.balanceOf(account); } function transferFrom(address sender, address recipient, uint256 amount) public virtual override(AbstractToken) returns (bool) { return AbstractToken.transferFrom(sender, recipient, amount); } /// @notice Allows the StandardBridge on this network 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 override(IOptimismMintableERC20) onlyBridge { _mint(_to, _amount); emit Mint(_to, _amount); } /// @notice Allows the StandardBridge on this network 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 override(IOptimismMintableERC20) onlyBridge { _burn(_from, _amount); emit Burn(_from, _amount); } /// @notice ERC165 interface check function. /// @param _interfaceId Interface ID to check. /// @return Whether or not the interface is supported by this contract. function supportsInterface(bytes4 _interfaceId) public pure virtual override(AbstractToken, IERC165) returns (bool) { bytes4 iface1 = type(IERC165).interfaceId; // Interface corresponding to the legacy L2StandardERC20. bytes4 iface2 = type(ILegacyMintableERC20).interfaceId; // Interface corresponding to the updated OptimismMintableERC20 (this contract). bytes4 iface3 = type(IOptimismMintableERC20).interfaceId; return _interfaceId == iface1 || _interfaceId == iface2 || _interfaceId == iface3; } /// @custom:legacy /// @notice Legacy getter for REMOTE_TOKEN. // Is this needed? function remoteToken() public view virtual override(IOptimismMintableERC20) returns (address) { return REMOTE_TOKEN; } /// @custom:legacy /// @notice Legacy getter for BRIDGE. // Is this needed? function bridge() public view virtual override(IOptimismMintableERC20) returns (address) { return BRIDGE; } /// @custom:legacy /// @notice Legacy getter for the remote token. Use REMOTE_TOKEN going forward. function l1Token() public virtual view returns (address) { return REMOTE_TOKEN; } /// @custom:legacy /// @notice Legacy getter for the bridge. Use BRIDGE going forward. function l2Bridge() public virtual view returns (address) { return BRIDGE; } }