Uniswap V4

Swap tokens and read pool state on Uniswap V4 (Base, Ethereum). Use when the agent needs to: (1) swap ERC20 tokens or ETH via Uniswap V4, (2) get pool info (price, tick, liquidity, fees), (3) find the best pool for a token pair, (4) quote expected swap output via the on-chain V4Quoter, (5) set up Permit2 approvals for the Universal Router, or (6) execute exact-input swaps with proper slippage protection. Supports Base and Ethereum mainnet, plus Base Sepolia testnet. TypeScript with strict types. Write operations need a private key via env var.

MIT-0 · Free to use, modify, and redistribute. No attribution required.
1 · 1.3k · 3 current installs · 3 all-time installs
MIT-0
Security Scan
VirusTotalVirusTotal
Benign
View report →
OpenClawOpenClaw
Suspicious
medium confidence
Purpose & Capability
The code and SKILL.md align with the stated purpose (reading pool state, quoting, Permit2 approvals, and executing swaps). Requested credentials are proportional (PRIVATE_KEY only for write ops). However, the repository includes multiple auxiliary shell/Python scripts that require external tools (cast/foundry, python3, jq) which are not declared in the top-level 'required binaries' or metadata — this mismatch is unexpected but plausibly explained by providing legacy/auxiliary scripts alongside the TypeScript CLI.
!
Instruction Scope
SKILL.md instructs using the TypeScript entrypoints (npx tsx src/*.ts) and clearly limits private-key usage to env var for write operations. Nonetheless several included shell scripts (e.g., scripts/approve.sh, scripts/swap.sh, scripts/v4_read.py wrappers) invoke external binaries (cast) and pass the PRIVATE_KEY as a CLI argument to those binaries (e.g., --private-key "$PRIVATE_KEY"). Passing private keys as process arguments can expose them in process listings on the host. The presence of both modern TypeScript scripts and older shell/Python wrappers creates ambiguity about which code the agent will actually run; the shell wrappers also rely on default public RPC endpoints. The skill's runtime instructions do not clearly document this duality, which increases risk of accidental key exposure.
Install Mechanism
There is no remote download/install step in the skill metadata (instruction-only install); package.json and package-lock.json indicate normal npm dependencies (ethers, dev tooling). No arbitrary remote archives or shorteners are used. This is low risk from an install-mechanism perspective.
Credentials
The only sensitive environment variable used is PRIVATE_KEY for write operations, which is appropriate for a swap/transaction skill. RPC URL env vars are optional. That said, some scripts implicitly assume availability of foundry/cast and pass PRIVATE_KEY to cast as a CLI argument (see instruction_scope). The skill metadata declares node as required but does not declare cast/python/jq as required even though several scripts require them.
Persistence & Privilege
The skill does not request elevated or persistent platform privileges; always:false and the skill doesn't modify other skills or system-wide config. Autonomous invocation is enabled (normal for skills) but not combined with other high-risk signals.
What to consider before installing
This repo appears to implement the advertised Uniswap V4 functionality and only needs a PRIVATE_KEY for transactions, but review and a few precautions are necessary before using with real funds: - Prefer the TypeScript entrypoints (npx tsx src/pool-info.ts, src/quote.ts, src/approve.ts, src/swap.ts) rather than the included shell wrappers. The SKILL.md emphasizes TypeScript usage; many shell scripts are legacy/auxiliary and rely on external tools. - Inspect src/approve.ts and src/swap.ts to confirm they do not pass PRIVATE_KEY on the command line to external processes. If you must use the shell scripts, note they call 'cast' with --private-key "$PRIVATE_KEY" which can expose the key via process listings; avoid running those scripts with real keys. - Use a secure signer when possible (hardware wallet, remote signer, or ephemeral key) rather than a long-lived raw private key in your shell environment. - Supply your own trusted RPC endpoint (Alchemy/Alchemy-like) rather than public endpoints for sensitive operations; the repo notes public defaults but recommends paid providers for important work. - If you plan to install into an automated agent, run the repository's security scan (node scripts/security-scan.mjs) and run unit/integration tests in a safe environment first. Confirm which script the agent will invoke (TypeScript vs. shell) and ensure the agent runtime has only the minimal required binaries. If you want, I can: (1) inspect src/swap.ts and src/approve.ts specifically and report whether they risk leaking PRIVATE_KEY, or (2) produce a short checklist to safely run swaps (minimize key exposure, RPC selection, dry-run steps).

Like a lobster shell, security has layers — review code before you run it.

Current versionv2.0.4
Download zip
latestvk973s4ehtxphfs2fgtvp5apqb580xtt6

License

MIT-0
Free to use, modify, and redistribute. No attribution required.

SKILL.md

Uniswap V4 🦄

Swap tokens and read pool state on Uniswap V4 via the Universal Router.

Chains: Base (8453), Ethereum (1), Base Sepolia (84532)

ContractBaseEthereum
PoolManager0x498581fF718922c3f8e6A244956aF099B2652b2b0x000000000004444c5dc75cB358380D2e3dE08A90
UniversalRouter0x6ff5693b99212da76ad316178a184ab56d299b430x66a9893cC07D91D95644AEDD05D03f95e1dBA8Af
Permit20x000000000022D473030F116dDEE9F6B43aC78BA30x000000000022D473030F116dDEE9F6B43aC78BA3
StateView0xa3c0c9b65bad0b08107aa264b0f3db444b867a710x7ffe42c4a5deea5b0fec41c94c136cf115597227
V4Quoter0x0d5e0f971ed27fbff6c2837bf31316121532048d0x52f0e24d1c21c8a0cb1e5a5dd6198556bd9e1203

Addresses from docs.uniswap.org/contracts/v4/deployments, verified 2026-02-08.

Decision Tree

  1. Read pool state?src/pool-info.ts (free, no gas, no key)
  2. Get swap quote?src/quote.ts (free, uses on-chain V4Quoter)
  3. Approve tokens?src/approve.ts (write, ~100K gas, needs PRIVATE_KEY)
  4. Execute swap?src/swap.ts (write, ~300-350K gas, needs PRIVATE_KEY)
  5. First time with an ERC20? → Run approve first, or use --auto-approve on swap

Scripts Reference

All scripts in src/. Run with npx tsx. Pass --help for usage.

pool-info.ts — Read Pool State (free)

Returns pool ID, sqrtPriceX96, tick, liquidity, fees, token symbols/decimals. Auto-detects the best pool by liquidity (or specify --fee/--tick-spacing).

npx tsx src/pool-info.ts --token0 ETH --token1 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 --chain base --rpc $BASE_RPC_URL

Env: BASE_RPC_URL or ETH_RPC_URL (or pass --rpc)

quote.ts — Quote Swap Amounts (free)

Quotes exact input amounts via the on-chain V4Quoter contract (simulation, no tx). Returns expected output amount and gas estimate.

npx tsx src/quote.ts \
  --token-in ETH \
  --token-out 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 \
  --amount 10000000000000000 \
  --chain base \
  --rpc $BASE_RPC_URL

Env: BASE_RPC_URL or ETH_RPC_URL

approve.ts — Set Up Token Approvals (write)

Two-step Permit2 flow: ERC20 → Permit2, then Permit2 → Universal Router. Skips if already approved. Only needed for ERC20 tokens (not ETH).

PRIVATE_KEY=0x... npx tsx src/approve.ts \
  --token 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 \
  --chain base \
  --rpc $BASE_RPC_URL \
  --json

Env: PRIVATE_KEY (required), BASE_RPC_URL

swap.ts — Execute Swap (write)

Exact-input swap via Universal Router. Quotes expected output first, applies slippage, then sends the transaction.

PRIVATE_KEY=0x... npx tsx src/swap.ts \
  --token-in ETH \
  --token-out 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 \
  --amount 10000000000000000 \
  --slippage 50 \
  --chain base \
  --rpc $BASE_RPC_URL \
  --json

With auto-approval (sets up Permit2 if needed):

PRIVATE_KEY=0x... npx tsx src/swap.ts \
  --token-in 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 \
  --token-out ETH \
  --amount 25000000 \
  --slippage 100 \
  --auto-approve \
  --chain base \
  --rpc $BASE_RPC_URL

Options: --slippage <bps> (default 50 = 0.5%), --recipient <addr>, --auto-approve, --json Env: PRIVATE_KEY (required), BASE_RPC_URL

Token Input

  • ETH or eth → native ETH (address(0) in V4)
  • Contract address → ERC20 token
  • Common Base tokens: USDC 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913, WETH 0x4200000000000000000000000000000000000006

Environment Variables

VariableUsed ByRequiredDescription
PRIVATE_KEYapprove, swapYes*Wallet private key (never CLI!)
BASE_RPC_URLall (Base)NoBase mainnet RPC URL
ETH_RPC_URLall (Ethereum)NoEthereum mainnet RPC URL
BASE_SEPOLIA_RPC_URLall (testnet)NoBase Sepolia RPC URL

* Only required for write operations. Read operations (pool-info, quote) don't need a key.

V4 Architecture Notes

  • Singleton PoolManager holds all pools in one contract
  • State read via StateView contract (wraps PoolManager storage)
  • Swaps: Universal Router → PoolManager via V4_SWAP command
  • Approvals: ERC20 → Permit2 → Universal Router (two-step)
  • Pool ID: keccak256(abi.encode(currency0, currency1, fee, tickSpacing, hooks))
  • Currency ordering: currency0 < currency1 by numeric value. ETH = address(0)
  • Action sequence: SWAP_EXACT_IN_SINGLE (0x06) + SETTLE_ALL (0x0c) + TAKE_ALL (0x0f)
  • See references/v4-encoding.md for full encoding reference

Error Handling

ErrorCauseFix
No V4 pool foundPair not listed on V4 for this chainCheck token addresses
Quote failedPool exists but can't simulate swapCheck amount, pool may lack liq
PRIVATE_KEY requiredMissing env var for write operationexport PRIVATE_KEY=0x...
No RPC URLMissing RPC configPass --rpc or set env var
Tx revertsInsufficient balance, expired, slippageCheck balance, increase slippage
uint128 maxAmount too large for V4Use smaller amount

SECURITY

  • PRIVATE_KEY must be provided via an environment variable or secret manager only.

  • NEVER paste or send PRIVATE_KEY in chat.

  • NEVER commit PRIVATE_KEY (or .env files) to git.

  • Treat stdout/stderr as public logs (CI, terminals, chat). CI tests ensure the PRIVATE_KEY value is never printed.

  • NEVER pass private keys as CLI arguments (rejected by all scripts)

  • Private keys accepted via PRIVATE_KEY env var only

  • All inputs validated: addresses (format), amounts (BigInt bounds), slippage (0-10000)

  • No eval(), no exec(), no shell commands — pure TypeScript

  • BigInt used everywhere for token amounts (no floating point, no overflow)

Testing

npm run test:unit      # Unit tests (no network)
npm run test:fork      # Fork tests (needs: anvil --fork-url https://mainnet.base.org)
npm run test:testnet   # Testnet reads (Base Sepolia)
npm run test:mainnet   # Mainnet smoke tests (read-only)
npm run security       # Security scan

References

  • V4 encoding reference: references/v4-encoding.md
  • Contract addresses: references/addresses.md
  • V4 architecture: references/v4-architecture.md

Files

36 total
Select a file
Select a file to preview.

Comments

Loading comments…