// SPDX-License-Identifier: MIT pragma solidity ^0.8.25; // Contracts import { ERC20 } from "@solady-v0.0.245/tokens/ERC20.sol"; // Libraries import { PredeployAddresses } from "./libraries/PredeployAddresses.sol"; import { Unauthorized } from "./libraries/errors/CommonErrors.sol"; // Interfaces import { IERC20 } from "@openzeppelin-contracts/interfaces/IERC20.sol"; import { ISemver } from "./interfaces/ISemver.sol"; import { IERC7802, IERC165 } from "./interfaces/IERC7802.sol"; /// @title SuperchainERC20 /// @notice A standard ERC20 extension implementing IERC7802 for unified cross-chain fungibility /// across the Superchain. Gives the SuperchainTokenBridge mint and burn permissions. /// @dev This contract inherits from Solady@v0.0.245 ERC20. Carefully review Solady's, /// documentation including all warnings, comments and natSpec, before extending or /// interacting with this contract. abstract contract SuperchainERC20 is ERC20, IERC7802, ISemver { /// @notice Semantic version. /// @custom:semver 1.0.2 function version() external view virtual returns (string memory) { return "1.0.2"; } /// @notice Allows the SuperchainTokenBridge to mint tokens. /// @param _to Address to mint tokens to. /// @param _amount Amount of tokens to mint. function crosschainMint(address _to, uint256 _amount) external { if (msg.sender != PredeployAddresses.SUPERCHAIN_TOKEN_BRIDGE) revert Unauthorized(); _mint(_to, _amount); emit CrosschainMint(_to, _amount, msg.sender); } /// @notice Allows the SuperchainTokenBridge to burn tokens. /// @param _from Address to burn tokens from. /// @param _amount Amount of tokens to burn. function crosschainBurn(address _from, uint256 _amount) external { if (msg.sender != PredeployAddresses.SUPERCHAIN_TOKEN_BRIDGE) revert Unauthorized(); _burn(_from, _amount); emit CrosschainBurn(_from, _amount, msg.sender); } /// @inheritdoc IERC165 function supportsInterface(bytes4 _interfaceId) public view virtual returns (bool) { return _interfaceId == type(IERC7802).interfaceId || _interfaceId == type(IERC20).interfaceId || _interfaceId == type(IERC165).interfaceId; } }