Single Swaps
For a token to token swap through a single pool the following Balancer Router functions should be used: swapSingleTokenExactIn and swapSingleTokenExactOut are the most gas efficient functions to use.
Checkout Javascript and Solidity examples here.
Multi-path Swaps
Swaps paths constructed of steps through multiple pools/tokens the following Batch Router functions should be used: swapExactIn and swapExactOut functions.
A SwapPathStep
is defined as:
struct SwapPathStep {
address pool;
IERC20 tokenOut;
// If true, the "pool" is an ERC4626 Buffer. Used to wrap/unwrap tokens if pool doesn't have enough liquidity.
bool isBuffer;
}
and paths can include add/remove liquidity steps by using the address of the respective pool. For example, the following SwapPathExactAmountIn
would execute a swap of USDC to BAL then add liquidity to the 80/20 BAL/WETH pool.
// Note - pseudo code
SwapPathExactAmountIn {
tokenIn: USDC
// for each step:
// if tokenIn == pool use removeLiquidity SINGLE_TOKEN_EXACT_IN
// if tokenOut == pool use addLiquidity UNBALANCED
steps: [
{
pool: '0xBAL_USDC_POOL',
tokenOut: '0xBAL',
isBuffer: false
},
{
pool: '0xB-80BAL-20WETH_POOL',
tokenOut: '0xB-80BAL-20WETH_POOL',
isBuffer: false
}
]
exactAmountIn: 1000000,
minAmountOut: 100000
}
Checkout Javascript and Solidity examples here.
Simulating Swaps Using Query Functions
Queries provide the ability to simulate an operation and find its result without executing a transaction. Balancer Routers provide a query for all state changing liquidity operations including single and multi-path swap functions, e.g. querySwapSingleTokenExactIn
.
Note - for onchain integrations queries should not be used to set limits due to possible manipulation via frontrunning.