zap-fast
KyberSwap Fast Zap Skill
⚠️ VIGILANT WARNING — EXTREME CAUTION REQUIRED ⚠️
This skill builds AND executes zap-in transactions IMMEDIATELY without any confirmation. Once executed, transactions are IRREVERSIBLE and cannot be cancelled.
Critical Risks:
- NO CONFIRMATION — Transaction broadcasts the instant this skill runs
- IRREVERSIBLE — Blockchain transactions cannot be undone
- REAL MONEY AT STAKE — Gas fees are charged even if the zap fails
- NO QUOTE VERIFICATION — You cannot review the zap route before execution
- NO SECOND CHANCE — Wrong parameters or bad rates will still execute
- IMPERMANENT LOSS — Providing liquidity carries impermanent loss risk
- ACTIVE MANAGEMENT — Concentrated liquidity positions require active management
Before Using This Skill, Ensure:
- You have double-checked all zap parameters (token, amount, pool, ticks, chain)
- You understand this sends a real transaction immediately
- You have sufficient gas fees in your wallet
- You understand the risks of providing concentrated liquidity
- You have used
/zapbefore to understand typical zap outputs
When NOT to Use This Skill:
- High-value transactions (> $1,000 USD equivalent) — Use
/zapwith confirmation instead - First time using these skills
- When you want to review the zap route before executing
- When you're unsure about any zap parameter (pool address, tick range, dex)
- Volatile market conditions
If the estimated zap value exceeds $1,000 USD, refuse fast execution and recommend the user use /zap with confirmation prompts instead.
Safer Alternatives:
- Use
/zapfor step-by-step zap with confirmation and route review
Build and execute a zap-in transaction in one step using the shell script at ${CLAUDE_PLUGIN_ROOT}/skills/zap-fast/scripts/execute-zap.sh. The script calls fast-zap.sh internally to build the zap route, then immediately broadcasts it. No confirmation prompts.
Important: The ZaaS router address is different from the Aggregator router. The script verifies 0x0e97c887b61ccd952a53578b04763e7134429e05.
Prerequisites
- Foundry installed:
castmust be available in PATH - curl and jq installed: Required for API calls
- Wallet configured: See
${CLAUDE_PLUGIN_ROOT}/skills/swap-execute/references/wallet-setup.md
Wallet setup: See
${CLAUDE_PLUGIN_ROOT}/skills/swap-execute/references/wallet-setup.mdfor wallet configuration options (keystore, env, Ledger, Trezor).
Input Parsing
The user will provide input like:
fast zap 1 ETH into pool 0xPool123... on uniswapv3 ticks -887220 to 887220 on arbitrum from 0xAbc123...instant zap 100 USDC into 0xPool456... pancakev3 ticks -100 100 on base from 0xAbc123... slippage 50skip confirmation and zap 0.5 WETH into 0xPool789... uniswapv3 -1000 1000 polygon 0xAbc123...
Extract these fields:
- tokenIn — the input token symbol or address:decimals
- amountIn — the human-readable amount to zap
- poolAddress — the pool contract address (0x...)
- dex — the DEX identifier (e.g.
uniswapv3,pancakev3). The script normalizes shorthand to API format (e.g.uniswapv3→DEX_UNISWAPV3) - tickLower — lower tick of the position (integer, may be negative)
- tickUpper — upper tick of the position (integer, may be negative)
- chain — the chain slug (default:
ethereum) - sender — the address that will send the transaction (required)
- slippageTolerance — slippage in basis points (default: 100)
- walletMethod —
keystore,env,ledger, ortrezor(default:keystore) - keystoreName — keystore account name (default:
mykey)
If the sender address is not provided, ask the user for it before proceeding. Do not guess or use a placeholder address.
Sender address validation: See ${CLAUDE_PLUGIN_ROOT}/references/address-validation.md for validation rules.
Slippage Defaults
If the user does not specify slippage, choose based on the token:
| Token type | Default | Rationale |
|---|---|---|
| Stablecoin (e.g. USDC, USDT) | 50 bps (0.50%) | Low volatility but zaps involve multiple steps |
| Common tokens (e.g. ETH, WBTC) | 100 bps (1.00%) | Standard volatility buffer for multi-step zap |
| All other / unknown tokens | 100 bps (1.00%) | Conservative default for long-tail or volatile tokens |
Why higher than
/zap? These defaults are intentionally higher than/zap(which uses 5/50/100 bps) because fast execution has no confirmation gate — higher slippage reduces the chance of transaction failure.
Note: The underlying
execute-zap.shscript defaults to 100 bps if no slippage argument is passed. You must calculate and pass the correct slippage value from this table as argument 9 when calling the script.
Known stablecoins: USDC, USDT, DAI, BUSD, FRAX, LUSD, USDC.e, USDT.e, TUSD Known common tokens: ETH, WETH, WBTC, BTC, BNB, MATIC, POL, AVAX, S
Workflow
Pre-Step: Verbal Confirmation Required
CRITICAL: Before running any script or making any API call, you MUST confirm with the user:
You are about to execute a zap-in IMMEDIATELY with no confirmation step. The transaction will be broadcast as soon as the zap route is found. Providing liquidity carries impermanent loss risk and concentrated positions require active management. Proceed? (yes/no)
Wait for the user to explicitly respond with "yes", "proceed", "confirm", or a clear affirmative. If the user says "no", "cancel", "wait", or anything non-affirmative, abort and recommend they use /zap instead for a safer flow with route review.
Do NOT skip this confirmation. Do NOT assume consent. This is the only safety gate before an irreversible transaction.
Step 0: Dust Amount Pre-Check
Before running the script, sanity-check the zap amount. If the amount is obviously a dust amount (e.g., 0.0000000001 ETH), warn the user and abort — the script will reject dust amounts (< $0.10 USD or gas > zap value) anyway. Catching it early avoids unnecessary API calls.
"This zap amount is extremely small. Gas fees will far exceed the zap value. Use a larger amount."
Step 0.5: Resolve Token Address
Resolve tokenIn before running the script.
- Check
${CLAUDE_PLUGIN_ROOT}/references/token-registry.mdfor the token on the specified chain - If found — pass the symbol to the script (e.g.
ETH,USDC). The script resolves it internally. - If NOT found — use the fallback sequence in
${CLAUDE_PLUGIN_ROOT}/references/token-registry.md(Section "Token Not Listed?"). Pass resolved token asaddress:decimalsformat.
For any non-registry token, check honeypot/FOT via the API in ${CLAUDE_PLUGIN_ROOT}/references/api-reference.md (Honeypot/FOT section):
- If
isHoneypot: true— refuse the zap and warn the user. - If
isFOT: true— warn about fee-on-transfer tax. Proceed only if acknowledged.
Step 0.6: DEX Auto-Detection (when DEX is not specified)
If the user provides a pool address but does not specify the DEX, use the KyberSwap Earn Service API to identify it.
Query the pool:
GET https://earn-service.kyberswap.com/api/v1/explorer/pools?chainIds={chainId}&page=1&limit=1&interval=24h&q={poolAddress}
Via WebFetch. This works for both V3 pool addresses (20-byte) and V4 pool IDs (32-byte).
From the response, extract the exchange field and map it to the ZaaS dex parameter:
exchange value |
ZaaS dex parameter |
|---|---|
uniswapv3 |
DEX_UNISWAPV3 |
uniswap-v4 |
DEX_UNISWAP_V4 |
pancake-v3 |
DEX_PANCAKESWAPV3 |
sushiswap-v3 |
DEX_SUSHISWAPV3 |
aerodrome-cl |
DEX_AERODROMECL |
camelot-v3 |
DEX_CAMELOTV3 |
General rule: Uppercase the exchange value, replace - with _, prefix with DEX_. Cross-reference with ${CLAUDE_PLUGIN_ROOT}/references/dex-identifiers.md for the canonical list.
If the pool is not indexed (0 results), ask the user to specify the DEX manually.
See ${CLAUDE_PLUGIN_ROOT}/skills/pool-info/SKILL.md for the full API reference.
Step 0.65: Determine Tick Spacing for Uniswap V4 Pools
When a user requests "full range" for a Uniswap V4 pool, you need the pool's tick spacing to compute the correct tickLower/tickUpper. In V4, tick spacing is a free parameter (not fixed per fee tier like V3), so you must query it.
Approach — call poolKeys on the Uniswap V4 PositionManager:
The PositionManager contract has a public poolKeys(bytes25) function that returns the full PoolKey struct including tick spacing:
poolKeys(bytes25 poolId) returns (address currency0, address currency1, uint24 fee, int24 tickSpacing, address hooks)
Important: The PositionManager uses bytes25 (the first 25 bytes of the 32-byte pool ID). When calling, truncate the pool ID to 25 bytes (keep 0x + first 50 hex characters).
Cast command:
export FOUNDRY_DISABLE_NIGHTLY_WARNING=1
# Truncate 32-byte pool ID to 25 bytes: keep first 50 hex chars after 0x
POOL_ID_25="0x$(echo '<POOL_ID_32>' | sed 's/^0x//' | cut -c1-50)"
cast call <POSITION_MANAGER_ADDRESS> \
"poolKeys(bytes25)(address,address,uint24,int24,address)" \
"$POOL_ID_25" \
--rpc-url <RPC_URL>
The 4th return value is tickSpacing (int24).
Example — Arbitrum pool 0xd88f3...d869:
# Full pool ID: 0x4fd69d55704d8c40ebbd6d0086f1c827eed02bfb4a42cea8aafda66b45dab22e
# Truncated to bytes25: 0x4fd69d55704d8c40ebbd6d0086f1c827eed02bfb4a42cea8aa
cast call 0xd88f38f930b7952f2db2432cb002e7abbf3dd869 \
"poolKeys(bytes25)(address,address,uint24,int24,address)" \
0x4fd69d55704d8c40ebbd6d0086f1c827eed02bfb4a42cea8aa \
--rpc-url https://arb1.arbitrum.io/rpc
# Result: tickSpacing = 1
Uniswap V4 PositionManager addresses:
| Chain | PositionManager Address |
|---|---|
| Ethereum | 0xbd216513d74c8cf14cf4747e6aaa6420ff64ee9e |
| Arbitrum | 0xd88f38f930b7952f2db2432cb002e7abbf3dd869 |
| Base | 0x7c5f5a4bbd8fd63184577525326123b519429bdc |
| Optimism | 0x3c3ea4b57a46241e54610e5f022e5c45859a1017 |
| Polygon | 0x1ec2ebf4f37e7363fdfe3551602425af0b3ceef9 |
Do NOT rely on an lpFee-to-tickSpacing mapping. Unlike Uniswap V3 (which had fixed mappings like 500->10, 3000->60, 10000->200), V4 allows arbitrary tick spacing as a free parameter in the PoolKey. For example, a pool can have fee=50 (0.005%) with tickSpacing=1. Always query poolKeys on the PositionManager.
Step 0.7: Price Context
Before executing the fast zap, fetch the current USD price of the input token to validate the zap value. Use the KyberSwap Aggregator:
GET https://aggregator-api.kyberswap.com/{chain}/api/v1/routes?tokenIn={tokenAddress}&tokenOut={usdcAddress}&amountIn={oneUnitInWei}&source=ai-agent-skills
Via WebFetch. Use the USDC address from ${CLAUDE_PLUGIN_ROOT}/references/token-registry.md for the given chain. If USDC route fails, try USDT.
Calculate and display:
tokenPriceUsd = amountOut / 10^6
zapValueUsd = tokenPriceUsd * amountIn
Display to the user before proceeding:
Zap value: {amountIn} {token} ~ ${zapValueUsd} USD (1 {token} = ${tokenPriceUsd})
This helps catch errors like accidentally zapping 100 ETH instead of 0.1 ETH, or zapping a token whose price has collapsed.
Warn if price seems wrong:
- If
zapValueUsd> $1,000 and the user hasn't explicitly acknowledged, the script's built-in $1,000 threshold will block it anyway. But showing the USD value upfront helps the user catch mistakes before the script runs. - If the USD price is
0or route fails, warn: "Could not fetch USD price for {token}. Cannot validate zap value. Proceed with extra caution."
If both USDC and USDT routes fail, skip the price check with a note and proceed.
Tip: Use
/token-info {token} on {chain}to check current prices before zapping.
Step 1: Run the Script
Execute the script:
bash ${CLAUDE_PLUGIN_ROOT}/skills/zap-fast/scripts/execute-zap.sh <tokenIn> <amountIn> <poolAddress> <dex> <tickLower> <tickUpper> <chain> <sender> [slippage_bps] [wallet_method] [keystore_name]
Arguments (positional):
| # | Name | Required | Description |
|---|---|---|---|
| 1 | tokenIn |
Yes | Input token symbol (e.g. ETH, USDC) or pre-resolved address:decimals (e.g. 0xA0b8...:6) |
| 2 | amountIn |
Yes | Human-readable amount (e.g. 1, 0.5, 100) |
| 3 | poolAddress |
Yes | Pool contract address (0x + 40 hex chars) |
| 4 | dex |
Yes | DEX identifier — shorthand (uniswapv3) or API format (DEX_UNISWAPV3). Script auto-normalizes. |
| 5 | tickLower |
Yes | Lower tick of the position (integer, may be negative) |
| 6 | tickUpper |
Yes | Upper tick of the position (integer, may be negative) |
| 7 | chain |
Yes | Chain slug (e.g. ethereum, arbitrum, base) |
| 8 | sender |
Yes | Sender wallet address |
| 9 | slippage_bps |
No | Slippage in basis points (default: 100) |
| 10 | wallet_method |
No | keystore, env, ledger, trezor (default: keystore) |
| 11 | keystore_name |
No | Keystore account name (default: mykey) |
Note: Arguments 9-11 use snake_case (shell convention) for the script's positional parameters. When parsing user input, map from the camelCase names above (slippageTolerance -> slippage_bps, walletMethod -> wallet_method, keystoreName -> keystore_name).
Examples:
# Known token (symbol) -- script resolves internally
bash execute-zap.sh ETH 1 0xPoolAddress uniswapv3 -887220 887220 arbitrum 0xYourAddress
# Pre-resolved token (address:decimals) -- skips script resolution
bash execute-zap.sh 0xaf88d065e77c8cC2239327C5EDb3A432268e5831:6 100 0xPoolAddress uniswapv3 -100 100 arbitrum 0xYourAddress
# Specify all options
bash execute-zap.sh USDC 100 0xPoolAddress pancakev3 -100 100 base 0xYourAddress 50 keystore mykey
# Using Ledger hardware wallet
bash execute-zap.sh ETH 1 0xPoolAddress uniswapv3 -887220 887220 base 0xYourAddress 100 ledger
# Using env private key
bash execute-zap.sh ETH 0.5 0xPoolAddress uniswapv3 -1000 1000 polygon 0xSender 100 env
Step 2: Parse the Output
On success (ok: true):
{
"ok": true,
"chain": "arbitrum",
"txHash": "0x1234567890abcdef...",
"blockNumber": "12345678",
"gasUsed": "485432",
"status": "1",
"explorerUrl": "https://arbiscan.io/tx/0x1234...",
"zap": {
"tokenIn": {"symbol": "ETH", "amount": "1"},
"poolAddress": "0xPoolAddress...",
"dex": "uniswapv3",
"tickLower": "-887220",
"tickUpper": "887220",
"slippageBps": "100"
},
"tx": {
"sender": "0xYourAddress",
"router": "0x0e97c887b61ccd952a53578b04763e7134429e05",
"value": "1000000000000000000"
},
"walletMethod": "keystore"
}
On error (ok: false):
{
"ok": false,
"error": "Zap failed (pre-flight): Build failed -- ZaaS route error (4008): Route not found. No transaction was submitted."
}
Step 3: Format the Output
IMPORTANT: Do not duplicate output. The script's raw output (stderr log lines and stdout JSON) is already visible to the user from the Bash tool call in Step 1. Do NOT echo, quote, or re-display the raw script output. Only present the formatted summary below, which extracts key fields from the JSON. If you repeat the raw output AND show the formatted summary, the user sees every line twice.
On success, present:
## Transaction Executed
**Zapped {zap.tokenIn.amount} {zap.tokenIn.symbol} into {zap.dex} pool** on {chain}
| Field | Value |
|-------|-------|
| Transaction Hash | `{txHash}` |
| Block Number | {blockNumber} |
| Gas Used | {gasUsed} |
| Status | {status == "1" ? "Success" : "Failed"} |
| Pool | `{zap.poolAddress}` |
| DEX | {zap.dex} |
| Tick Range | [{zap.tickLower}, {zap.tickUpper}] |
| Slippage | {zap.slippageBps/100}% |
**Explorer:** [{explorerUrl}]({explorerUrl})
> ⚠️ This transaction was executed immediately without confirmation. If this was a mistake, you cannot undo it. Remember that concentrated liquidity positions require active management and carry impermanent loss risk.
On error, check the error prefix to determine what happened:
"Zap failed (pre-flight): ..."— No transaction was submitted on-chain. No gas was spent. Fix the issue and retry."Transaction was broadcast but ..."— A real transaction was sent. Gas fees were consumed. Check the block explorer for details.
Environment Variables
| Variable | Description |
|---|---|
PRIVATE_KEY |
Private key (required if wallet_method=env) |
KEYSTORE_PASSWORD_FILE |
Override default ~/.foundry/.password |
RPC_URL_OVERRIDE |
Override chain RPC URL |
FAST_ZAP_MAX_USD |
Override $1000 USD safety threshold (default: 1000) |
EXPECTED_ZAP_ROUTER_OVERRIDE |
Override expected ZapRouter address for verification (e.g., for Uniswap V4 pools that return the V4 PositionManager instead of the standard ZapRouter) |
Supported Chains
See ${CLAUDE_PLUGIN_ROOT}/references/supported-chains.md (ZaaS section) for the full chain list. ZaaS supports 13 chains.
Supported DEX Identifiers
See ${CLAUDE_PLUGIN_ROOT}/references/dex-identifiers.md for the complete list of 71 supported DEX IDs.
Important Notes
- EXTREMELY DANGEROUS: This skill builds AND executes in one step with NO confirmation
- Irreversible: Once sent, transactions cannot be cancelled
- Gas fees: Charged even if the zap fails (e.g., slippage exceeded)
- Impermanent loss: Providing liquidity carries impermanent loss risk
- Active management: Concentrated liquidity positions require active management
- ZaaS router: The ZaaS router address (
0x0e97c887b61ccd952a53578b04763e7134429e05) is different from the Aggregator router. The script verifies this address. - Ledger/Trezor: Still requires physical button press on the device
- ERC-20 tokens: The script automatically checks allowance and token balance before executing. If insufficient, it aborts with an actionable error. Approvals must be granted to the ZapRouter, NOT the Aggregator router.
- Balance pre-check: Native token balance is verified against tx.value + estimated gas cost before sending. ERC-20 balance is checked against amountInWei.
- Gas buffer: A 20% buffer is applied to the API gas estimate to reduce out-of-gas failures.
- Gas price: Current gas price is logged so you can see what you're paying.
- For safer execution, use
/zap(has confirmation steps)
Common Errors
Pre-Flight Errors (no transaction sent, no gas spent)
These errors appear with the prefix "Zap failed (pre-flight): ..." in the script output.
| Error | Cause | Quick Fix |
|---|---|---|
| ZaaS route error | No liquidity or unsupported pool/dex | Verify pool address and dex identifier are correct. Try a different pool. |
| Token not found | Wrong token symbol or unsupported token | Verify the token symbol and chain are correct. |
| Invalid pool address | Pool address format is wrong | Ensure pool address is 0x + 40 hex characters. |
| Invalid tick values | Ticks are not valid integers | Ensure tickLower and tickUpper are integers. tickLower must be less than tickUpper. |
| Unsupported chain for ZaaS | Chain not in the 13 supported chains | Use one of: ethereum, bsc, arbitrum, polygon, optimism, avalanche, base, linea, sonic, berachain, ronin, scroll, zksync. |
| Insufficient allowance | ERC-20 approval too low for ZapRouter | Approve the ZapRouter (0x0e97c887b61ccd952a53578b04763e7134429e05) to spend the input token. |
| Insufficient token balance | Sender doesn't hold enough of the input token | The script detects this and aborts. Check balance. |
| Dust amount detected | Zap value < $0.10 USD | Use a larger amount. Gas fees dwarf the zap value. |
| Uneconomical zap | Gas cost > zap value | Use a larger amount to make the trade worthwhile. |
| Zap value exceeds threshold | Value > $1000 USD (configurable) | Use /zap with confirmation for large amounts. Set FAST_ZAP_MAX_USD to override. |
On-Chain Errors (transaction sent, gas spent)
These errors appear with the prefix "Transaction was broadcast but ..." in the script output.
| Error | Cause | Quick Fix |
|---|---|---|
TRANSFER_FROM_FAILED |
Approval revoked or race condition | Re-approve the ZapRouter and retry. |
| Out of gas | Gas limit insufficient for the zap route | The script adds a 20% buffer, but complex zap routes may need more. Set RPC_URL_OVERRIDE to a faster RPC and retry. |
| Reverted | Pool state changed between route fetch and execution | Increase slippage or retry quickly. |
Troubleshooting
For errors not covered above (full API error catalog, advanced debugging), refer to ${CLAUDE_PLUGIN_ROOT}/skills/error-handling/SKILL.md.
Common script-level errors:
| Error | Solution |
|---|---|
cast not found |
Install Foundry: download a verified release from github.com/foundry-rs/foundry/releases and verify the checksum before running |
Password file not found |
Create ~/.foundry/.password with your keystore password |
PRIVATE_KEY not set |
Export PRIVATE_KEY=0x... or use keystore method |
Unknown chain |
Set RPC_URL_OVERRIDE environment variable |
Unexpected router address |
The API returned a different router than expected. This is a safety check. For Uniswap V4 pools, the API returns the V4 PositionManager instead of the standard ZapRouter — set EXPECTED_ZAP_ROUTER_OVERRIDE to the V4 PositionManager address for the target chain (e.g., 0x7C5f5A4bBd8fD63184577525326123B519429bDc on Base). If KyberSwap deployed a new ZapRouter, set the override accordingly. |
More from kybernetwork/kyberswap-skills
swap-execute-fast
This skill should ONLY be used when the user explicitly asks for immediate, no-confirmation execution using phrases like "fast swap", "execute immediately", "swap with no confirmation", "quick swap now", "instant execute", or "skip confirmation and swap". The user must clearly indicate they want to bypass the review/confirmation step. Do NOT use this skill if the user mentions wanting to review, confirm, check, or verify before executing — use swap-build + swap-execute instead. Do NOT use this skill for general swap requests like "swap ETH to USDC" or "trade tokens" — those should go to swap-build. This skill runs a shell script that builds the swap via fast-swap.sh then immediately broadcasts the transaction. DANGEROUS - no confirmation before sending real transactions.
19swap-execute
This skill should be used when the user asks to "execute swap", "send swap transaction", "submit swap", "broadcast swap", "run the swap", "execute the trade", or wants to submit a previously built swap transaction on-chain. Uses Foundry's `cast send` to broadcast transactions. Requires swap calldata from swap-build skill output.
17swap-build
This skill should be used when the user asks to "swap-build", "build a swap transaction", "build swap calldata", "create swap tx", "swap tokens", "trade crypto", "execute a token exchange", "swap ETH to USDC", "convert tokens", or needs encoded calldata for on-chain submission. Fetches the best route and builds transaction data via KyberSwap Aggregator.
16error-handling
Handle errors when swapping tokens through KyberSwap Aggregator API
16quote
This skill should be used when the user asks to "get a swap quote", "check swap price", "compare token rates", "see exchange rates", "how much would I get for", "price check", or wants to know the expected output for a token trade. Fetches the best route from KyberSwap Aggregator across 18 EVM chains.
15zap
This skill should be used when the user asks to "zap into a pool", "add liquidity", "zap in", "provide liquidity", "LP into", "zap out", "remove liquidity from pool", "withdraw from position", "migrate position", "move liquidity", "migrate LP", "rebalance position", or wants to add, remove, or migrate liquidity in concentrated liquidity pools in one transaction. Uses KyberSwap Zap as a Service (ZaaS) API to handle token ratio calculation, swaps, and deposits in a single transaction across 13 EVM chains.
3