Sending a Swap Transaction

BrainDex exposes three functions for swapping tokens, after common router patterns of allowing the network currency as either the input or the output of the swap, as well as allowing swaps of tokens for tokens.

interface IBrainDexRouter {
        function multiSwapEthForTokens(
                address tokenOut,
                address to,
                uint256 amountOutMin,
                uint256 deadline,
                bytes calldata swapData
        ) external payable;
        
        function multiSwapTokensForEth(
                address tokenIn,
                address to,
                uint256 amountIn,
                uint256 amountOutMin,
                uint256 deadline,
                bytes calldata swapData
        ) external;
        
        function multiSwapTokensForTokens(
                address tokenIn,
                address tokenOut,
                address to,
                uint256 amountIn,
                uint256 amountOutMin,
                uint256 deadline,
                bytes calldata swapData
        ) external;
}

See BrainDexRouterV2.sol for detailed function parameter information.

Calling the swap function with route request response parameters

In cases where the end-user is attempting to swap to or from the network currency, the route request JSON must be populated with the corresponding input/output wrapped version of the network currency. For example, if the end-user wants to swap from native ETH, token_in will be the WETH address.

Example: calling multiSwapTokensForTokens

Given the following route response data:

{
    "token_in":"0xacc15dc74880c9944775448304b263d191c6077f",
    "token_out":"0x818ec0a7fe18ff94269904fced6ae3dae6d6dc0b",
    "amount_in":"0x579a814e10a740000",
    "amount_out":"0x203c06b",
    "swap_paths":"0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000053392e0a296bb0000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000b929914b89584b4081c7966ac6287636f7efd0530000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000818ec0a7fe18ff94269904fced6ae3dae6d6dc0b00000000000000000000000000000000000000000000000000000000000f36880000000000000000000000000000000000000000000000004615343e73b90000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000fc422eb0a2c7a99bad330377497fd9798c9b10010000000000000000000000008273de7090c7067f3ae1b6602eedbd2dbc02c48f0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a649325aa7c5093d12d6f98eb4378deae68ce23f00000000000000000000000000000000000000000000000000000000000f3688000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000818ec0a7fe18ff94269904fced6ae3dae6d6dc0b0000000000000000000000000000000000000000000000000000000000000000",
    "swap_viz_data":[
        {
            "route_tokens":["0xacc15dc74880c9944775448304b263d191c6077f","0x818ec0a7fe18ff94269904fced6ae3dae6d6dc0b"],
            "route_protocols":["Beamswap"],
            "route_percent":95
        },
        {
            "route_tokens":["0xacc15dc74880c9944775448304b263d191c6077f","0xa649325aa7c5093d12d6f98eb4378deae68ce23f","0x818ec0a7fe18ff94269904fced6ae3dae6d6dc0b"],
            "route_protocols":["Beamswap","Beamswap"],
            "route_percent":5
        }
    ],
    "price_impact":0.0004684849937906582
}

A sample call to prepare a swap transaction using wagmi.sh:

const { config, error } = usePrepareContractWrite({
  address: BrainDexRouterContract,
  abi: BrainDexRouterAbi,
  functionName: "multiSwapTokensForTokens",
  args: [
    token_in,         // Supplied by frontend
    token_out,        // Supplied by frontend
    to,               // Supplied by frontend
    amount_in,        // Supplied by frontend
    amount_out_min,   // computed using amount_out net slippage
    timestamp,        // Supplied by frontend
    swap_paths,       // Supplied by pathfinderResponse
  ],
  overrides: {},

swap_viz_data and price_impact are not used in the on-chain call, and are for frontend visualization / route visualization purposes only.

Security Considerations

While we return token_in, token_out, and amount_in from the route response, when calling the relevant swap function, for safety the following parameters should be supplied directly from the frontend interface, and not from the route request response:

  • tokenIn: The token to swap from

  • tokenOut: The token to swap to

  • amountIn: The desired amount of tokens to swap from

  • to: The account which should receive the output swap

  • deadline: The deadline in UNIX time after which processing the swap will result in a revert

The following two parameters should be processed from the route response object:

  • amountOutMin: This is a computed parameter equal to the amount_out quote, net the slippage margin as processed by a frontend. This should be at least marginally lower than the actual quote value, as transactions trading with exactly 0% slippage are likely to fail.

  • swapData: This parameter should be passed directly from the route response object to the smart contract call as is.

A Note on Gas Estimation

We do not currently provide gas estimation via the BrainDex API -- gas estimation should be done locally. In addition, we have found that for most compatible chains, the gas estimate can sometimes be insufficient to complete the swap, so we recommend that implementers buffer their gas estimates by 1.2x the returned value to ensure swap success.

Last updated