Provide liquidity
Liquidity on BarkSwap is concentrated: you choose a price range (tickLower → tickUpper) and
your capital is only active within it. Positions are minted as ERC-721 NFTs by the
NonfungiblePositionManager (NPM).
Parameter shape
Like swaps, the NPM mint struct takes a deployer field instead of a fee tier. Pass
address(0) for the default deployer.
1. Approve both tokens
import { Contract, MaxUint256 } from 'ethers';
const NPM = '0xf596329a6c7E03F0708199cB5435f86783DB4302';
const ERC20_ABI = ['function approve(address spender, uint256 amount) returns (bool)'];
for (const tokenAddr of [token0, token1]) {
const token = new Contract(tokenAddr, ERC20_ABI, signer);
await (await token.approve(NPM, MaxUint256)).wait();
}
token0 and token1 must be sorted ascending by address (token0 < token1), matching the
pool's ordering.
2. Mint a position
const NPM_ABI = [
'function mint((address token0,address token1,address deployer,int24 tickLower,int24 tickUpper,uint256 amount0Desired,uint256 amount1Desired,uint256 amount0Min,uint256 amount1Min,address recipient,uint256 deadline)) payable returns (uint256 tokenId, uint128 liquidity, uint256 amount0, uint256 amount1)',
];
const ZERO = '0x0000000000000000000000000000000000000000';
const npm = new Contract(NPM, NPM_ABI, signer);
const tx = await npm.mint({
token0,
token1,
deployer: ZERO,
tickLower, // must be a multiple of the pool tickSpacing
tickUpper,
amount0Desired,
amount1Desired,
amount0Min: 0n, // set real minimums in production to bound slippage
amount1Min: 0n,
recipient: await signer.getAddress(),
deadline: Math.floor(Date.now() / 1000) + 60 * 10,
});
const receipt = await tx.wait();
// The new position's tokenId is in the IncreaseLiquidity / Transfer event logs.
3. Manage the position
The NPM exposes the standard lifecycle calls:
| Action | Call |
|---|---|
| Add liquidity | increaseLiquidity((tokenId, amount0Desired, amount1Desired, amount0Min, amount1Min, deadline)) |
| Remove liquidity | decreaseLiquidity((tokenId, liquidity, amount0Min, amount1Min, deadline)) |
| Collect fees / withdrawn tokens | collect((tokenId, recipient, amount0Max, amount1Max)) |
| Read position | positions(tokenId) |
| Burn empty position | burn(tokenId) |
decreaseLiquidity only credits tokens to the position; you must then collect to receive them.
Earning emissions on your position
Trading fees accrue automatically. To also earn BARK emissions, stake the position NFT into the pool's gauge — see ve(3,3): lock, vote, earn.
Gotchas
- Tick alignment.
tickLower/tickUppermust be multiples of the pooltickSpacing, or the mint reverts. ReadtickSpacing()from the pool. - Token order. Always sort
token0 < token1; the NPM does not reorder for you. - Set minimums in production.
amount0Min/amount1Minof0accepts any execution price. - Out-of-range mints. If the current price is outside
[tickLower, tickUpper], you deposit only one of the two tokens.