129 lines
4.9 KiB
Solidity
129 lines
4.9 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity ^0.8.18;
|
|
|
|
import { MiniMeBase } from "@vacp2p/minime/contracts/MiniMeBase.sol";
|
|
import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
|
|
import { ILegacyMintableERC20, IOptimismMintableERC20 } from "./IOptimismMintableERC20.sol";
|
|
import { Semver } from "./Semver.sol";
|
|
|
|
/// @title OptimismMintableMiniMeToken
|
|
/// @notice OptimismMintableMiniMeToken is a standard extension of the base MiniMeToken token contract designed
|
|
/// to allow the StandardBridge contracts to mint and burn tokens. This makes it possible to
|
|
/// use an OptimismMintablERC20 as the L2 representation of an L1 token, or vice-versa.
|
|
/// Designed to be backwards compatible with the older StandardL2ERC20 token which was only
|
|
/// meant for use on L2.
|
|
contract OptimismMintableMiniMeToken is IOptimismMintableERC20, ILegacyMintableERC20, MiniMeBase, Semver {
|
|
/// @notice Error that is thrown if the sender is not the bridge.
|
|
error OptimismMintableMiniMeToken_SenderNotBridge();
|
|
|
|
/// @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() {
|
|
if (msg.sender != BRIDGE) revert OptimismMintableMiniMeToken_SenderNotBridge();
|
|
_;
|
|
}
|
|
|
|
/// @custom:semver 1.0.1
|
|
/// @param _bridge Address of the L2 standard bridge.
|
|
/// @param _remoteToken Address of the corresponding L1 token.
|
|
/// @param _tokenName ERC20 name.
|
|
/// @param _tokenSymbol ERC20 symbol.
|
|
constructor(
|
|
address _bridge,
|
|
address _remoteToken,
|
|
MiniMeBase _parentToken,
|
|
uint256 _parentSnapShotBlock,
|
|
string memory _tokenName,
|
|
uint8 _decimalUnits,
|
|
string memory _tokenSymbol,
|
|
bool _transfersEnabled
|
|
)
|
|
MiniMeBase(_parentToken, _parentSnapShotBlock, _tokenName, _decimalUnits, _tokenSymbol, _transfersEnabled)
|
|
Semver(1, 0, 1)
|
|
{
|
|
REMOTE_TOKEN = _remoteToken;
|
|
BRIDGE = _bridge;
|
|
}
|
|
|
|
/// @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
|
|
override(IOptimismMintableERC20, ILegacyMintableERC20)
|
|
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
|
|
override(IOptimismMintableERC20, ILegacyMintableERC20)
|
|
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 returns (bool) {
|
|
bytes4 iface1 = type(IERC165).interfaceId;
|
|
// Interface corresponding to the legacy L2StandardERC20.
|
|
bytes4 iface2 = type(ILegacyMintableERC20).interfaceId;
|
|
// Interface corresponding to the updated OptimismMintableMiniMeToken (this contract).
|
|
bytes4 iface3 = type(IOptimismMintableERC20).interfaceId;
|
|
return _interfaceId == iface1 || _interfaceId == iface2 || _interfaceId == iface3;
|
|
}
|
|
|
|
/// @custom:legacy
|
|
/// @notice Legacy getter for the remote token. Use REMOTE_TOKEN going forward.
|
|
function l1Token() public view returns (address) {
|
|
return REMOTE_TOKEN;
|
|
}
|
|
|
|
/// @custom:legacy
|
|
/// @notice Legacy getter for the bridge. Use BRIDGE going forward.
|
|
function l2Bridge() public view returns (address) {
|
|
return BRIDGE;
|
|
}
|
|
|
|
/// @custom:legacy
|
|
/// @notice Legacy getter for REMOTE_TOKEN.
|
|
function remoteToken() public view returns (address) {
|
|
return REMOTE_TOKEN;
|
|
}
|
|
|
|
/// @custom:legacy
|
|
/// @notice Legacy getter for BRIDGE.
|
|
function bridge() public view returns (address) {
|
|
return BRIDGE;
|
|
}
|
|
}
|