diff --git a/packages/contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol b/packages/contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol index 091f7b35d61c..db065764eab3 100644 --- a/packages/contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol +++ b/packages/contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol @@ -26,28 +26,35 @@ contract L2StandardBridgeInterop_Test is Bridge_Initializer { /// @notice Emitted when a conversion is made. event Converted(address indexed from, address indexed to, address indexed caller, uint256 amount); + /// @notice Helper function to setup a mock and expect a call to it. + function _mockAndExpect(address _receiver, bytes memory _calldata, bytes memory _returned) internal { + vm.mockCall(_receiver, _calldata, _returned); + vm.expectCall(_receiver, _calldata); + } + /// @notice Mock ERC20 decimals function _mockDecimals(address _token, uint8 _decimals) internal { - vm.mockCall(_token, abi.encodeWithSelector(IERC20Metadata.decimals.selector), abi.encode(_decimals)); + _mockAndExpect(_token, abi.encodeWithSelector(IERC20Metadata.decimals.selector), abi.encode(_decimals)); } /// @notice Mock ERC165 interface function _mockInterface(address _token, bytes4 _interfaceId, bool _supported) internal { - vm.mockCall( + _mockAndExpect( _token, abi.encodeWithSelector(IERC165.supportsInterface.selector, _interfaceId), abi.encode(_supported) ); } /// @notice Mock factory deployment function _mockDeployments(address _factory, address _token, address _deployed) internal { - vm.mockCall( + _mockAndExpect( _factory, abi.encodeWithSelector(IOptimismERC20Factory.deployments.selector, _token), abi.encode(_deployed) ); } } -/// @notice Test when converting from a legacy token to a SuperchainERC20 token +/// @notice Test suite when converting from a legacy token to a SuperchainERC20 token contract L2StandardBridgeInterop_LegacyToSuper_Test is L2StandardBridgeInterop_Test { + /// @notice Set up the test for converting from a legacy token to a SuperchainERC20 token function _setUpLegacyToSuper(address _from, address _to) internal { // Assume vm.assume(_from != console2.CONSOLE_ADDRESS); @@ -63,7 +70,7 @@ contract L2StandardBridgeInterop_LegacyToSuper_Test is L2StandardBridgeInterop_T } /// @notice Test that the `convert` function with different decimals reverts - function testFuzz_convert_differenteDecimals_reverts( + function testFuzz_convert_differentDecimals_reverts( address _from, uint8 _decimalsFrom, address _to, @@ -184,17 +191,13 @@ contract L2StandardBridgeInterop_LegacyToSuper_Test is L2StandardBridgeInterop_T _mockDeployments(address(l2OptimismMintableERC20Factory), _from, _remoteToken); _mockDeployments(Predeploys.OPTIMISM_SUPERCHAIN_ERC20_FACTORY, _to, _remoteToken); - // Mock the `burn` and `mint` functions - vm.mockCall(_from, abi.encodeWithSelector(MintableAndBurnable.burn.selector, _caller, _amount), abi.encode()); - vm.mockCall(_to, abi.encodeWithSelector(MintableAndBurnable.mint.selector, _caller, _amount), abi.encode()); - // Expect the `Converted` event to be emitted vm.expectEmit(true, true, true, true, address(l2StandardBridge)); emit Converted(_from, _to, _caller, _amount); - // Expect the `mint` and `burn` functions to be called - vm.expectCall(_from, abi.encodeWithSelector(MintableAndBurnable.burn.selector, _caller, _amount), 1); - vm.expectCall(_to, abi.encodeWithSelector(MintableAndBurnable.mint.selector, _caller, _amount), 1); + // Mock and expect the `burn` and `mint` functions + _mockAndExpect(_from, abi.encodeWithSelector(MintableAndBurnable.burn.selector, _caller, _amount), abi.encode()); + _mockAndExpect(_to, abi.encodeWithSelector(MintableAndBurnable.mint.selector, _caller, _amount), abi.encode()); // Act vm.prank(_caller); @@ -202,8 +205,9 @@ contract L2StandardBridgeInterop_LegacyToSuper_Test is L2StandardBridgeInterop_T } } -/// @notice Test when converting from a SuperchainERC20 token to a legacy token +/// @notice Test suite when converting from a SuperchainERC20 token to a legacy token contract L2StandardBridgeInterop_SuperToLegacy_Test is L2StandardBridgeInterop_Test { + /// @notice Set up the test for converting from a SuperchainERC20 token to a legacy token function _setUpSuperToLegacy(address _from, address _to) internal { // Assume vm.assume(_from != console2.CONSOLE_ADDRESS); @@ -212,14 +216,10 @@ contract L2StandardBridgeInterop_SuperToLegacy_Test is L2StandardBridgeInterop_T // Mock same decimals _mockDecimals(_from, 18); _mockDecimals(_to, 18); - - // Mock `_to` to be a legacy address - _mockInterface(_to, type(IERC165).interfaceId, true); - _mockInterface(_to, type(IOptimismMintableERC20).interfaceId, true); } /// @notice Test that the `convert` function with different decimals reverts - function testFuzz_convert_differenteDecimals_reverts( + function testFuzz_convert_differentDecimals_reverts( address _from, uint8 _decimalsFrom, address _to, @@ -340,17 +340,13 @@ contract L2StandardBridgeInterop_SuperToLegacy_Test is L2StandardBridgeInterop_T _mockDeployments(address(l2OptimismMintableERC20Factory), _to, _remoteToken); _mockDeployments(Predeploys.OPTIMISM_SUPERCHAIN_ERC20_FACTORY, _from, _remoteToken); - // Mock the `burn` and `mint` functions - vm.mockCall(_from, abi.encodeWithSelector(MintableAndBurnable.burn.selector, _caller, _amount), abi.encode()); - vm.mockCall(_to, abi.encodeWithSelector(MintableAndBurnable.mint.selector, _caller, _amount), abi.encode()); - // Expect the `Converted` event to be emitted vm.expectEmit(true, true, true, true, address(l2StandardBridge)); emit Converted(_from, _to, _caller, _amount); - // Expect the `mint` and `burn` functions to be called - vm.expectCall(_from, abi.encodeWithSelector(MintableAndBurnable.burn.selector, _caller, _amount), 1); - vm.expectCall(_to, abi.encodeWithSelector(MintableAndBurnable.mint.selector, _caller, _amount), 1); + // Mock and expect the `burn` and `mint` functions + _mockAndExpect(_from, abi.encodeWithSelector(MintableAndBurnable.burn.selector, _caller, _amount), abi.encode()); + _mockAndExpect(_to, abi.encodeWithSelector(MintableAndBurnable.mint.selector, _caller, _amount), abi.encode()); // Act vm.prank(_caller);