swap-and-add-liquidity
Introduction
This guide will cover how to execute a swap-and-add operation in a single atomic transaction. It is based on the swap-and-add example, found in the SwapX code examples repository. To run this example, check out the examples's README and follow the setup instructions.
If you need a briefer on the SDK and to learn more about how these guides connect to the examples repository, please visit our background page!
When adding liquidity to a SwapX v3 pool, you must provide two assets in a particular ratio. In many cases, your contract or the user's wallet hold a different ratio of those two assets. In order to deposit 100% of your assets, you must first swap your assets to the optimal ratio and then add liquidity.
However, the swap may shift the balance of the pool and thus change the optimal ratio. To avoid that, we can execute this swap-and-add liquidity operation in an atomic fashion, using a router. The inputs to our guide are the two tokens that we are pooling for, the amount of each token we are pooling for, the amount of each token to swap-and-add, and the Pool fee.
The guide will cover:
- Setup a router instance
- Configuring our ratio calculation
- Calculating our currency ratio
- Constructing and executing our swap-and-add transaction
At the end of the guide, given the inputs above, we should be able swap-and-add liquidity using 100% of the input assets with the press of a button and see the change reflected in our position and the balance of our tokens.
For this guide, the following SwapX packages are used:
The core code of this guide can be found in swapAndAddLiquidity()
.
This guide assumes you are familiar with our Minting a Position guide. A minted position is required to add or remove liquidity from, so the buttons will be disabled until a position is minted.
Also note that we do not need to give approval to the NonfungiblePositionManager
to transfer our tokens as we will have already done that when minting our position.
Setup a router instance
The first step is to approve the SwapRouter
smart contract to spend our tokens for us in order for us to add liquidity to our position:
const tokenInApproval = await getTokenTransferApproval(
token0,
V3_SWAP_ROUTER_ADDRESS
);
const tokenOutApproval = await getTokenTransferApproval(
token1,
V3_SWAP_ROUTER_ADDRESS
);
We described the getTokenTransferApproval
function here.
Then we can setup our router, the AlphaRouter
, which is part of the smart-order-router package. The router requires a chainId
and a provider
to be initialized. Note that routing is not supported for local forks, so we will use a mainnet provider even when swapping on a local fork:
import { ethers } from "ethers";
import { AlphaRouter } from "@swapx/smart-order-router";
const provider = new ethers.providers.JsonRpcProvider(rpcUrl);
const router = new AlphaRouter({ chainId: 1, provider });
For a more detailed example, check out our routing guide.