A small, opinionated CLI for poking at Uniswap V3 pools without firing up a subgraph or a notebook.
I use this to answer questions like "what does the liquidity look like around the current tick?", "what's the IL if I LP a [3500, 4500] range and ETH dips 30%?", and "what's the rough fee APR over the last 24h?". It's not a replacement for proper analytics — it's a sanity check that runs in your terminal in under a second.
git clone https://github.com/moxailoo/univ3-pool-lens
cd univ3-pool-lens
npm install
npm run build
npm link # optional, makes `lens` available globallyCopy .env.example to .env and set at least one RPC URL.
# Pool summary — current tick, price, liquidity
lens pool 0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640
# WETH / USDC fee 0.05%
# address 0x88e6…5640
# tick 198543
# price 3742.18 USDC per WETH
# liquidity 12384720394823049823
# IL projection for a [3500, 4500] range
lens range 0x88e6...5640 --lower 196900 --upper 199810
# 24h fee APR estimate
lens fees 0x88e6...5640
# Diff pool state across a window
lens snapshot 0x88e6...5640 --from 21000000 --to 21007200
# Other chains
lens pool 0x... --chain arbitrum
lens pool 0x... --chain base
# JSON output for piping into jq, scripts, dashboards
lens pool 0x... --json | jq '.price' ┌──────────────────────────────────┐
│ CLI (cli.ts) │
└────────────────┬─────────────────┘
│
┌───────────────────────┼───────────────────────┐
▼ ▼ ▼
commands/pool.ts commands/range.ts commands/fees.ts
│ │ │
└───────────┬───────────┴───────────┬───────────┘
▼ ▼
lens/* (pool, ticks, liquidity, il, fees)
│
▼
chain/provider + util/multicall + util/cache
│
▼
ethers.js
The lens/* modules know nothing about the CLI or the chain plumbing — they take a provider and an address and return data. Commands handle formatting. This makes the library easy to import into other projects (notebooks, bots, dashboards) without dragging the CLI along.
| Command | What it does |
|---|---|
lens pool <addr> |
Pool immutables, current tick & price, in-range liquidity |
lens range <addr> |
IL projection + ASCII curve for a [tickLower, tickUpper] position |
lens fees <addr> |
Fee APR estimate from feeGrowthGlobal deltas over a window |
lens snapshot <addr> |
Diff between pool state at two block heights |
Run any command with --json for machine-readable output.
| Env var | Purpose |
|---|---|
ETH_RPC_URL |
Mainnet JSON-RPC endpoint |
ARBITRUM_RPC_URL |
Arbitrum endpoint |
BASE_RPC_URL |
Base endpoint |
OPTIMISM_RPC_URL |
Optimism endpoint |
POLYGON_RPC_URL |
Polygon PoS endpoint |
LENS_CACHE_DIR |
Override the on-disk cache location (default: ./.lens-cache) |
LENS_MULTICALL_BATCH |
Bump multicall chunk size if your RPC can take it |
The cache stores ERC20 metadata for 30 days — symbols and decimals never change, so there's no reason to re-fetch.
If you'd rather skip the CLI:
import { JsonRpcProvider } from "ethers";
import { readImmutables, readState } from "univ3-pool-lens";
const provider = new JsonRpcProvider(process.env.ETH_RPC_URL);
const immut = await readImmutables(provider, "0x88e6...");
const state = await readState(provider, "0x88e6...");
console.log(immut.fee, state.tick);Most of the lens/* exports are stable. The commands/* ones are designed to be CLI-shaped and may change.
- The fee APR estimate is rough. It uses
feeGrowthGlobaldeltas across two blocks, which catches only fees that crossed the global counter — concentrated liquidity in volatile periods can skew this. For real numbers, use the Uniswap V3 subgraph. - No gas-cost modeling in IL projections. Fees offset IL in practice; this tool models them separately.
- Custom-fee pools (those deployed via
enableFeeAmountwith a non-canonical fee) are detected with a warning but otherwise treated normally. - Forked V3 deployments (PancakeSwap V3, etc.) — the math is the same, but the factory addresses in
chain/config.tsare Uniswap-only. Pass any pool address directly and it'll work; the factory address is only used for discovery features which aren't implemented yet.
-
lens position <tokenId>to inspect a specific NFT-LP position -
lens comparefor side-by-side multi-pool diffs - Pull historical fee data from a subgraph when configured
- Optional Vega/Plotly export for IL curves
Math obviously based on the Uniswap V3 whitepaper and the canonical TickMath/SqrtPriceMath libraries. Multicall3 by @mds1.
MIT — see LICENSE.