-
Notifications
You must be signed in to change notification settings - Fork 74
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add example of how to make existing ERC20 compatible with super…
…chain interop
- Loading branch information
1 parent
0d36a50
commit 6925d7b
Showing
2 changed files
with
166 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
79 changes: 79 additions & 0 deletions
79
packages/contracts/src/examples/L2NativeInteroperableGovernanceToken.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.15; | ||
|
||
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; | ||
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; | ||
import { ERC20Burnable } from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol"; | ||
import { ERC20Votes, ERC20Permit } from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol"; | ||
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; | ||
import { IERC7802, IERC165 } from "@contracts-bedrock/L2/interfaces/IERC7802.sol"; | ||
import { Predeploys } from "@contracts-bedrock/libraries/Predeploys.sol"; | ||
import { Unauthorized } from "@contracts-bedrock/libraries/errors/CommonErrors.sol"; | ||
|
||
contract GovernanceToken is IERC7802, ERC20Burnable, ERC20Votes, Ownable { | ||
/// @notice Constructs the GovernanceToken contract. | ||
constructor() ERC20("Optimism", "OP") ERC20Permit("Optimism") { } | ||
|
||
/// @notice Allows the owner to mint tokens. | ||
/// @param _account The account receiving minted tokens. | ||
/// @param _amount The amount of tokens to mint. | ||
function mint(address _account, uint256 _amount) public onlyOwner { | ||
_mint(_account, _amount); | ||
} | ||
|
||
/// @notice Callback called after a token transfer. | ||
/// @param from The account sending tokens. | ||
/// @param to The account receiving tokens. | ||
/// @param amount The amount of tokens being transfered. | ||
function _afterTokenTransfer(address from, address to, uint256 amount) internal override(ERC20, ERC20Votes) { | ||
super._afterTokenTransfer(from, to, amount); | ||
} | ||
|
||
/// @notice Internal mint function. | ||
/// @param to The account receiving minted tokens. | ||
/// @param amount The amount of tokens to mint. | ||
function _mint(address to, uint256 amount) internal override(ERC20, ERC20Votes) { | ||
super._mint(to, amount); | ||
} | ||
|
||
/// @notice Internal burn function. | ||
/// @param account The account that tokens will be burned from. | ||
/// @param amount The amount of tokens that will be burned. | ||
function _burn(address account, uint256 amount) internal override(ERC20, ERC20Votes) { | ||
super._burn(account, amount); | ||
} | ||
|
||
/// @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 { | ||
// Only the `SuperchainTokenBridge` has permissions to mint tokens during crosschain transfers. | ||
if (msg.sender != Predeploys.SUPERCHAIN_TOKEN_BRIDGE) revert Unauthorized(); | ||
|
||
// Mint tokens to the `_to` account's balance. | ||
_mint(_to, _amount); | ||
|
||
// Emit the CrosschainMint event included on IERC7802 for tracking token mints associated with cross chain transfers. | ||
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 { | ||
// Only the `SuperchainTokenBridge` has permissions to burn tokens during crosschain transfers. | ||
if (msg.sender != Predeploys.SUPERCHAIN_TOKEN_BRIDGE) revert Unauthorized(); | ||
|
||
// Burn the tokens from the `_from` account's balance. | ||
_burn(_from, _amount); | ||
|
||
// Emit the CrosschainBurn event included on IERC7802 for tracking token burns associated with cross chain transfers. | ||
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; | ||
} | ||
} |