diff --git a/packages/contracts-rfq/test/FastBridgeV2.Src.RefundV1.t.sol b/packages/contracts-rfq/test/FastBridgeV2.Src.RefundV1.t.sol index 44443a3920..4ea6518cda 100644 --- a/packages/contracts-rfq/test/FastBridgeV2.Src.RefundV1.t.sol +++ b/packages/contracts-rfq/test/FastBridgeV2.Src.RefundV1.t.sol @@ -3,8 +3,11 @@ pragma solidity ^0.8.20; import {BridgeTransactionV2Lib, FastBridgeV2SrcTest, IFastBridgeV2} from "./FastBridgeV2.Src.t.sol"; -// solhint-disable func-name-mixedcase, ordering +// solhint-disable func-name-mixedcase, no-empty-blocks, ordering contract FastBridgeV2SrcRefundV1Test is FastBridgeV2SrcTest { + /// @notice We include an empty "test" function so that this contract does not appear in the coverage report. + function testFastBridgeV2SrcRefundV1Test() external {} + function cancel(address caller, IFastBridgeV2.BridgeTransactionV2 memory bridgeTx) public virtual override { vm.prank({msgSender: caller, txOrigin: caller}); fastBridge.refund(BridgeTransactionV2Lib.encodeV2(bridgeTx)); diff --git a/packages/contracts-rfq/test/harnesses/BridgeTransactionV2Harness.sol b/packages/contracts-rfq/test/harnesses/BridgeTransactionV2Harness.sol index 947f8f2f16..08247407e2 100644 --- a/packages/contracts-rfq/test/harnesses/BridgeTransactionV2Harness.sol +++ b/packages/contracts-rfq/test/harnesses/BridgeTransactionV2Harness.sol @@ -3,7 +3,11 @@ pragma solidity 0.8.24; import {BridgeTransactionV2Lib, IFastBridgeV2} from "../../contracts/libs/BridgeTransactionV2.sol"; +// solhint-disable no-empty-blocks contract BridgeTransactionV2Harness { + /// @notice We include an empty "test" function so that this contract does not appear in the coverage report. + function testBridgeTransactionV2Harness() external {} + function encodeV2(IFastBridgeV2.BridgeTransactionV2 memory bridgeTx) public pure returns (bytes memory) { return BridgeTransactionV2Lib.encodeV2(bridgeTx); } diff --git a/packages/contracts-rfq/test/harnesses/ZapDataV1Harness.sol b/packages/contracts-rfq/test/harnesses/ZapDataV1Harness.sol index 8414fb454b..af342f9e65 100644 --- a/packages/contracts-rfq/test/harnesses/ZapDataV1Harness.sol +++ b/packages/contracts-rfq/test/harnesses/ZapDataV1Harness.sol @@ -3,10 +3,14 @@ pragma solidity 0.8.24; import {ZapDataV1} from "../../contracts/libs/ZapDataV1.sol"; +// solhint-disable no-empty-blocks contract ZapDataV1Harness { uint16 public constant VERSION = ZapDataV1.VERSION; uint16 public constant AMOUNT_NOT_PRESENT = ZapDataV1.AMOUNT_NOT_PRESENT; + /// @notice We include an empty "test" function so that this contract does not appear in the coverage report. + function testZapDataV1Harness() external {} + function validateV1(bytes calldata encodedZapData) public pure { ZapDataV1.validateV1(encodedZapData); } diff --git a/packages/contracts-rfq/test/integration/FastBridge.MulticallTarget.t.sol b/packages/contracts-rfq/test/integration/FastBridge.MulticallTarget.t.sol index 182b25f050..08b432466e 100644 --- a/packages/contracts-rfq/test/integration/FastBridge.MulticallTarget.t.sol +++ b/packages/contracts-rfq/test/integration/FastBridge.MulticallTarget.t.sol @@ -5,7 +5,11 @@ import {FastBridge} from "../../contracts/FastBridge.sol"; import {IFastBridge, MulticallTargetIntegrationTest} from "./MulticallTarget.t.sol"; +// solhint-disable no-empty-blocks contract FastBridgeMulticallTargetTest is MulticallTargetIntegrationTest { + /// @notice We include an empty "test" function so that this contract does not appear in the coverage report. + function testFastBridgeMulticallTargetTest() external {} + function deployAndConfigureFastBridge() public override returns (address) { FastBridge fastBridge = new FastBridge(address(this)); fastBridge.grantRole(fastBridge.RELAYER_ROLE(), relayer); diff --git a/packages/contracts-rfq/test/integration/FastBridgeV2.MulticallTarget.t.sol b/packages/contracts-rfq/test/integration/FastBridgeV2.MulticallTarget.t.sol index 794d0c9210..ebb0f78689 100644 --- a/packages/contracts-rfq/test/integration/FastBridgeV2.MulticallTarget.t.sol +++ b/packages/contracts-rfq/test/integration/FastBridgeV2.MulticallTarget.t.sol @@ -6,7 +6,11 @@ import {BridgeTransactionV2Lib} from "../../contracts/libs/BridgeTransactionV2.s import {IFastBridge, MulticallTargetIntegrationTest} from "./MulticallTarget.t.sol"; +// solhint-disable no-empty-blocks contract FastBridgeV2MulticallTargetTest is MulticallTargetIntegrationTest { + /// @notice We include an empty "test" function so that this contract does not appear in the coverage report. + function testFastBridgeV2MulticallTargetTest() external {} + function deployAndConfigureFastBridge() public override returns (address) { FastBridgeV2 fb = new FastBridgeV2(address(this)); fb.addProver(relayer); diff --git a/packages/contracts-rfq/test/integration/TokenZapV1.t.sol b/packages/contracts-rfq/test/integration/TokenZapV1.t.sol index efd1fefac3..8cb8a502ac 100644 --- a/packages/contracts-rfq/test/integration/TokenZapV1.t.sol +++ b/packages/contracts-rfq/test/integration/TokenZapV1.t.sol @@ -11,7 +11,7 @@ import {VaultManyArguments} from "../mocks/VaultManyArguments.sol"; import {Test} from "forge-std/Test.sol"; -// solhint-disable ordering +// solhint-disable no-empty-blocks, ordering abstract contract TokenZapV1IntegrationTest is Test { address internal constant NATIVE_GAS_TOKEN = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; @@ -43,6 +43,9 @@ abstract contract TokenZapV1IntegrationTest is Test { IFastBridgeV2.BridgeParamsV2 internal depositNativeNoAmountParams; IFastBridgeV2.BridgeParamsV2 internal depositNativeRevertParams; + /// @notice We include an empty "test" function so that this contract does not appear in the coverage report. + function testTokenZapV1IntegrationTest() external {} + function setUp() public virtual { fastBridge = new FastBridgeV2(address(this)); fastBridge.addProver(relayer); diff --git a/packages/contracts-rfq/test/mocks/MockRevertingRecipient.sol b/packages/contracts-rfq/test/mocks/MockRevertingRecipient.sol index 2068022f3c..fbf0e0ef76 100644 --- a/packages/contracts-rfq/test/mocks/MockRevertingRecipient.sol +++ b/packages/contracts-rfq/test/mocks/MockRevertingRecipient.sol @@ -1,8 +1,12 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.17; +// solhint-disable no-empty-blocks contract MockRevertingRecipient { receive() external payable { revert("GM"); } + + /// @notice We include an empty "test" function so that this contract does not appear in the coverage report. + function testMockRevertingRecipient() external {} } diff --git a/packages/contracts-rfq/test/mocks/VaultMock.sol b/packages/contracts-rfq/test/mocks/VaultMock.sol index b4d1f514ec..4df738b05e 100644 --- a/packages/contracts-rfq/test/mocks/VaultMock.sol +++ b/packages/contracts-rfq/test/mocks/VaultMock.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.20; import {IERC20, SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +// solhint-disable no-empty-blocks /// @notice Vault mock for testing purposes. DO NOT USE IN PRODUCTION. abstract contract VaultMock { using SafeERC20 for IERC20; @@ -13,6 +14,9 @@ abstract contract VaultMock { error VaultMock__AmountIncorrect(); + /// @notice We include an empty "test" function so that this contract does not appear in the coverage report. + function testVaultMock() external {} + function _deposit(address user, address token, uint256 amount) internal { if (token == NATIVE_GAS_TOKEN) { if (msg.value != amount) revert VaultMock__AmountIncorrect(); diff --git a/packages/contracts-rfq/test/zaps/TokenZapV1.t.sol b/packages/contracts-rfq/test/zaps/TokenZapV1.t.sol index 5842b25172..7f7574c8c1 100644 --- a/packages/contracts-rfq/test/zaps/TokenZapV1.t.sol +++ b/packages/contracts-rfq/test/zaps/TokenZapV1.t.sol @@ -417,6 +417,48 @@ contract TokenZapV1Test is Test { assertEq(weth.balanceOf(user), 2 * AMOUNT); } + function getZapDataTransferNative(address target) public view returns (bytes memory) { + return tokenZap.encodeZapData({ + target: target, + payload: "", + amountPosition: type(uint256).max, + finalToken: address(0), + forwardTo: address(0) + }); + } + + function test_zap_transferNativeEOA() public { + bytes memory zapData = getZapDataTransferNative(user); + bytes4 returnValue = tokenZap.zap{value: AMOUNT}(nativeGasToken, AMOUNT, zapData); + assertEq(returnValue, tokenZap.zap.selector); + // Check that the user received the native tokens + assertEq(user.balance, AMOUNT); + } + + function test_zap_transferNativeContract() public { + bytes memory zapData = getZapDataTransferNative(payableMock); + bytes4 returnValue = tokenZap.zap{value: AMOUNT}(nativeGasToken, AMOUNT, zapData); + assertEq(returnValue, tokenZap.zap.selector); + // Check that the contract received the native tokens + assertEq(payableMock.balance, AMOUNT); + } + + function test_zap_transferNativeEOA_extraFunds() public { + // Transfer some extra tokens to the zap contract + weth.transfer(address(tokenZap), AMOUNT); + deal(address(tokenZap), AMOUNT); + // Should not affect the zap + test_zap_transferNativeEOA(); + } + + function test_zap_transferNativeContract_extraFunds() public { + // Transfer some extra native tokens to the zap contract + weth.transfer(address(tokenZap), AMOUNT); + deal(address(tokenZap), AMOUNT); + // Should not affect the zap + test_zap_transferNativeContract(); + } + // ═════════════════════════════════════════════════ ENCODING ══════════════════════════════════════════════════════ function test_encodeZapData_roundtrip(address token, uint256 placeholderAmount, uint256 amount) public view { @@ -544,6 +586,12 @@ contract TokenZapV1Test is Test { tokenZap.zap(address(weth), AMOUNT, zapDataWithdrawAndForward); } + function test_zap_transferNative_revert_targetReverted() public { + bytes memory zapData = getZapDataTransferNative(nonPayableMock); + vm.expectRevert(Address.FailedInnerCall.selector); + tokenZap.zap{value: AMOUNT}(nativeGasToken, AMOUNT, zapData); + } + function test_zap_native_revert_targetZeroAddress_emptyPayload() public { bytes memory zapData = getZeroTargetZapData({payload: "", amountPosition: 0}); vm.expectRevert(TokenZapV1.TokenZapV1__TargetZeroAddress.selector);