synapsecns/sanguine

View on GitHub
packages/contracts-rfq/test/integration/TokenZapV1.t.sol

Summary

Maintainability
Test Coverage
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

import {FastBridgeV2, IFastBridge, IFastBridgeV2} from "../../contracts/FastBridgeV2.sol";
import {BridgeTransactionV2Lib} from "../../contracts/libs/BridgeTransactionV2.sol";
import {ZapDataV1} from "../../contracts/libs/ZapDataV1.sol";
import {TokenZapV1} from "../../contracts/zaps/TokenZapV1.sol";

import {MockERC20} from "../mocks/MockERC20.sol";
import {VaultManyArguments} from "../mocks/VaultManyArguments.sol";

import {Test} from "forge-std/Test.sol";

// solhint-disable no-empty-blocks, ordering
abstract contract TokenZapV1IntegrationTest is Test {
    address internal constant NATIVE_GAS_TOKEN = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;

    uint32 internal constant SRC_CHAIN_ID = 1337;
    uint32 internal constant DST_CHAIN_ID = 7331;

    uint256 internal constant SRC_AMOUNT = 1 ether;
    uint256 internal constant DST_AMOUNT = 0.9999 ether;
    uint256 internal constant ZAP_NATIVE = 123_456;

    FastBridgeV2 internal fastBridge;
    TokenZapV1 internal dstZap;

    address internal user = makeAddr("User");
    address internal relayer = makeAddr("Relayer");

    MockERC20 internal srcToken;
    MockERC20 internal dstToken;

    VaultManyArguments internal dstVault;

    IFastBridge.BridgeParams internal tokenParams;
    IFastBridge.BridgeParams internal nativeParams;

    IFastBridgeV2.BridgeParamsV2 internal depositTokenParams;
    IFastBridgeV2.BridgeParamsV2 internal depositTokenWithZapNativeParams;
    IFastBridgeV2.BridgeParamsV2 internal depositTokenRevertParams;
    IFastBridgeV2.BridgeParamsV2 internal depositNativeParams;
    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);

        srcToken = new MockERC20("SRC", 18);
        dstToken = new MockERC20("DST", 18);

        dstZap = new TokenZapV1();
        dstVault = new VaultManyArguments();

        createFixtures();
        mintTokens();
    }

    function createFixtures() public virtual {
        tokenParams = IFastBridge.BridgeParams({
            dstChainId: DST_CHAIN_ID,
            sender: user,
            to: address(dstZap),
            originToken: address(srcToken),
            destToken: address(dstToken),
            originAmount: SRC_AMOUNT,
            destAmount: DST_AMOUNT,
            sendChainGas: false,
            deadline: block.timestamp + 1 days
        });
        nativeParams = IFastBridge.BridgeParams({
            dstChainId: DST_CHAIN_ID,
            sender: user,
            to: address(dstZap),
            originToken: NATIVE_GAS_TOKEN,
            destToken: NATIVE_GAS_TOKEN,
            originAmount: SRC_AMOUNT,
            destAmount: DST_AMOUNT,
            sendChainGas: false,
            deadline: block.timestamp + 1 days
        });
        // Deposit token
        bytes memory zapData = dstZap.encodeZapData({
            target: address(dstVault),
            payload: getDepositPayload(address(dstToken)),
            amountPosition: 4 + 32 * 2,
            finalToken: address(0),
            forwardTo: address(0)
        });
        depositTokenParams.zapData = zapData;
        depositTokenWithZapNativeParams.zapData = zapData;
        depositTokenWithZapNativeParams.zapNative = ZAP_NATIVE;
        // Deposit native
        depositNativeParams.zapData = dstZap.encodeZapData({
            target: address(dstVault),
            payload: getDepositPayload(NATIVE_GAS_TOKEN),
            amountPosition: 4 + 32 * 2,
            finalToken: address(0),
            forwardTo: address(0)
        });
        // Deposit no amount
        depositNativeNoAmountParams.zapData = dstZap.encodeZapData({
            target: address(dstVault),
            payload: getDepositNoAmountPayload(),
            amountPosition: ZapDataV1.AMOUNT_NOT_PRESENT,
            finalToken: address(0),
            forwardTo: address(0)
        });
        // Deposit revert
        depositTokenRevertParams.zapData = dstZap.encodeZapData({
            target: address(dstVault),
            payload: getDepositRevertPayload(),
            amountPosition: ZapDataV1.AMOUNT_NOT_PRESENT,
            finalToken: address(0),
            forwardTo: address(0)
        });
        depositNativeRevertParams.zapData = dstZap.encodeZapData({
            target: address(dstVault),
            payload: getDepositRevertPayload(),
            amountPosition: ZapDataV1.AMOUNT_NOT_PRESENT,
            finalToken: address(0),
            forwardTo: address(0)
        });
    }

    function mintTokens() public virtual;

    function encodeBridgeTx(
        IFastBridge.BridgeParams memory params,
        IFastBridgeV2.BridgeParamsV2 memory paramsV2
    )
        public
        pure
        returns (bytes memory)
    {
        IFastBridgeV2.BridgeTransactionV2 memory bridgeTx = IFastBridgeV2.BridgeTransactionV2({
            originChainId: SRC_CHAIN_ID,
            destChainId: params.dstChainId,
            originSender: params.sender,
            destRecipient: params.to,
            originToken: params.originToken,
            destToken: params.destToken,
            originAmount: params.originAmount,
            destAmount: params.destAmount,
            // No protocol fees for the test
            originFeeAmount: 0,
            deadline: params.deadline,
            // Single tx is sent, so nonce is 0
            nonce: 0,
            exclusivityRelayer: address(0),
            exclusivityEndTime: 0,
            zapNative: paramsV2.zapNative,
            zapData: paramsV2.zapData
        });
        return BridgeTransactionV2Lib.encodeV2(bridgeTx);
    }

    function getDepositPayload(address token) public view returns (bytes memory) {
        return abi.encodeCall(dstVault.deposit, (token, abi.encode(token), DST_AMOUNT, user, abi.encode(user)));
    }

    function getDepositNoAmountPayload() public view returns (bytes memory) {
        return abi.encodeCall(dstVault.depositNoAmount, (user));
    }

    function getDepositRevertPayload() public view returns (bytes memory) {
        return abi.encodeCall(dstVault.depositWithRevert, ());
    }
}