Managing liquidity in decentralized finance (DeFi) requires precision, especially when dealing with assets that must be deposited in specific ratios. On Uniswap v3, providing liquidity isn't as simple as depositing two tokens—you need them in the exact proportion required by the pool. If your wallet holds an imbalanced ratio, you’ll either leave some assets unused or risk inefficient capital allocation.
The solution? A swap-and-add strategy: atomically swapping part of one token into the other to achieve the ideal ratio, then depositing both into the pool—all in a single transaction. This method ensures 100% of your assets are utilized while avoiding mid-process price shifts due to pool imbalance.
This guide walks through how to execute a swap-and-add liquidity operation using Uniswap’s SDK and smart order routing tools, enabling efficient, gas-optimized DeFi interactions.
Understanding Swap-and-Add Liquidity
In traditional liquidity provision on Uniswap v3, you must supply two tokens in a precise ratio matching the current state of the pool. But what if your holdings don’t match that ratio?
You could manually:
- Swap part of Token A for Token B
- Check the new balance
- Attempt to add liquidity
But this multi-step process is risky. The swap itself changes the pool’s price, altering the optimal deposit ratio before you even reach step three. This leads to leftover tokens or failed transactions.
👉 Discover how automated DeFi strategies can optimize your asset utilization
By combining the swap and add into a single atomic transaction, we eliminate timing risks and slippage issues. The entire process is calculated and executed at once, ensuring maximum capital efficiency.
Core Keywords
- Swap and add liquidity
- Uniswap v3
- Atomic transaction
- Smart order router
- Liquidity provision
- Token ratio optimization
- DeFi automation
- Nonfungible Position Manager
Setting Up the Router Instance
To perform a swap-and-add, we use Uniswap’s AlphaRouter, part of the @uniswap/smart-order-router package. This intelligent router finds optimal swap paths and supports advanced functions like ratio-based swaps.
First, ensure your tokens approve the V3_SWAP_ROUTER_ADDRESS to spend them:
const tokenInApproval = await getTokenTransferApproval(
token0,
V3_SWAP_ROUTER_ADDRESS
);
const tokenOutApproval = await getTokenTransferApproval(
token1,
V3_SWAP_ROUTER_ADDRESS
);Once approved, initialize the router with a provider and chain ID:
import { ethers } from 'ethers';
import { AlphaRouter } from '@uniswap/smart-order-router';
const provider = new ethers.providers.JsonRpcProvider(rpcUrl);
const router = new AlphaRouter({ chainId: 1, provider });Note: Even when testing on local forks, use a mainnet provider for accurate routing data—local simulations lack real-time liquidity information.
For detailed implementation, refer to Uniswap’s routing guide.
Configuring Ratio Calculation Parameters
The key to successful swap-and-add lies in accurately calculating the target ratio using routeToRatio. This function adjusts your input amounts so they align perfectly with the pool’s requirements.
Start by defining your input currency amounts:
import { CurrencyAmount } from '@uniswap/sdk-core';
const token0CurrencyAmount = CurrencyAmount.fromRawAmount(
token0,
fromReadableAmount(token0AmountToAdd, token0.decimals)
);
const token1CurrencyAmount = CurrencyAmount.fromRawAmount(
token1,
fromReadableAmount(token1AmountToAdd, token1.decimals)
);Next, create a placeholder position to represent your intended liquidity range:
import { Pool, Position, nearestUsableTick } from '@uniswap/v3-sdk';
const placeholderPosition = new Position({
pool,
liquidity: 1,
tickLower: nearestUsableTick(pool.tickCurrent, pool.tickSpacing) - pool.tickSpacing * 2,
tickUpper: nearestUsableTick(pool.tickCurrent, pool.tickSpacing) + pool.tickSpacing * 2
});Configure algorithm behavior with SwapAndAddConfig:
import { Fraction } from '@uniswap/sdk-core';
import { SwapAndAddConfig } from '@uniswap/smart-order-router';
const swapAndAddConfig: SwapAndAddConfig = {
ratioErrorTolerance: new Fraction(1, 100), // 1% tolerance
maxIterations: 6
};Finally, define execution options:
const swapAndAddOptions: SwapAndAddOptions = {
swapOptions: {
type: SwapType.SWAP_ROUTER_02,
recipient: address,
slippageTolerance: new Percent(50, 10_000), // 0.5%
deadline: Math.floor(Date.now() / 1000) + 60 * 20
},
addLiquidityOptions: {
tokenId: positionId
}
};👉 Learn how top traders automate complex DeFi operations with precision
Calculating the Optimal Currency Ratio
With all parameters set, call routeToRatio to compute the ideal swap path:
const routeToRatioResponse: SwapToRatioResponse = await router.routeToRatio(
token0CurrencyAmount,
token1CurrencyAmount,
placeholderPosition,
swapAndAddConfig,
swapAndAddOptions
);Check for success before proceeding:
import { SwapToRatioStatus } from '@uniswap/smart-order-router';
if (!routeToRatioResponse || routeToRatioResponse.status !== SwapToRatioStatus.SUCCESS) {
// Handle failed route lookup
}If successful, the response contains a SwapToRatioRoute object with encoded calldata for execution.
Executing the Atomic Swap-and-Add Transaction
Now construct and send the transaction:
const route: SwapToRatioRoute = routeToRatioResponse.result;
const transaction = {
data: route.methodParameters?.calldata,
to: V3_SWAP_ROUTER_ADDRESS,
value: route.methodParameters?.value,
from: address
};
const txRes = await wallet.sendTransaction(transaction);Upon confirmation:
- Input token balances decrease
- Liquidity position increases accordingly
- No leftover tokens remain
This atomic execution guarantees that either both operations succeed or neither does—eliminating partial failures and wasted gas.
👉 See how integrated trading platforms streamline advanced DeFi workflows
Frequently Asked Questions (FAQ)
Q: What is a swap-and-add liquidity operation?
A: It's a single transaction that first swaps part of one token into another to match a pool's required ratio, then deposits both into the liquidity position—ensuring full capital utilization without intermediate risks.
Q: Why can't I just swap and add liquidity separately?
A: Separate transactions expose you to price movement between steps. The initial swap alters the pool ratio, making your second deposit less efficient or potentially failing due to outdated pricing.
Q: Is this method supported on all Uniswap pools?
A: Yes, as long as the pool exists on Uniswap v3 and both tokens are tradable, the AlphaRouter can calculate and execute the swap-and-add.
Q: How does routeToRatio determine the correct ratio?
A: It uses real-time pool data and iterative calculations to find a swap path that brings your token balances into alignment with the current optimal deposit ratio within defined error tolerance.
Q: Can I use this for new or low-liquidity pools?
A: While possible, low-liquidity pools may result in higher slippage or failed routes. The algorithm attempts up to maxIterations (default 6) to find a viable path.
Q: Do I need to re-approve tokens every time?
A: No. Once you’ve approved the NonfungiblePositionManager during initial minting, no further approvals are needed for subsequent add/remove actions.
By leveraging atomic operations and smart routing logic, users can now optimize their DeFi strategies with surgical precision—maximizing yield while minimizing risk.