Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 49 additions & 19 deletions packages/contracts-bedrock/test/legacy/LegacyMintableERC20.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import { ILegacyMintableERC20 } from "interfaces/legacy/ILegacyMintableERC20.sol
abstract contract LegacyMintableERC20_TestInit is CommonTest {
LegacyMintableERC20 legacyMintableERC20;

event Mint(address indexed account, uint256 amount);
event Burn(address indexed account, uint256 amount);

function setUp() public override {
super.setUp();

Expand All @@ -22,8 +25,8 @@ abstract contract LegacyMintableERC20_TestInit is CommonTest {
/// @title LegacyMintableERC20_Constructor_Test
/// @notice Tests the constructor of the `LegacyMintableERC20` contract.
contract LegacyMintableERC20_Constructor_Test is LegacyMintableERC20_TestInit {
/// @notice Tests that the constructor sets the correct values
function test_constructor_works() public view {
/// @notice Tests that the constructor sets the correct values.
function test_constructor_succeeds() public view {
assertEq(legacyMintableERC20.l2Bridge(), address(l2StandardBridge));
assertEq(legacyMintableERC20.l1Token(), address(L1Token));
assertEq(legacyMintableERC20.name(), "_L2Token_");
Expand All @@ -35,8 +38,8 @@ contract LegacyMintableERC20_Constructor_Test is LegacyMintableERC20_TestInit {
/// @title LegacyMintableERC20_SupportsInterface_Test
/// @notice Tests the `supportsInterface` function of the `LegacyMintableERC20` contract.
contract LegacyMintableERC20_SupportsInterface_Test is LegacyMintableERC20_TestInit {
/// @notice Tests that the contract supports the correct interfaces
function test_supportsInterface_works() public view {
/// @notice Tests that the contract supports the correct interfaces.
function test_supportsInterface_supportedInterfaces_succeeds() public view {
assertEq(legacyMintableERC20.supportsInterface(bytes4(keccak256("supportsInterface(bytes4)"))), true);
assertEq(
legacyMintableERC20.supportsInterface(
Expand All @@ -46,41 +49,68 @@ contract LegacyMintableERC20_SupportsInterface_Test is LegacyMintableERC20_TestI
true
);
}

/// @notice Tests that the contract returns false for unsupported interfaces.
function testFuzz_supportsInterface_unsupportedInterface_succeeds(bytes4 _interfaceId) public view {
bytes4 erc165Interface = bytes4(keccak256("supportsInterface(bytes4)"));
bytes4 legacyInterface = ILegacyMintableERC20.l1Token.selector ^ ILegacyMintableERC20.mint.selector
^ ILegacyMintableERC20.burn.selector;
vm.assume(_interfaceId != erc165Interface && _interfaceId != legacyInterface);
assertEq(legacyMintableERC20.supportsInterface(_interfaceId), false);
}
}

/// @title LegacyMintableERC20_Mint_Test
/// @notice Tests the `mint` function of the `LegacyMintableERC20` contract.
contract LegacyMintableERC20_Mint_Test is LegacyMintableERC20_TestInit {
/// @notice Tests that the mint function works when called by the bridge
function test_mint_byBridge_succeeds() public {
/// @notice Tests that the mint function works when called by the bridge.
function testFuzz_mint_byBridge_succeeds(address _to, uint256 _amount) public {
vm.assume(_to != address(0));

vm.expectEmit(true, true, true, true);
emit Mint(_to, _amount);

vm.prank(address(l2StandardBridge));
legacyMintableERC20.mint(address(this), 1000);
assertEq(legacyMintableERC20.balanceOf(address(this)), 1000);
legacyMintableERC20.mint(_to, _amount);

assertEq(legacyMintableERC20.balanceOf(_to), _amount);
}

/// @notice Tests that the mint function fails when called by an address other than the bridge
function test_mint_byNonBridge_reverts() public {
/// @notice Tests that the mint function reverts when called by a non-bridge address.
function testFuzz_mint_byNonBridge_reverts(address _caller, address _to, uint256 _amount) public {
vm.assume(_caller != address(l2StandardBridge));

vm.prank(_caller);
vm.expectRevert(bytes("Only L2 Bridge can mint and burn"));
legacyMintableERC20.mint(address(this), 1000);
legacyMintableERC20.mint(_to, _amount);
}
}

/// @title LegacyMintableERC20_Burn_Test
/// @notice Tests the `burn` function of the `LegacyMintableERC20` contract.
contract LegacyMintableERC20_Burn_Test is LegacyMintableERC20_TestInit {
/// @notice Tests that the burn function works when called by the bridge
function test_burn_byBridge_succeeds() public {
/// @notice Tests that the burn function works when called by the bridge.
function testFuzz_burn_byBridge_succeeds(address _from, uint256 _amount) public {
vm.assume(_from != address(0));

vm.prank(address(l2StandardBridge));
legacyMintableERC20.mint(address(this), 1000);
legacyMintableERC20.mint(_from, _amount);

vm.expectEmit(true, true, true, true);
emit Burn(_from, _amount);

vm.prank(address(l2StandardBridge));
legacyMintableERC20.burn(address(this), 1000);
assertEq(legacyMintableERC20.balanceOf(address(this)), 0);
legacyMintableERC20.burn(_from, _amount);

assertEq(legacyMintableERC20.balanceOf(_from), 0);
}

/// @notice Tests that the burn function fails when called by an address other than the bridge
function test_burn_byNonBridge_reverts() public {
/// @notice Tests that the burn function reverts when called by a non-bridge address.
function testFuzz_burn_byNonBridge_reverts(address _caller, address _from, uint256 _amount) public {
vm.assume(_caller != address(l2StandardBridge));

vm.prank(_caller);
vm.expectRevert(bytes("Only L2 Bridge can mint and burn"));
legacyMintableERC20.burn(address(this), 1000);
legacyMintableERC20.burn(_from, _amount);
}
}