Execution

The route data from the V2 API can be used directly with the MultiHopRouter smart contract. The V2 API provides ready-to-use transaction calldata, making execution simple.

Contract Address

0x744489ee3d540777a66f2cf297479745e0852f7a

Execution Methods

There are three primary ways to execute swaps with the MultiHopRouter:

1. Using the executeSwaps Function

The executeSwaps function provides advanced features including positive slippage capture (50% capture rate) and custom fee collection:

function executeSwaps(
    address[] calldata tokens,
    uint256 amountIn,
    uint256 minAmountOut,
    uint256 expectedAmountOut,
    Swap[][] calldata hopSwaps,
    uint256 feeBps,
    address feeRecipient
) external payable nonReentrant returns (uint256 userAmountOut)

Parameters:

  • tokens: Array of token addresses representing the swap path

  • amountIn: Amount of input tokens to swap

  • minAmountOut: Minimum amount of output tokens expected (slippage protection)

  • expectedAmountOut: Expected amount of output tokens (used for positive slippage calculation)

  • hopSwaps: Array of swap configurations for each hop (obtained from the V2 API response)

  • feeBps: Fee in basis points (e.g., 100 = 1%) - automatically capped at 1% max

  • feeRecipient: Address to receive the fee (97.5% of fee goes here, 2.5% goes to protocol)

Features:

  • Positive Slippage Capture: Captures 50% of any positive slippage

    • If feeRecipient is specified: half of captured slippage goes to your wallet, half to protocol

    • If no feeRecipient is specified: protocol keeps all captured positive slippage

    • You can set feeBps=0 and still receive positive slippage by providing feeRecipient

  • Custom Fee Collection: Set your own fees up to 1% (100 basis points), or set to 0 for no fees

  • Revenue Sharing: You keep 97.5% of collected fees, protocol keeps 2.5%

  • Automatic Fee Handling: If feeBps is 0 or feeRecipient is zero address, no fee is taken

2. Using the executeMultiHopSwap Function

The executeMultiHopSwap function is designed for searchers, arbitragers, and advanced traders who build routes off-chain and don't want to share positive slippage:

function executeMultiHopSwap(
    address[] calldata tokens,
    uint256 amountIn,
    uint256 minAmountOut,
    Swap[][] calldata hopSwaps
) external payable nonReentrant returns (uint256 totalAmountOut)

Parameters:

  • tokens: Array of token addresses representing the swap path

  • amountIn: Amount of input tokens to swap

  • minAmountOut: Minimum amount of output tokens expected (slippage protection)

  • hopSwaps: Array of swap configurations for each hop

Features:

  • Flat Fee: 0.03% fee on output amount (goes entirely to protocol)

  • No Positive Slippage Sharing: You keep all positive slippage

  • No Expected Amount Required: Simpler parameter set for advanced users

  • Off-Chain Route Building: Perfect for custom routing strategies

Ideal For:

  • Searchers and MEV bots

  • Arbitrage strategies

  • Advanced traders with custom routing logic

  • Applications that build routes off-chain

  • Users who prefer not to share positive slippage

3. Using Calldata Directly from V2 Route

The V2 API response includes ready-to-use transaction calldata in the execution.calldata field. This calldata can be sent directly to the contract without manually constructing function calls.

Example using the calldata:

// Get route from V2 API
const response = await fetch('https://api.liqd.ag/v2/route?tokenIn=0x5555...&tokenOut=0xB8CE...&amountIn=100');
const routeData = await response.json();

// Execute using the provided calldata
if (routeData.success && routeData.execution) {
    const transaction = {
        to: routeData.execution.to,           // Contract address
        data: routeData.execution.calldata,   // Ready-to-use calldata
        value: 0                              // Add ETH value if swapping from native token
    };
    
    // Send transaction using your preferred method (ethers, web3, etc.)
    const result = await signer.sendTransaction(transaction);
}

Benefits of using calldata directly:

  • Simplified Integration: No need to manually construct function parameters

  • Guaranteed Compatibility: Calldata is generated by the same system that will execute it

  • Reduced Errors: Eliminates parameter formatting mistakes

  • Future-Proof: Automatically uses the optimal execution method

Which Method to Choose?

  • Use calldata directly for simpler integration and guaranteed compatibility

  • Use executeSwaps function when you need custom fee collection, positive slippage sharing, and have an expected output amount

  • Use executeMultiHopSwap function for searchers, arbitragers, and advanced use cases where you want to keep all positive slippage and build routes off-chain

All methods execute optimized routing strategies, but executeSwaps and calldata use the V2 API routing, while executeMultiHopSwap is designed for custom off-chain route construction.

Hop Swaps Data Structure

For developers building routes off-chain or using the executeMultiHopSwap function, you need to understand the hop swaps data structure. This is also the same structure returned in the V2 API response under execution.details.hopSwaps:

Swap Struct

struct Swap {
    address tokenIn;       // Input token address
    address tokenOut;      // Output token address  
    uint8 routerIndex;     // DEX router index (1-12, see route-finding.md for DEX table)
    uint24 fee;            // Trading fee in basis points (used by V3 DEXs)
    uint256 amountIn;      // Amount of input tokens for this specific swap
    bool stable;           // Whether to use stable pool (used by V2 DEXs like KittenSwap)
}

Hop Swaps Array Structure

// Each hop contains an array of swaps that execute in parallel
Swap[][] hopSwaps = [
    [swap1, swap2, swap3], // First hop: multiple swaps from tokenA to tokenB
    [swap4, swap5]         // Second hop: multiple swaps from tokenB to tokenC  
];

Field Usage by DEX Type

Field
V2 DEXs (1,2,7)
V3 DEXs (3,4,5,8,10,12)
Others (6,9,11)

tokenIn

βœ… Required

βœ… Required

βœ… Required

tokenOut

βœ… Required

βœ… Required

βœ… Required

routerIndex

βœ… Required

βœ… Required

βœ… Required

fee

❌ Ignored

βœ… Required

❌ Ignored

amountIn

βœ… Required

βœ… Required

βœ… Required

stable

βœ… Required

❌ Ignored

❌ Ignored

This structure allows for complex multi-hop routing where each hop can split across multiple DEXs for optimal execution.

Last updated