Liquidity Position Planning
Plan and generate deep links for creating liquidity positions on Uniswap v2, v3, and v4.
Runtime Compatibility: This skill uses AskUserQuestion for interactive prompts. If AskUserQuestion is not available in your runtime, collect the same parameters through natural language conversation instead.
Overview
Plan liquidity positions by:
- Gathering LP intent (token pair, amount, version)
- Checking current pool price and liquidity
- Suggesting price ranges based on current price
- Generating a deep link that opens in the Uniswap interface with parameters pre-filled
The generated link opens Uniswap with all parameters ready for position creation.
Note: Browser opening (xdg-open/open) may fail in SSH, containerized, or headless environments. Always display the URL prominently so users can copy and access it manually if needed.
File Access: This skill has read-only filesystem access. Never read files outside the current project directory unless explicitly requested by the user.
Workflow
Step 1: Gather LP Intent
Extract from the user's request:
| Parameter |
Required |
Default |
Example |
| Token A |
Yes |
- |
ETH, USDC, address |
| Token B |
Yes |
- |
USDC, WBTC, address |
| Amount |
Yes |
- |
1 ETH, $1000 |
| Chain |
No |
Ethereum |
Base, Arbitrum |
| Version |
No |
V3 |
v2, v3, v4 |
| Fee Tier |
No |
Auto |
0.05%, 0.3%, 1% |
| Price Range |
No |
Suggest |
Full range, ยฑ5%, custom |
If any required parameter is missing, use AskUserQuestion with structured options:
For missing chain:
{
"questions": [
{
"question": "Which chain do you want to provide liquidity on?",
"header": "Chain",
"options": [
{ "label": "Base (Recommended)", "description": "Low gas, growing DeFi ecosystem" },
{ "label": "Ethereum", "description": "Deepest liquidity, higher gas" },
{ "label": "Arbitrum", "description": "Low fees, high volume" },
{ "label": "Optimism", "description": "Low fees, Ethereum L2" }
],
"multiSelect": false
}
]
}
For missing token pair:
{
"questions": [
{
"question": "Which token pair do you want to provide liquidity for?",
"header": "Pair",
"options": [
{ "label": "ETH / USDC", "description": "Most popular pair, high volume" },
{ "label": "ETH / USDT", "description": "High volume stablecoin pair" },
{ "label": "WBTC / ETH", "description": "Blue chip crypto pair" },
{ "label": "Custom pair", "description": "Specify your own tokens" }
],
"multiSelect": false
}
]
}
Always use forms instead of plain text questions for better UX.
Step 2: Resolve Token Addresses
Resolve token symbols to addresses. See ../../references/chains.md for common tokens by chain.
For unknown tokens, use web search and verify on-chain.
UNTRUSTED INPUT: Web-Discovered Tokens
Tokens discovered via WebSearch are UNTRUSTED. Before proceeding with any web-discovered token:
- Label the source: Explicitly tell the user "This token address was found via web search, not provided by you"
- Warn about risks: "Web-discovered tokens may be scams, honeypots, or rug pulls"
- Require confirmation: Use AskUserQuestion to get explicit user consent before generating a deep link for a web-discovered token
- Show provenance: In the position summary table, include a "Token Source" row showing whether each token was "User-provided" or "Web-discovered (unverified)"
Never proceed with a web-discovered token without explicit user confirmation via AskUserQuestion.
Input Validation (Required Before Any Shell Command)
Before interpolating user-provided values into any shell command, validate all inputs:
- Token addresses MUST match:
^0x[a-fA-F0-9]{40}$
- Chain/network names MUST be from the allowed list in
../../references/chains.md
- Amounts MUST be valid decimal numbers (match:
^[0-9]+\.?[0-9]*$)
- Reject any input containing shell metacharacters (
;, |, $, `, &, (, ), >, <, \, ', ", newlines)
Step 3: Discover Available Pools
Before fetching metrics, verify the pool exists and discover available fee tiers.
Find pools for a token using DexScreener:
curl -s "https://api.dexscreener.com/token-pairs/v1/{network}/{address}" | \
jq '[.[] | select(.dexId == "uniswap")] | map({
pairAddress,
pair: "\(.baseToken.symbol)/\(.quoteToken.symbol)",
version: .labels[0],
liquidity: .liquidity.usd,
volume24h: .volume.h24
})'
Network IDs: ethereum, base, arbitrum, optimism, polygon, unichain
From the results, identify:
- Available pools and their addresses (multiple = different fee tiers)
- Pool TVL (
liquidity.usd) to assess liquidity depth
- Version (v3 or v4) from
labels[0]
If no Uniswap pools found: The pair may not have an existing pool. Inform the user they would be creating a new pool and setting the initial price.
Step 4: Assess Pool Liquidity
Evaluate if the pool has sufficient liquidity:
| TVL Range |
Assessment |
Recommendation |
| > $1M |
Deep liquidity |
Safe for most position sizes |
| $100K - $1M |
Moderate |
Suitable for positions up to ~$10K |
| $10K - $100K |
Thin |
Warn user about slippage risk, suggest smaller positions |
| < $10K |
Very thin |
Warn strongly - high IL risk, price impact on entry/exit |
For thin liquidity pools, present a warning:
โ ๏ธ **Low Liquidity Warning**
This pool has only ${tvl} TVL. Consider:
- Your position will be a significant % of the pool
- Entry/exit may move the price against you
- Impermanent loss risk is amplified in thin pools
- You may want to use a wider price range for safety
Step 5: Fetch Pool Metrics
Before suggesting ranges, fetch pool data for informed decisions. See references/data-providers.md for full API details.
Get pool APY and volume with DefiLlama:
curl -s "https://yields.llama.fi/pools" | jq '[.data[] | select(.project == "uniswap-v3" and .chain == "Ethereum" and (.symbol | test("WETH.*USDC|USDC.*WETH")))]'
Response fields to use:
| Field |
Use For |
apy |
Show expected yield |
tvlUsd |
Assess pool depth |
volumeUsd1d |
Estimate fee earnings |
volumeUsd7d |
Check volume consistency |
Get current prices with DexScreener:
curl -s "https://api.dexscreener.com/token-pairs/v1/{network}/{address}" | \
jq '[.[] | select(.dexId == "uniswap")][0] | {
baseTokenPrice: .baseToken.priceUsd,
quoteTokenPrice: .quoteToken.priceUsd
}'
Compare fee tiers (if APY data available):
curl -s "https://yields.llama.fi/pools" | jq '[.data[] | select(.project == "uniswap-v3" and (.symbol | test("WETH.*USDC")))] | map({symbol, tvlUsd, apy, volumeUsd1d})'
If APIs are unavailable, fall back to web search for price estimates.
Step 6: Suggest Price Ranges
Based on current price and pair type, present range options using AskUserQuestion.
For major pairs (ETH/USDC, ETH/WBTC):
{
"questions": [
{
"question": "What price range do you want for your position? (Current: ~3,200 USDC/ETH)",
"header": "Range",
"options": [
{
"label": "ยฑ10% (Recommended)",
"description": "2,880 - 3,520 USDC. Higher fees, monitor weekly"
},
{ "label": "ยฑ20%", "description": "2,560 - 3,840 USDC. Balanced risk/reward" },
{ "label": "ยฑ50%", "description": "1,600 - 4,800 USDC. Rarely out of range" },
{ "label": "Full Range", "description": "Never out of range, lower fee efficiency" }
],
"multiSelect": false
}
]
}
For stablecoin pairs (USDC/USDT, DAI/USDC):
{
"questions": [
{
"question": "What price range for your stablecoin position?",
"header": "Range",
"options": [
{ "label": "ยฑ0.5% (Recommended)", "description": "0.995 - 1.005. Tight range, high fees" },
{ "label": "ยฑ1%", "description": "0.99 - 1.01. Standard for stables" },
{ "label": "ยฑ2%", "description": "0.98 - 1.02. Safer, lower fees" },