From e1c9d49816e34cf2fe64bebc1773c19ca401d86d Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Sat, 23 Nov 2024 09:26:44 +0100 Subject: [PATCH 1/2] add LegacyMintableERC20 tests --- .../interfaces/ILegacyMintableERC20.sol | 13 +++- .../test/legacy/LegacyMintableERC20.t.sol | 78 +++++++++++++++++++ 2 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 packages/contracts-bedrock/test/legacy/LegacyMintableERC20.t.sol diff --git a/packages/contracts-bedrock/src/universal/interfaces/ILegacyMintableERC20.sol b/packages/contracts-bedrock/src/universal/interfaces/ILegacyMintableERC20.sol index ad518b8b4d7..9c190145d42 100644 --- a/packages/contracts-bedrock/src/universal/interfaces/ILegacyMintableERC20.sol +++ b/packages/contracts-bedrock/src/universal/interfaces/ILegacyMintableERC20.sol @@ -2,16 +2,27 @@ pragma solidity ^0.8.0; import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; +import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; /// @custom:legacy /// @title ILegacyMintableERC20 /// @notice This interface was available on the legacy L2StandardERC20 contract. /// It remains available on the OptimismMintableERC20 contract for /// backwards compatibility. -interface ILegacyMintableERC20 is IERC165 { +interface ILegacyMintableERC20 is IERC165, IERC20Metadata { function l1Token() external view returns (address); function mint(address _to, uint256 _amount) external; function burn(address _from, uint256 _amount) external; + + function l2Bridge() external view returns (address); + + function __constructor__( + address _l2Bridge, + address _l1Token, + string memory _name, + string memory _symbol + ) + external; } diff --git a/packages/contracts-bedrock/test/legacy/LegacyMintableERC20.t.sol b/packages/contracts-bedrock/test/legacy/LegacyMintableERC20.t.sol new file mode 100644 index 00000000000..4d741f96e52 --- /dev/null +++ b/packages/contracts-bedrock/test/legacy/LegacyMintableERC20.t.sol @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +// Testing utilities +import { CommonTest } from "test/setup/CommonTest.sol"; + +import { ILegacyMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; +import { DeployUtils } from "scripts/libraries/DeployUtils.sol"; + +contract LegacyMintableERC20_Test is CommonTest { + ILegacyMintableERC20 legacyMintableERC20; + + function setUp() public override { + super.setUp(); + + legacyMintableERC20 = ILegacyMintableERC20( + DeployUtils.create1({ + _name: "LegacyMintableERC20", + _args: DeployUtils.encodeConstructor( + abi.encodeCall( + ILegacyMintableERC20.__constructor__, + (address(l2StandardBridge), address(L1Token), "_L2Token_", "_L2T_") + ) + ) + }) + ); + } + + /// @notice Tests that the constructor sets the correct values + function test_constructor_works() public view { + assertEq(legacyMintableERC20.l2Bridge(), address(l2StandardBridge)); + assertEq(legacyMintableERC20.l1Token(), address(L1Token)); + assertEq(legacyMintableERC20.name(), "_L2Token_"); + assertEq(legacyMintableERC20.symbol(), "_L2T_"); + assertEq(legacyMintableERC20.decimals(), 18); + } + + /// @notice Tests that the contract supports the correct interfaces + function test_supportsInterface_works() public view { + assertEq(legacyMintableERC20.supportsInterface(bytes4(keccak256("supportsInterface(bytes4)"))), true); + assertEq( + legacyMintableERC20.supportsInterface( + ILegacyMintableERC20.l1Token.selector ^ ILegacyMintableERC20.mint.selector + ^ ILegacyMintableERC20.burn.selector + ), + true + ); + } + + /// @notice Tests that the mint function works when called by the bridge + function test_mint_byBridge_works() public { + vm.prank(address(l2StandardBridge)); + legacyMintableERC20.mint(address(this), 1000); + assertEq(legacyMintableERC20.balanceOf(address(this)), 1000); + } + + /// @notice Tests that the mint function fails when called by an address other than the bridge + function test_mint_byNonBridge_fails() public { + vm.expectRevert(bytes("Only L2 Bridge can mint and burn")); + legacyMintableERC20.mint(address(this), 1000); + } + + /// @notice Tests that the burn function works when called by the bridge + function test_burn_byBridge_works() public { + vm.prank(address(l2StandardBridge)); + legacyMintableERC20.mint(address(this), 1000); + + vm.prank(address(l2StandardBridge)); + legacyMintableERC20.burn(address(this), 1000); + assertEq(legacyMintableERC20.balanceOf(address(this)), 0); + } + + /// @notice Tests that the burn function fails when called by an address other than the bridge + function test_burn_byNonBridge_fails() public { + vm.expectRevert(bytes("Only L2 Bridge can mint and burn")); + legacyMintableERC20.burn(address(this), 1000); + } +} From e24953d14704c61e88704b2f54cd24ab4a459125 Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Sat, 23 Nov 2024 09:41:30 +0100 Subject: [PATCH 2/2] fixes --- .../interfaces/ILegacyMintableERC20.sol | 13 +--------- .../test/legacy/LegacyMintableERC20.t.sol | 26 ++++++------------- 2 files changed, 9 insertions(+), 30 deletions(-) diff --git a/packages/contracts-bedrock/src/universal/interfaces/ILegacyMintableERC20.sol b/packages/contracts-bedrock/src/universal/interfaces/ILegacyMintableERC20.sol index 9c190145d42..ad518b8b4d7 100644 --- a/packages/contracts-bedrock/src/universal/interfaces/ILegacyMintableERC20.sol +++ b/packages/contracts-bedrock/src/universal/interfaces/ILegacyMintableERC20.sol @@ -2,27 +2,16 @@ pragma solidity ^0.8.0; import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; -import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; /// @custom:legacy /// @title ILegacyMintableERC20 /// @notice This interface was available on the legacy L2StandardERC20 contract. /// It remains available on the OptimismMintableERC20 contract for /// backwards compatibility. -interface ILegacyMintableERC20 is IERC165, IERC20Metadata { +interface ILegacyMintableERC20 is IERC165 { function l1Token() external view returns (address); function mint(address _to, uint256 _amount) external; function burn(address _from, uint256 _amount) external; - - function l2Bridge() external view returns (address); - - function __constructor__( - address _l2Bridge, - address _l1Token, - string memory _name, - string memory _symbol - ) - external; } diff --git a/packages/contracts-bedrock/test/legacy/LegacyMintableERC20.t.sol b/packages/contracts-bedrock/test/legacy/LegacyMintableERC20.t.sol index 4d741f96e52..061b6eee6c5 100644 --- a/packages/contracts-bedrock/test/legacy/LegacyMintableERC20.t.sol +++ b/packages/contracts-bedrock/test/legacy/LegacyMintableERC20.t.sol @@ -4,26 +4,16 @@ pragma solidity 0.8.15; // Testing utilities import { CommonTest } from "test/setup/CommonTest.sol"; -import { ILegacyMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; -import { DeployUtils } from "scripts/libraries/DeployUtils.sol"; +import { LegacyMintableERC20 } from "src/legacy/LegacyMintableERC20.sol"; +import { ILegacyMintableERC20 } from "src/universal/interfaces/ILegacyMintableERC20.sol"; contract LegacyMintableERC20_Test is CommonTest { - ILegacyMintableERC20 legacyMintableERC20; + LegacyMintableERC20 legacyMintableERC20; function setUp() public override { super.setUp(); - legacyMintableERC20 = ILegacyMintableERC20( - DeployUtils.create1({ - _name: "LegacyMintableERC20", - _args: DeployUtils.encodeConstructor( - abi.encodeCall( - ILegacyMintableERC20.__constructor__, - (address(l2StandardBridge), address(L1Token), "_L2Token_", "_L2T_") - ) - ) - }) - ); + legacyMintableERC20 = new LegacyMintableERC20(address(l2StandardBridge), address(L1Token), "_L2Token_", "_L2T_"); } /// @notice Tests that the constructor sets the correct values @@ -48,20 +38,20 @@ contract LegacyMintableERC20_Test is CommonTest { } /// @notice Tests that the mint function works when called by the bridge - function test_mint_byBridge_works() public { + function test_mint_byBridge_succeeds() public { vm.prank(address(l2StandardBridge)); legacyMintableERC20.mint(address(this), 1000); assertEq(legacyMintableERC20.balanceOf(address(this)), 1000); } /// @notice Tests that the mint function fails when called by an address other than the bridge - function test_mint_byNonBridge_fails() public { + function test_mint_byNonBridge_reverts() public { vm.expectRevert(bytes("Only L2 Bridge can mint and burn")); legacyMintableERC20.mint(address(this), 1000); } /// @notice Tests that the burn function works when called by the bridge - function test_burn_byBridge_works() public { + function test_burn_byBridge_succeeds() public { vm.prank(address(l2StandardBridge)); legacyMintableERC20.mint(address(this), 1000); @@ -71,7 +61,7 @@ contract LegacyMintableERC20_Test is CommonTest { } /// @notice Tests that the burn function fails when called by an address other than the bridge - function test_burn_byNonBridge_fails() public { + function test_burn_byNonBridge_reverts() public { vm.expectRevert(bytes("Only L2 Bridge can mint and burn")); legacyMintableERC20.burn(address(this), 1000); }