@steerprotocol/liquidity-meter
v1.0.0
Published
CLI to compute Uniswap v3 market depth bands using real on-chain/subgraph data
Readme
Liquidity Depth CLI
- Compute Uniswap v3 market depth bands (±1/2/5/10% by default) using live on-chain state or subgraph.
- Estimate price impact for given USD trade sizes.
- Batch over many pools from CSV.
- Simulate Steer vault withdrawals on a fork and re-run the analysis “after” to see slippage effects.
Requirements
- Node.js 18+ (uses global fetch and BigInt)
- For on-chain mode: an Ethereum RPC URL in
--rpc(or envRPC_URL) capable of eth_getProof. For Base, preferhttps://developer-access-mainnet.base.org.
Install
- Node module consumers (after publish):
npm install liquidity-meter- ESM-only: import from
liquidity-meterin Node 18+
- Local (from this repo):
npm installnpm run generate && npm run buildnpm link(optional; installsliquidity-depthin your PATH)
ESM Only
- This package ships ESM only. Use Node 18+ and
importsyntax. - Exports:
import { analyzePool, fetchPoolSnapshotViem, computeMarketDepthBands, simulateVaultWithdraw } from 'liquidity-meter'- CLI subpath:
node ./node_modules/liquidity-meter/dist/cli/liquidity-depth.js --help
Quick Start
Single pool (on-chain via Tevm fork):
liquidity-depth --pool 0x8ad599c3a0ff1de082011efddc58f1908eb6e6d8 --rpc https://mainnet.infura.io/v3/<KEY>
Same with JSON output:
liquidity-depth --pool 0x8ad599c3a0ff1de082011efddc58f1908eb6e6d8 --rpc <URL> --json
Subgraph fallback:
liquidity-depth --pool 0x... --source subgraph
Single pool with withdraw simulation (Tevm fork):
liquidity-depth --pool 0xPOOL --vault 0xVAULT --owner 0xOWNER --withdraw-pct 25 --rpc https://developer-access-mainnet.base.org --usd-sizes 1000,5000,10000
Tevm (On-Chain Fork)
- Default source is
tevm. The tool forks atlatestfrom--rpcand reads the pool directly. - We suppress EVM logs in reports and mine blocks deterministically for post-action state.
- If you see “distance to target block exceeds maximum proof window,” use a provider with proof support or a more recent block (we default to
latest).
Batch via CSV
- Run the CLI over many pools and write a per-pool report:
liquidity-depth --csv "/path/to/file.csv" --outdir ./reports --rpc <URL>- Reliability flags for large batches / flaky providers:
--throttle-ms Nadd delay between rows and retries--retries Nretry transient JSON-RPC failures (e.g.,-32000, proof window,429)
- CSV header expectations:
- Pool address: prefer one of
pool,address,pool_address,id(addresses embedded in URLs are auto-detected). - If no pool address is present, provide
token0,token1, andfee, and with--rpcthe tool will resolve the pool using the Uniswap v3 factory. - Optional per-row overrides:
rpc,source,percent,token0_usd,token1_usd,usd_sizes,assume_stable,prices. - Steer vault simulation columns (optional):
vault(aliases:vault_address,vault address,strategy)owner(aliases:owner_address,owner address,withdraw_owner,account,user,recipient,to)withdraw_pct(aliases:withdraw percent,withdraw_percent,withdrawPercentage,withdrawPercent,pct_withdraw,percent_withdraw)withdraw_shares(aliases:withdraw shares,withdrawShares,shares_to_withdraw,withdraw_share_amount)
- Pool address: prefer one of
- Output:
- Writes one file per pool in
--outdir(defaultreports), named<pool>.txtor<pool>.jsonwhen--jsonis set.
- Writes one file per pool in
CSV example
pool,vault,owner,withdraw_pct,usd_sizes
0x8ad599c3a0ff1de082011efddc58f1908eb6e6d8,0xYourVault,0xYourOwner,25,"1000,5000,10000"Simulating Steer Vault Withdrawals (Before/After)
- Adds an “after” section by impersonating an owner on a Tevm fork, withdrawing shares from the Steer vault, mining, then re-running the analysis.
- Global flags:
--vault <VAULT_ADDRESS>: Vault to withdraw from (per-row CSV overrides supported).--owner <ADDRESS>: Address whose shares are withdrawn (or envOWNER).--withdraw-pct <N>: Percent of owner’s current share balance to withdraw (e.g., 25).--withdraw-shares <RAW>: Raw share amount (overrides percent).
- The withdraw is simulated on the fork only. We top up owner gas, impersonate the owner, call
withdraw(shares,0,0,owner), then mine 1 block. - Example (CSV with a
vaultcolumn):OWNER=0xYourOwner liquidity-depth --csv "/path/file.csv" --outdir ./reports --rpc <URL> --withdraw-pct 25
Debug logging for withdraws
- Pass
--debugto print a concise audit trail to stderr without polluting report files:- Planned shares and percent, owner’s current shares and vault total supply.
- Owner and vault token balances before/after (formatted with decimals + symbol).
- Owner deltas received for token0/token1.
- Transaction hash on submit, then
[after]changes to tick and in-range liquidity. - A pool mismatch notice if
vault.pool()differs from CLI--pool.
Text Output (Summary)
- Shows pool, token symbols/addresses, tick, fee, inferred or fetched USD prices, range of examined ticks, cumulative USD depth per bucket, headline ±2% depth, and optional price impact lines for USD sizes.
- If a withdrawal is simulated, an “— After Withdraw —” section prints the same summary after state changes.
JSON Output
- Without simulation: prints a single object with fields:
pool,tokens.token0/1,ethPriceUSD,tick,sqrtPriceX96,liquidity,feePips,range,percentBuckets,prices,buyCumToken1[],sellCumToken0[], and metrics fromcomputeMarketDepthBandsplus optionalpriceImpacts.
- With simulation: prints
{ before: {...}, after: {...} }with the same structure on each side. BigInts are stringified in arrays.
Options (Reference)
--pool/-p: Uniswap v3 pool address.--percent/-b: Comma-separated percent buckets (default:1,2,5,10).--source:tevm|subgraph|auto(default:tevm).--rpc/-r: RPC URL for Tevm fork (or envRPC_URL).--subgraph/-s: Subgraph URL (defaults to Uniswap v3 mainnet).--token0-usd/--token1-usd: Manual USD prices.--assume-stable 0|1: Assume token index is $1 stable when USD not supplied/inferred.--usd-sizes: Comma-separated USD sizes for price impact (token1 buys, token0 sells).--prices:reserve|dexscreener|llama|coingecko|auto(default:auto; envPRICES_SOURCE).--reserve-limit: Limit for Reserve API (default:100; envRESERVE_LIMIT).--throttle-ms: Delay between CSV rows & retries (ms).--retries: Retries per row on transient RPC errors (default:0).--csv: CSV file with pool/vault rows.--outdir: Output directory (default:reports).--json/-j: Emit machine-readable JSON.--debug: Print pricing/inference debug logs to stderr.--vault,--owner,--withdraw-pct,--withdraw-shares: Steer vault withdraw simulation (see above).
Pricing Sources
- If manual USD prices aren’t provided, the tool tries (in
automode): Reserve (if chainId known), Dexscreener (if chainId known), DeFiLlama, Coingecko. - ChainId is resolved via the provided RPC. Coingecko can be rate-limited without an API key.
RPC Guidance (Proof Window)
- Tevm forks and then reads state using proofs from your RPC. Some providers only serve proofs for a recent block window.
- If you see: “distance to target block exceeds maximum proof window,” switch to a proof-capable provider or ensure you fork at
latest(default). - Recommended for Base:
https://developer-access-mainnet.base.org.
Troubleshooting
- Missing
--rpcin tevm mode: supply--rpcor setRPC_URL. - CSV row errors write a file named
error-<pool>.txtin--outdir. - If owner has 0 vault shares at the forked block, the withdraw step is skipped.
- If a vault does not expose
pool()or withdraw reverts, the run fails for that row only. - Logs: Reports strip noisy EVM logs; use
--debugfor pricing diagnostics. - zsh/newlines: keep command arguments on a single line (e.g., do not split
--rpcURL across lines).
Examples
- Single pool on-chain:
liquidity-depth --pool 0x8ad599c3a0ff1de082011efddc58f1908eb6e6d8 --rpc https://mainnet.infura.io/v3/<KEY> --usd-sizes 1000,5000,10000
- Batch CSV:
liquidity-depth --csv "/path/to/file.csv" --outdir ./reports --rpc https://developer-access-mainnet.base.org --usd-sizes 1000,5000,10000,25000,50000,100000- With backoff and retries:
liquidity-depth --csv "/path/to/file.csv" --outdir ./reports --rpc https://developer-access-mainnet.base.org --usd-sizes 1000,5000,10000,25000,50000,100000 --throttle-ms 500 --retries 2
- Batch with withdraw simulation for a single owner across all rows:
OWNER=0xYourOwner liquidity-depth --csv "/path/to/file.csv" --outdir ./reports --rpc https://developer-access-mainnet.base.org --withdraw-pct 25 --usd-sizes 1000,5000,10000
Programmatic API
- One-call analysis (before/after) with price inference and optional withdraw simulation:
import { analyzePool } from 'liquidity-meter'
const res = await analyzePool({
poolAddress: '0x11e26bbd1a5547895a50fc39a2d4c0025dec0bda',
source: 'tevm', // or 'subgraph' | 'auto'
rpcUrl: 'https://developer-access-mainnet.base.org',
percentBuckets: [1, 2, 5, 10],
usdSizes: [1000, 5000, 10000, 25000],
prices: 'auto', // reserve | dexscreener | llama | coingecko | auto
withdraw: { // optional; TEVM only
vault: '0xYourVault',
owner: '0xYourOwner',
withdrawPct: 25, // or: withdrawShares: '1230000000000000000'
},
})
console.log(res.before.metrics.depthPlus2USD)
console.log(res.after?.metrics.depthPlus2USD)- Lower-level building blocks (for custom flows):
import {
fetchPoolSnapshotViem, // TEVM on-chain snapshot
fetchPoolSnapshot as fetchFromSubgraph,
computeMarketDepthBands,
computePriceImpactsBySizes,
fetchTokenUSDPrices,
simulateVaultWithdraw, // TEVM withdraw sim
} from 'liquidity-meter'Notes & Limitations
- No transactions are sent to mainnet; all simulations run on a local fork.
- Certain deposit transaction types (e.g., EIP-7702/OP Stack deposits) may be filtered in forked blocks; this does not affect pool state reads.
- The tool does not model MEV or off-range liquidity changes between snapshots.
Templates
- This repo includes ready-to-edit CSV templates under
templates/:templates/pools_minimal.csvtemplates/pools_with_vault.csv
- Copy one and fill in your addresses, then run (example):
liquidity-depth --csv ./templates/pools_with_vault.csv --outdir ./reports --rpc https://developer-access-mainnet.base.org
