github.com/ethereum-optimism/optimism@v1.7.2/packages/contracts-bedrock/test/universal/OptimismMintableERC20.t.sol (about) 1 // SPDX-License-Identifier: MIT 2 pragma solidity 0.8.15; 3 4 import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; 5 import { ILegacyMintableERC20, IOptimismMintableERC20 } from "src/universal/IOptimismMintableERC20.sol"; 6 import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; 7 8 contract OptimismMintableERC20_Test is Bridge_Initializer { 9 event Mint(address indexed account, uint256 amount); 10 event Burn(address indexed account, uint256 amount); 11 12 function test_remoteToken_succeeds() external { 13 assertEq(L2Token.remoteToken(), address(L1Token)); 14 } 15 16 function test_bridge_succeeds() external { 17 assertEq(L2Token.bridge(), address(l2StandardBridge)); 18 } 19 20 function test_l1Token_succeeds() external { 21 assertEq(L2Token.l1Token(), address(L1Token)); 22 } 23 24 function test_l2Bridge_succeeds() external { 25 assertEq(L2Token.l2Bridge(), address(l2StandardBridge)); 26 } 27 28 function test_legacy_succeeds() external { 29 // Getters for the remote token 30 assertEq(L2Token.REMOTE_TOKEN(), address(L1Token)); 31 assertEq(L2Token.remoteToken(), address(L1Token)); 32 assertEq(L2Token.l1Token(), address(L1Token)); 33 // Getters for the bridge 34 assertEq(L2Token.BRIDGE(), address(l2StandardBridge)); 35 assertEq(L2Token.bridge(), address(l2StandardBridge)); 36 assertEq(L2Token.l2Bridge(), address(l2StandardBridge)); 37 } 38 39 function test_mint_succeeds() external { 40 vm.expectEmit(true, true, true, true); 41 emit Mint(alice, 100); 42 43 vm.prank(address(l2StandardBridge)); 44 L2Token.mint(alice, 100); 45 46 assertEq(L2Token.balanceOf(alice), 100); 47 } 48 49 function test_mint_notBridge_reverts() external { 50 // NOT the bridge 51 vm.expectRevert("OptimismMintableERC20: only bridge can mint and burn"); 52 vm.prank(address(alice)); 53 L2Token.mint(alice, 100); 54 } 55 56 function test_burn_succeeds() external { 57 vm.prank(address(l2StandardBridge)); 58 L2Token.mint(alice, 100); 59 60 vm.expectEmit(true, true, true, true); 61 emit Burn(alice, 100); 62 63 vm.prank(address(l2StandardBridge)); 64 L2Token.burn(alice, 100); 65 66 assertEq(L2Token.balanceOf(alice), 0); 67 } 68 69 function test_burn_notBridge_reverts() external { 70 // NOT the bridge 71 vm.expectRevert("OptimismMintableERC20: only bridge can mint and burn"); 72 vm.prank(address(alice)); 73 L2Token.burn(alice, 100); 74 } 75 76 function test_erc165_supportsInterface_succeeds() external { 77 // The assertEq calls in this test are comparing the manual calculation of the iface, 78 // with what is returned by the solidity's type().interfaceId, just to be safe. 79 bytes4 iface1 = bytes4(keccak256("supportsInterface(bytes4)")); 80 assertEq(iface1, type(IERC165).interfaceId); 81 assert(L2Token.supportsInterface(iface1)); 82 83 bytes4 iface2 = L2Token.l1Token.selector ^ L2Token.mint.selector ^ L2Token.burn.selector; 84 assertEq(iface2, type(ILegacyMintableERC20).interfaceId); 85 assert(L2Token.supportsInterface(iface2)); 86 87 bytes4 iface3 = 88 L2Token.remoteToken.selector ^ L2Token.bridge.selector ^ L2Token.mint.selector ^ L2Token.burn.selector; 89 assertEq(iface3, type(IOptimismMintableERC20).interfaceId); 90 assert(L2Token.supportsInterface(iface3)); 91 } 92 }