ERC20 Tokens with Zircuit Canonical Bridge
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
interface IOptimismMintableERC20 is IERC165 {
function remoteToken() external view returns (address);
function bridge() external returns (address);
function mint(address _to, uint256 _amount) external;
function burn(address _from, uint256 _amount) external;
}
contract MyZircuitERC20 is IOptimismMintableERC20, ERC20 {
/// @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 Decimals of the token
uint8 private immutable DECIMALS;
/// @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(msg.sender == BRIDGE, "Only bridge can mint and burn");
_;
}
/// @param _bridge Address of the L2 standard bridge.
/// @param _remoteToken Address of the corresponding L1 token.
/// @param _name ERC20 name.
/// @param _symbol ERC20 symbol.
constructor(
address _bridge,
address _remoteToken,
string memory _name,
string memory _symbol,
uint8 _decimals
)
ERC20(_name, _symbol)
{
REMOTE_TOKEN = _remoteToken;
BRIDGE = _bridge;
DECIMALS = _decimals;
}
/// @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) external pure virtual returns (bool) {
bytes4 iface1 = type(IERC165).interfaceId;
// Interface corresponding to the updated OptimismMintableERC20 (this contract).
bytes4 iface3 = type(IOptimismMintableERC20).interfaceId;
return _interfaceId == iface1 || _interfaceId == iface3;
}
/// @notice Getter for the remote token. Legacy, also use REMOTE_TOKEN
function l1Token() public view returns (address) {
return REMOTE_TOKEN;
}
/// @notice Getter for the bridge. Legacy, also use BRIDGE
function l2Bridge() public view returns (address) {
return BRIDGE;
}
/// @notice Getter for the remote token. Legacy, also use REMOTE_TOKEN
function remoteToken() public view returns (address) {
return REMOTE_TOKEN;
}
/// @notice Getter for the bridge. Legacy, also use BRIDGE.
function bridge() public view returns (address) {
return BRIDGE;
}
/// @dev Returns the number of decimals used to get its user representation.
/// For example, if `decimals` equals `2`, a balance of `505` tokens should
/// be displayed to a user as `5.05` (`505 / 10 ** 2`).
/// NOTE: This information is only used for _display_ purposes: it in
/// no way affects any of the arithmetic of the contract, including
/// {IERC20-balanceOf} and {IERC20-transfer}.
function decimals() public view override returns (uint8) {
return DECIMALS;
}
}Last updated
Was this helpful?