Skip to content

rickycnsten/univ3-pool-lens

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

37 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Uniswap V3 Pool Lens 🔍

TypeScript Node 20+ License: MIT

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.

Install

git clone https://github.com/moxailoo/univ3-pool-lens
cd univ3-pool-lens
npm install
npm run build
npm link    # optional, makes `lens` available globally

Copy .env.example to .env and set at least one RPC URL.

Quick start

# 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'

Architecture

                ┌──────────────────────────────────┐
                │             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.

Subcommands

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.

Configuration

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.

Library use

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.

Caveats

  • The fee APR estimate is rough. It uses feeGrowthGlobal deltas 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 enableFeeAmount with 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.ts are 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.

Roadmap

  • lens position <tokenId> to inspect a specific NFT-LP position
  • lens compare for side-by-side multi-pool diffs
  • Pull historical fee data from a subgraph when configured
  • Optional Vega/Plotly export for IL curves

Acknowledgments

Math obviously based on the Uniswap V3 whitepaper and the canonical TickMath/SqrtPriceMath libraries. Multicall3 by @mds1.

License

MIT — see LICENSE.

About

A focused TypeScript toolkit for inspecting Uniswap V3 pools — liquidity distribution, fee yield, and impermanent-loss math from your terminal.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • TypeScript 92.5%
  • JavaScript 7.5%