From d7db76b1cd202fbe14d45e18c3fc2b23883907a6 Mon Sep 17 00:00:00 2001 From: James Lawton Date: Wed, 29 Apr 2026 10:56:56 +0100 Subject: [PATCH 1/2] fix: auto-whitelist Aave V3 Pool, enforce 0.1 gas reserve on deposit Moves 0x794a61358d6845594f94dc1db02a252b5b4814ad (Aave V3 Pool) from DEFI_CONTRACTS to AUTO_WHITELISTED_CONTRACTS so it is approved in every new session without needing the --defi flag or a manual --contract flag. Raises the deposit gas reserve from 0.05 to 0.1 and applies it unconditionally regardless of POL balance. Updates SKILL.md and polygon-defi/SKILL.md to reflect both changes and sets the default --usdc-limit baseline to 50. Bumps connector-ui to 1.6.11 to trigger a fresh deploy. --- packages/connector-ui/package.json | 2 +- .../src/commands/operations.ts | 12 ++++----- .../polygon-agent-cli/src/commands/wallet.ts | 8 +++--- skills/SKILL.md | 13 +++++----- skills/polygon-defi/SKILL.md | 26 ++++++++----------- 5 files changed, 29 insertions(+), 32 deletions(-) diff --git a/packages/connector-ui/package.json b/packages/connector-ui/package.json index b8ca831..5aeedbf 100644 --- a/packages/connector-ui/package.json +++ b/packages/connector-ui/package.json @@ -1,7 +1,7 @@ { "name": "@polygonlabs/agent-connector-ui", "private": true, - "version": "1.6.10", + "version": "1.6.11", "type": "module", "description": "Wallet connector UI for Polygon Agent Kit - creates secure encrypted wallet sessions", "repository": { diff --git a/packages/polygon-agent-cli/src/commands/operations.ts b/packages/polygon-agent-cli/src/commands/operations.ts index ff23848..146607d 100644 --- a/packages/polygon-agent-cli/src/commands/operations.ts +++ b/packages/polygon-agent-cli/src/commands/operations.ts @@ -1144,7 +1144,7 @@ export const depositCommand: CommandModule = { try { const viemChain = await viemChainForDeposit(chainId); const publicClient = createPublicClient({ chain: viemChain, transport: http() }); - const [usdcBal, nativeBal] = await Promise.all([ + const [usdcBal] = await Promise.all([ publicClient.readContract({ address: asset.address as `0x${string}`, abi: ERC20_BALANCE_OF_ABI, @@ -1154,7 +1154,7 @@ export const depositCommand: CommandModule = { publicClient.getBalance({ address: walletAddress as `0x${string}` }) ]); const requestedUnits = viemParseUnits(amountArg, asset.decimals); - const GAS_RESERVE = viemParseUnits('0.05', asset.decimals); + const GAS_RESERVE = viemParseUnits('0.1', asset.decimals); if (usdcBal < requestedUnits) { const available = viemFormatUnits(usdcBal, asset.decimals); throw new Error( @@ -1162,18 +1162,18 @@ export const depositCommand: CommandModule = { `Run: polygon-agent balances` ); } - if (nativeBal === 0n && requestedUnits + GAS_RESERVE > usdcBal) { - // Wallet has no POL — USDC paymaster will pay gas; auto-reduce to leave 0.05 buffer + if (requestedUnits + GAS_RESERVE > usdcBal) { + // Always reserve 0.1 for gas regardless of whether POL is available const adjusted = usdcBal - GAS_RESERVE; if (adjusted <= 0n) { throw new Error( - `Insufficient ${assetSymbol} for deposit plus 0.05 gas reserve. ` + + `Insufficient ${assetSymbol} for deposit plus 0.1 gas reserve. ` + `Fund with POL for native gas: polygon-agent fund` ); } amountArg = viemFormatUnits(adjusted, asset.decimals); process.stderr.write( - `Note: reduced deposit to ${amountArg} ${assetSymbol} (0.05 reserved for USDC gas)\n` + `Note: reduced deposit to ${amountArg} ${assetSymbol} (0.1 reserved for gas)\n` ); } } catch (e) { diff --git a/packages/polygon-agent-cli/src/commands/wallet.ts b/packages/polygon-agent-cli/src/commands/wallet.ts index 7bfb937..ba04401 100644 --- a/packages/polygon-agent-cli/src/commands/wallet.ts +++ b/packages/polygon-agent-cli/src/commands/wallet.ts @@ -53,7 +53,10 @@ const AUTO_WHITELISTED_CONTRACTS = [ // Polygon mainnet (chainId 137) — default tokens '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359', // USDC (native) - '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174' // USDC.e (bridged) + '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174', // USDC.e (bridged) + + // Polygon mainnet (chainId 137) — yield vaults (always available for deposit) + '0x794a61358d6845594f94dc1db02a252b5b4814ad' // Aave V3 Pool (all markets) ]; // Additional contracts whitelisted when --defi flag is passed. @@ -63,8 +66,7 @@ const DEFI_CONTRACTS = [ '0xc2132D05D31c914a87C6611C10748AEb04B58e8F', // USDT '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619', // WETH - // Polygon mainnet (chainId 137) — yield vaults - '0x794a61358d6845594f94dc1db02a252b5b4814ad', // Aave V3 Pool (all markets) + // Polygon mainnet (chainId 137) — additional yield vaults '0x781fb7f6d845e3be129289833b04d43aa8558c42', // Morpho Compound USDC '0xf5c81d25ee174d83f1fd202ca94ae6070d073ccf', // Morpho Compound WETH '0x3f33f9f7e2d7cfbcbdf8ea8b870a6e3d449664c2' // Morpho Compound POL diff --git a/skills/SKILL.md b/skills/SKILL.md index e2bcd38..74d854b 100644 --- a/skills/SKILL.md +++ b/skills/SKILL.md @@ -59,13 +59,11 @@ polygon-agent setup --name "MyAgent" # → all subsequent commands auto-load the access key from disk — no export needed # Step 2: Create ecosystem wallet (opens browser, waits for 6-digit code) -# If the user's goal involves DeFi (deposit, yield, swap, Aave, Morpho), include all DeFi -# contracts now so the user only approves once — not again when the deposit is attempted. -polygon-agent wallet create --usdc-limit 100 --native-limit 5 \ - --contract 0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359 \ +# Aave V3 Pool is auto-whitelisted in all sessions. For Morpho or other DeFi vaults, +# add --contract flags as needed. +polygon-agent wallet create --usdc-limit 50 --native-limit 5 \ --contract 0xc2132D05D31c914a87C6611C10748AEb04B58e8F \ --contract 0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619 \ - --contract 0x794a61358d6845594f94dc1db02a252b5b4814ad \ --contract 0x781fb7f6d845e3be129289833b04d43aa8558c42 \ --contract 0xf5c81d25ee174d83f1fd202ca94ae6070d073ccf \ --contract 0x3f33f9f7e2d7cfbcbdf8ea8b870a6e3d449664c2 @@ -162,13 +160,14 @@ polygon-agent agent feedback --agent-id --value [--tag1 ] [--tag - **`balances --chains`** — comma-separated chains (max 20); two or more return JSON with `multiChain: true` and a `chains` array (same wallet address on each) - **Fee preference** — auto-selects USDC over native POL when both available - **`fund`** — returns `https://wallet.polygon.technology` as the `fundingUrl`. Always run `polygon-agent fund` to get the URL and wallet address — never hardcode or construct manually. -- **`deposit`** — picks highest-TVL pool via Trails `getEarnPools` and deposits directly. `wallet create` auto-whitelists USDC, Aave V3 Pool (`0x794a61358d6845594f94dc1db02a252b5b4814ad`), and all standard DeFi contracts — if the user has an older session, re-run `wallet create --usdc-limit 5` before depositing. Full deposit reference: https://agentconnect.polygon.technology/polygon-defi/SKILL.md +- **`deposit`** — picks highest-TVL pool via Trails `getEarnPools` and deposits directly. Aave V3 Pool (`0x794a61358d6845594f94dc1db02a252b5b4814ad`) is auto-whitelisted in all sessions. Full deposit reference: https://agentconnect.polygon.technology/polygon-defi/SKILL.md +- **Gas reserve** — when using `deposit` or any command that spends tokens, always reserve at least 0.1 USDC or 0.1 POL in the wallet for gas. Never attempt to spend the full balance. The `deposit` command enforces a 0.1 reserve automatically, but the agent must apply the same rule when constructing amounts for `send`, `swap`, or direct contract calls. - **`withdraw`** — `--position` = aToken or ERC-4626 vault; `--amount` = `max` or underlying units (Aave / vault). Dry-run JSON includes `poolAddress` / `vault`. Broadcast needs session on the **same chain** as `--chain`, with pool/vault + underlying token whitelisted where the relayer touches them - **`x402-pay`** — probes endpoint for 402, smart wallet funds builder EOA with exact token amount, EOA signs EIP-3009 payment. Chain auto-detected from 402 response - **`send-native --direct`** — bypasses ValueForwarder contract for direct EOA transfer - **Session permissions** — without `--usdc-limit` etc., session gets bare-bones defaults and may not transact - **Session expiry** — 6 months from creation -- **One-pass session setup** — if the user's intent involves DeFi (deposit, yield, swap, Aave, Morpho), include all required DeFi contracts in the initial `wallet create` call. Never create a bare session and then ask the user to re-approve when a deposit is later attempted. See the Complete Setup Flow above for the full contract list. +- **One-pass session setup** — if the user's intent involves DeFi (deposit, yield, swap, Aave, Morpho), include any additional contracts (Morpho vaults etc.) in the initial `wallet create` call. Never create a bare session and then ask the user to re-approve when a deposit is later attempted. ## Wallet Creation Flow (v2 Relay) diff --git a/skills/polygon-defi/SKILL.md b/skills/polygon-defi/SKILL.md index e12b5b4..56aa7f2 100644 --- a/skills/polygon-defi/SKILL.md +++ b/skills/polygon-defi/SKILL.md @@ -10,21 +10,17 @@ description: DeFi operations on Polygon using the Polygon Agent CLI. Covers same **Before any DeFi operation, the wallet session must include the token contracts and pool contracts.** If the user does not yet have a session, or has an older session that predates this list, create one now — do not wait until a deposit fails: ```bash -polygon-agent wallet create --usdc-limit 5 \ - --contract 0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359 \ +polygon-agent wallet create --usdc-limit 50 \ --contract 0xc2132D05D31c914a87C6611C10748AEb04B58e8F \ --contract 0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619 \ - --contract 0x794a61358d6845594f94dc1db02a252b5b4814ad \ --contract 0x781fb7f6d845e3be129289833b04d43aa8558c42 \ --contract 0xf5c81d25ee174d83f1fd202ca94ae6070d073ccf \ --contract 0x3f33f9f7e2d7cfbcbdf8ea8b870a6e3d449664c2 ``` -This automatically includes: -- USDC (native): `0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359` +**Aave V3 Pool (`0x794a61358d6845594f94dc1db02a252b5b4814ad`) is auto-whitelisted in every session** — no `--contract` flag needed for it. The above command adds: - USDT: `0xc2132D05D31c914a87C6611C10748AEb04B58e8F` - WETH: `0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619` -- Aave V3 Pool (all markets): `0x794a61358d6845594f94dc1db02a252b5b4814ad` - Morpho Compound USDC: `0x781fb7f6d845e3be129289833b04d43aa8558c42` - Morpho Compound WETH: `0xf5c81d25ee174d83f1fd202ca94ae6070d073ccf` - Morpho Compound POL: `0x3f33f9f7e2d7cfbcbdf8ea8b870a6e3d449664c2` @@ -136,7 +132,7 @@ interface PoolTokenInfo { Pool discovery uses `TrailsApi.getEarnPools` — picks the most liquid pool (highest TVL) for the asset on the requested chain. No hardcoded addresses — the pool is resolved at runtime. Supported chains: Polygon, Base, Arbitrum, Optimism, Ethereum mainnet (any chain Trails indexes). -**Gas requirement:** The wallet needs POL for gas, or a session created with `--usdc-limit` to enable USDC paymaster. If the wallet has no POL, create the session with `--usdc-limit 5`. When USDC paymaster is active and the deposit amount would consume the full balance, the CLI auto-reserves 0.05 USDC for gas and prints a note. +**Gas requirement:** The wallet needs POL for gas, or a session created with `--usdc-limit` to enable USDC paymaster. If the wallet has no POL, create the session with `--usdc-limit 50`. The CLI always reserves 0.1 USDC for gas — never deposit the full balance. If the requested amount would leave less than 0.1 USDC, the CLI auto-reduces the deposit and prints a note. **Session setup:** The wallet session must whitelist the token contract and the pool deposit contract, or the relay will reject the transaction with a 400 error. Run a dry-run first to get the exact addresses, then create (or re-create) the session with both contracts: @@ -145,7 +141,7 @@ Pool discovery uses `TrailsApi.getEarnPools` — picks the most liquid pool (hig polygon-agent deposit --asset USDC --amount 1 # 2. Create session with those contracts whitelisted (prevents 400 permission error on broadcast) -polygon-agent wallet create --usdc-limit 5 --contract --contract +polygon-agent wallet create --usdc-limit 50 --contract --contract # 3. Broadcast polygon-agent deposit --asset USDC --amount 1 --broadcast @@ -210,10 +206,10 @@ polygon-agent wallet create --contract --contract ` | Enable USDC gas paymaster. Required when the wallet has no POL. Recommended: `--usdc-limit 5`. | +| `--usdc-limit ` | Enable USDC gas paymaster. Required when the wallet has no POL. Recommended: `--usdc-limit 50`. | | `--contract ` | Whitelist an additional contract (repeatable). Use this if a deposit is rejected due to a missing contract permission. | ```bash # New session with USDC gas enabled -polygon-agent wallet create --usdc-limit 5 +polygon-agent wallet create --usdc-limit 50 ``` --- @@ -267,8 +263,8 @@ polygon-agent wallet create --usdc-limit 5 | Error | Cause | Fix | |-------|-------|-----| | `Insufficient : wallet has X` | Balance too low for the requested deposit amount | Run `polygon-agent balances` and adjust `--amount` | -| `Wallet has no POL for gas` | No native gas and no USDC paymaster | Fund with POL (`polygon-agent fund`) or re-create session with `--usdc-limit 5` | +| `Wallet has no POL for gas` | No native gas and no USDC paymaster | Fund with POL (`polygon-agent fund`) or re-create session with `--usdc-limit 50` | | `Transaction rejected by relay` | Session permissions missing for pool or token contract | Re-create with `--contract --contract ` | -| `Unable to pay gas` | No usable fee token found | Fund with POL or add `--usdc-limit 5` to session | +| `Unable to pay gas` | No usable fee token found | Fund with POL or add `--usdc-limit 50` to session | | `Protocol X not yet supported` | Trails returned a protocol other than aave/morpho | Use `polygon-agent swap` to obtain the yield-bearing token manually | | `swap`: no route found | Insufficient liquidity for the pair | Try a different amount or token pair | From f4be1a9e562e55eeda67481fe8a0cd665cab1e9a Mon Sep 17 00:00:00 2001 From: James Lawton Date: Wed, 29 Apr 2026 10:58:45 +0100 Subject: [PATCH 2/2] fix(deposit): restore native balance check, reserve USDC only when POL < 0.1 --- .../src/commands/operations.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/packages/polygon-agent-cli/src/commands/operations.ts b/packages/polygon-agent-cli/src/commands/operations.ts index 146607d..62ea540 100644 --- a/packages/polygon-agent-cli/src/commands/operations.ts +++ b/packages/polygon-agent-cli/src/commands/operations.ts @@ -1140,11 +1140,11 @@ export const depositCommand: CommandModule = { createPublicClient, http } = await import('viem'); - // Pre-flight: verify balance and auto-reserve gas buffer when wallet has no native token + // Pre-flight: verify balance and auto-reserve gas buffer try { const viemChain = await viemChainForDeposit(chainId); const publicClient = createPublicClient({ chain: viemChain, transport: http() }); - const [usdcBal] = await Promise.all([ + const [usdcBal, nativeBal] = await Promise.all([ publicClient.readContract({ address: asset.address as `0x${string}`, abi: ERC20_BALANCE_OF_ABI, @@ -1154,7 +1154,8 @@ export const depositCommand: CommandModule = { publicClient.getBalance({ address: walletAddress as `0x${string}` }) ]); const requestedUnits = viemParseUnits(amountArg, asset.decimals); - const GAS_RESERVE = viemParseUnits('0.1', asset.decimals); + const USDC_GAS_RESERVE = viemParseUnits('0.1', asset.decimals); + const POL_GAS_RESERVE = viemParseUnits('0.1', 18); if (usdcBal < requestedUnits) { const available = viemFormatUnits(usdcBal, asset.decimals); throw new Error( @@ -1162,18 +1163,18 @@ export const depositCommand: CommandModule = { `Run: polygon-agent balances` ); } - if (requestedUnits + GAS_RESERVE > usdcBal) { - // Always reserve 0.1 for gas regardless of whether POL is available - const adjusted = usdcBal - GAS_RESERVE; + if (nativeBal < POL_GAS_RESERVE && requestedUnits + USDC_GAS_RESERVE > usdcBal) { + // Not enough POL to cover gas — USDC paymaster will be used; reserve 0.1 USDC + const adjusted = usdcBal - USDC_GAS_RESERVE; if (adjusted <= 0n) { throw new Error( `Insufficient ${assetSymbol} for deposit plus 0.1 gas reserve. ` + - `Fund with POL for native gas: polygon-agent fund` + `Fund with at least 0.1 POL for native gas or ensure USDC balance exceeds deposit by 0.1: polygon-agent fund` ); } amountArg = viemFormatUnits(adjusted, asset.decimals); process.stderr.write( - `Note: reduced deposit to ${amountArg} ${assetSymbol} (0.1 reserved for gas)\n` + `Note: reduced deposit to ${amountArg} ${assetSymbol} (0.1 reserved for USDC gas paymaster — fund with POL to avoid this)\n` ); } } catch (e) {