Uniswap SDK Bot Integration
Uniswap SDK exists in two incompatible generations: v2 SDK (deprecated, but still alive in ecosystem) and v3 SDK (current standard with Uniswap v3 and v4 support via extensions). Most integration problems start here — when developer mixes concepts or uses outdated code from three-year-old tutorials.
Key difference between v2 and v3 SDK
In v2 SDK pool is just Pair with two tokens and reserve0/reserve1. Price calculated trivially. In v3 SDK pool is Pool with sqrtPriceX96, liquidity and tickCurrent. Price represented in Q64.96 fixed-point format. Calculating output amount requires iterating through tick array accounting for concentrated liquidity in each range.
This means for accurate amountOut calculation for large swap in v3 need to emulate entire tick traversal — exactly what @uniswap/v3-sdk does via SwapMath and TickMath utilities.
Getting current pool state
Typical mistake: taking sqrtPriceX96 and liquidity from one eth_call, and ticks from another. Pool can change state between calls. For trading bot leads to incorrect amountOut calculation and on-chain reverts.
Correct approach — Multicall: get slot0, liquidity and needed ticks in one atomic transaction via IMulticall.
import { Pool, Route, Trade, SwapQuoter } from '@uniswap/v3-sdk'
import { Token, CurrencyAmount, TradeType, Percent } from '@uniswap/sdk-core'
import { ethers } from 'ethers'
const poolContract = new ethers.Contract(poolAddress, IUniswapV3PoolABI, provider)
// Atomic multicall for pool state
const [slot0, liquidity] = await Promise.all([
poolContract.slot0(),
poolContract.liquidity()
])
const pool = new Pool(
tokenA,
tokenB,
fee,
slot0.sqrtPriceX96.toString(),
liquidity.toString(),
slot0.tick
)
For multi-hop routes need separate step — routing. SDK provides AlphaRouter from @uniswap/smart-order-router package, which iterates all possible paths through known pools and finds optimal split.
AlphaRouter vs manual routing
AlphaRouter — convenient for UI, but for trading bot often excessive and slow. It makes dozens of RPC calls to evaluate routes. For bot with hard latency requirements better to either cache routes beforehand or implement own lightweight router only for needed pairs.
In practice we do: pre-computed route cache for top-10 trading pairs (updated every 30 seconds), on swap request — direct calculation from cached route without calling AlphaRouter.
Permit2 and approvals
Since Uniswap Universal Router transition from infinite approve to Permit2 (EIP-2612 extension) — standard. Permit2 — separate contract acting as single allowance manager. User once approves Permit2 for token, then all protocols request transferFrom through Permit2 with signature.
For bot changes workflow: instead of direct token.approve(router, amount) need to sign PermitSingle structure via EIP-712 and pass signature in swap transaction. SDK provides AllowanceTransfer.getPermitData() for generating signature data.
Slippage and deadline
const slippageTolerance = new Percent(50, 10_000) // 0.5%
const deadline = Math.floor(Date.now() / 1000) + 60 * 20 // 20 minutes
const { calldata, value } = SwapRouter.swapCallParameters(trade, {
slippageTolerance,
deadline: deadline.toString(),
recipient: walletAddress
})
For arbitrage bots slippage tolerance should be minimal (0.1% and below) — otherwise attacker can insert sandwich at execution moment. Deadline — short (1–2 minutes): if price moved so much transaction wasn't included 2 minutes, arbitrage conditions likely already stale.
Gas optimization in bot
callStatic before sending: before sending swap transaction execute provider.call() with same data. If reverts — don't waste gas on revert in block.
Gas estimation: estimateGas() returns approximate gas limit. Add 10–20% buffer. Too small limit → revert due to out of gas; too large → suboptimal tip for builders.
Priority fee: for arbitrage bots important to hit block timely. Dynamically calculate maxPriorityFeePerGas based on recent blocks via eth_maxPriorityFeePerGas or Flashbots eth_gasFees.
Uniswap v4 Hooks integration
Uniswap v4 (mainnet 2025) introduces Hooks architecture — arbitrary logic executed before/after swap and liquidity addition. For bots important: hook can change effective amount out or block swap under certain conditions (e.g., if pool protected from MEV via hook dynamic fee).
SDK v4 (in development) provides V4Router with support for new PoolKey format. When working with v4 pools need to pass hookData — data for hook. Without it swap may revert.
Stack and recommended dependencies
| Package | Version | Purpose |
|---|---|---|
@uniswap/v3-sdk |
^3.x | V3 pool calculations |
@uniswap/sdk-core |
^5.x | Token, CurrencyAmount |
@uniswap/smart-order-router |
^3.x | AlphaRouter |
viem |
^2.x | RPC, type safety |
ethers |
^6.x | Signing, sending |
Prefer viem for read-only operations (faster, better TypeScript inference) and ethers.js for transaction signing — more mature ecosystem for wallet management.
Development process
Analytics (1 day). Determine target pairs, bot type (arbitrage, MM, strategy execution), latency requirements.
Development (3–5 days). SDK integration, router, gas management, backtest on historical data via Foundry fork.
Testing and deploy. Test on Sepolia testnet, then mainnet with limited amounts.







