fix(curve-plugin): add pre-flight balance check and human-readable outputs (v0.2.7)#211
Conversation
…tput fields (v0.2.7) - add_liquidity: pre-flight balance check before approve; cap down ≤1% shortfall (from prior swap slippage) with NOTE; bail on >1% gap; add amounts display field - swap: pre-flight balance check before approve; add amount_in/expected_out/ min_expected human-readable fields to both dry_run and live outputs - quote: add amount_in/amount_out/min_expected human-readable display fields - remove_liquidity: add lp_amount display (18 dec) to all outputs; add estimated_out/min_amount display fields to single-coin dry_run Fixes transferFrom revert when swap output < requested add-liquidity input. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
🔨 Phase 2: Build Verification — ✅ PASSED
Build succeeded. Compiled artifact uploaded as workflow artifact. Source integrity: commit SHA `` is the content fingerprint. |
Phase 4: Summary + Pre-flight for
|
| Command | Description |
|---|---|
get-pools |
List available Curve pools with TVL and APY data |
get-pool-info |
Get detailed information about a specific pool |
get-balances |
Check LP token balances across all pools |
quote |
Get swap quotes with slippage calculations |
swap |
Execute token swaps on Curve |
add-liquidity |
Add liquidity to Curve pools |
remove-liquidity |
Remove liquidity from pools (proportional or single-coin) |
Triggers
Activate this skill when users want to trade stablecoins on Curve Finance, manage liquidity positions, or query Curve pool data. It should be used specifically for Curve-related DeFi operations across supported chains.
Auto-injected Pre-flight
## Pre-flight Dependencies (auto-injected by Plugin Store CI)
> Run once per session before first use. These checks ensure required tools are installed.
### Version check (auto-injected)
> **AI Agent Instruction**: Run this version check before executing any commands from this skill. If an update is applied, re-read this SKILL.md before proceeding — the instructions may have changed.
```bash
# Check for skill updates (1-hour cache)
UPDATE_CACHE="$HOME/.plugin-store/update-cache/curve-plugin"
CACHE_MAX=3600
LOCAL_VER="0.2.7"
DO_CHECK=true
if [ -f "$UPDATE_CACHE" ]; then
CACHE_MOD=$(stat -f %m "$UPDATE_CACHE" 2>/dev/null || stat -c %Y "$UPDATE_CACHE" 2>/dev/null || echo 0)
NOW=$(date +%s)
AGE=$(( NOW - CACHE_MOD ))
[ "$AGE" -lt "$CACHE_MAX" ] && DO_CHECK=false
fi
if [ "$DO_CHECK" = true ]; then
REMOTE_VER=$(curl -sf --max-time 3 "https://raw.githubusercontent.com/okx/plugin-store/main/skills/curve-plugin/plugin.yaml" | grep '^version' | head -1 | tr -d '"' | awk '{print $2}')
if [ -n "$REMOTE_VER" ]; then
mkdir -p "$HOME/.plugin-store/update-cache"
echo "$REMOTE_VER" > "$UPDATE_CACHE"
fi
fi
REMOTE_VER=$(cat "$UPDATE_CACHE" 2>/dev/null || echo "$LOCAL_VER")
if [ "$REMOTE_VER" != "$LOCAL_VER" ]; then
echo "Update available: curve-plugin v$LOCAL_VER -> v$REMOTE_VER. Updating..."
npx skills add okx/plugin-store --skill curve-plugin --yes --global 2>/dev/null || true
echo "Updated curve-plugin to v$REMOTE_VER. Please re-read this SKILL.md."
fiInstall onchainos CLI + Skills (auto-injected)
# 1. Install onchainos CLI
onchainos --version 2>/dev/null || curl -fsSL https://raw.githubusercontent.com/okx/onchainos-skills/main/install.sh | sh
# 2. Install onchainos skills (enables AI agent to use onchainos commands)
npx skills add okx/onchainos-skills --yes --global
# 3. Install plugin-store skills (enables plugin discovery and management)
npx skills add okx/plugin-store --skill plugin-store --yes --globalInstall curve-plugin binary + launcher (auto-injected)
# Install shared infrastructure (launcher + update checker, only once)
LAUNCHER="$HOME/.plugin-store/launcher.sh"
CHECKER="$HOME/.plugin-store/update-checker.py"
if [ ! -f "$LAUNCHER" ]; then
mkdir -p "$HOME/.plugin-store"
curl -fsSL "https://raw.githubusercontent.com/okx/plugin-store/main/scripts/launcher.sh" -o "$LAUNCHER" 2>/dev/null || true
chmod +x "$LAUNCHER"
fi
if [ ! -f "$CHECKER" ]; then
curl -fsSL "https://raw.githubusercontent.com/okx/plugin-store/main/scripts/update-checker.py" -o "$CHECKER" 2>/dev/null || true
fi
# Clean up old installation
rm -f "$HOME/.local/bin/curve-plugin" "$HOME/.local/bin/.curve-plugin-core" 2>/dev/null
# Download binary
OS=$(uname -s | tr A-Z a-z)
ARCH=$(uname -m)
EXT=""
case "${OS}_${ARCH}" in
darwin_arm64) TARGET="aarch64-apple-darwin" ;;
darwin_x86_64) TARGET="x86_64-apple-darwin" ;;
linux_x86_64) TARGET="x86_64-unknown-linux-musl" ;;
linux_i686) TARGET="i686-unknown-linux-musl" ;;
linux_aarch64) TARGET="aarch64-unknown-linux-musl" ;;
linux_armv7l) TARGET="armv7-unknown-linux-musleabihf" ;;
mingw*_x86_64|msys*_x86_64|cygwin*_x86_64) TARGET="x86_64-pc-windows-msvc"; EXT=".exe" ;;
mingw*_i686|msys*_i686|cygwin*_i686) TARGET="i686-pc-windows-msvc"; EXT=".exe" ;;
mingw*_aarch64|msys*_aarch64|cygwin*_aarch64) TARGET="aarch64-pc-windows-msvc"; EXT=".exe" ;;
esac
mkdir -p ~/.local/bin
curl -fsSL "https://github.com/okx/plugin-store/releases/download/plugins/curve-plugin@0.2.7/curve-plugin-${TARGET}${EXT}" -o ~/.local/bin/.curve-plugin-core${EXT}
chmod +x ~/.local/bin/.curve-plugin-core${EXT}
# Symlink CLI name to universal launcher
ln -sf "$LAUNCHER" ~/.local/bin/curve-plugin
# Register version
mkdir -p "$HOME/.plugin-store/managed"
echo "0.2.7" > "$HOME/.plugin-store/managed/curve-plugin"Report install (auto-injected, runs once)
REPORT_FLAG="$HOME/.plugin-store/reported/curve-plugin"
if [ ! -f "$REPORT_FLAG" ]; then
mkdir -p "$HOME/.plugin-store/reported"
# Device fingerprint → SHA256 → 32-char device ID
DEV_RAW="$(hostname):$(uname -s):$(uname -m):$HOME"
DEV_ID=$(echo -n "$DEV_RAW" | shasum -a 256 | head -c 32)
# HMAC signature (obfuscated key, same as CLI binary)
_K=$(echo 'OE9nNWFRUFdfSVJkektrMExOV2RNeTIzV2JibXo3ZWNTbExJUDFIWnVoZw==' | base64 -d 2>/dev/null || echo 'OE9nNWFRUFdfSVJkektrMExOV2RNeTIzV2JibXo3ZWNTbExJUDFIWnVoZw==' | openssl base64 -d)
HMAC_SIG=$(echo -n "${_K}${DEV_ID}" | shasum -a 256 | head -c 8)
DIV_ID="${DEV_ID}${HMAC_SIG}"
unset _K
# Report to Vercel stats
curl -s -X POST "https://plugin-store-dun.vercel.app/install" \
-H "Content-Type: application/json" \
-d '{"name":"curve-plugin","version":"0.2.7"}' >/dev/null 2>&1 || true
# Report to OKX API (with HMAC-signed device token)
curl -s -X POST "https://www.okx.com/priapi/v1/wallet/plugins/download/report" \
-H "Content-Type: application/json" \
-d '{"pluginName":"curve-plugin","divId":"'"$DIV_ID"'"}' >/dev/null 2>&1 || true
touch "$REPORT_FLAG"
fi
</details>
---
*Generated by Plugin Store CI after maintainer approval.*
📋 Phase 3: AI Code Review Report — Score: 82/100
1. Plugin Overview
Summary: This plugin provides a Curve Finance DEX interface for swapping stablecoins and managing liquidity pools across Ethereum, Arbitrum, Base, Polygon, and BSC. It supports pool discovery, quoting, token swaps, adding/removing liquidity — with read operations using direct RPC calls and write operations delegated to Target Users: DeFi users who want to interact with Curve Finance pools through an AI agent for stablecoin swaps, liquidity provision, and portfolio management. 2. Architecture AnalysisComponents:
Skill Structure:
Data Flow:
Dependencies:
3. Auto-Detected Permissionsonchainos Commands Used
Wallet Operations
External APIs / URLs
Chains Operated OnEthereum (1), Arbitrum (42161), Base (8453), Polygon (137), BSC (56) Overall Permission SummaryThis plugin can read token balances and pool data via direct RPC calls, and execute on-chain transactions (token swaps, liquidity additions/removals, ERC-20 approvals) through 4. onchainos API ComplianceDoes this plugin use onchainos CLI for all on-chain write operations?Yes — all on-chain write operations are delegated to On-Chain Write Operations (MUST use onchainos)
Data Queries (allowed to use external sources)
External APIs / Libraries Detected
Verdict: ✅ Fully CompliantAll on-chain write operations (swaps, approvals, add/remove liquidity) use 5. Security AssessmentStatic Rule Scan (C01-C09, H01-H09, M01-M08, L01-L02)
LLM Judge Analysis (L-PINJ, L-MALI, L-MEMA, L-IINJ, L-AEXE, L-FINA, L-FISO)
Toxic Flow Detection (TF001-TF006)
Prompt Injection ScanNo instruction overrides, no identity manipulation, no hidden behavior, no confirmation bypass patterns, no base64/unicode encoded content, no HTML comments with directives found in SKILL.md or source code. Result: ✅ Clean Dangerous Operations Check
Result: Data Exfiltration RiskNo sensitive data (private keys, mnemonics, credentials) is accessed or transmitted. The plugin reads wallet addresses from onchainos (not private keys) and pool data from public sources. RPC calls are read-only Result: ✅ No Risk Overall Security Rating: 🟡 Medium RiskThe plugin involves on-chain financial operations (swaps, liquidity management) which are inherently high-risk. However, the implementation follows best practices: uses onchainos for signing, performs balance checks, waits for approval confirmations, uses exact approval amounts, provides dry-run previews, and documents user confirmation requirements. The medium rating reflects the financial operation risk inherent in any DeFi plugin. 6. Source Code Security (if source code is included)Language & Build Config
Dependency Analysis
No suspicious, unmaintained, or vulnerable dependencies detected. Code Safety Audit
Does SKILL.md accurately describe what the source code does?Yes. The SKILL.md accurately describes:
Verdict: ✅ Source Safe7. Code ReviewQuality Score: 82/100
Strengths
Issues Found
8. Recommendations
9. Reviewer SummaryOne-line verdict: Well-architected Curve Finance DeFi plugin with proper onchainos delegation for all write operations, comprehensive safety checks (balance verification, exact approvals, confirmation waiting), and clear security boundaries — suitable for production with minor fixes. Merge recommendation: Caveats to address:
Generated by Claude AI via Anthropic API — review the full report before approving. |
Summary
add-liquidity: verifies wallet holds enough of each token before submitting approvals. If shortfall ≤ 1% (common after a prior swap due to slippage), caps down to available balance with a NOTE; bails with a clear error if > 1%.swap: same pattern — checks ERC-20 balance before approve, fails fast with human-readable amounts._rawfields:quote:amount_in,amount_out,min_expectedswap:amount_in,expected_out,min_expectedadd-liquidity:amounts(per-coin, using pool decimals)remove-liquidity:lp_amount(18 dec), plusestimated_outandmin_amountfor single-coin dry-runRoot Cause Fixed
When a Curve agent runs swap → add-liquidity in sequence, the swap output is slightly less than requested (e.g. 1.499471 USDT for 1.5 USDC input). Without a balance check,
add-liquiditywould attempttransferFromfor the full 1.5 USDT, causing anestimateGasrevert. The cap-down logic resolves this automatically.Test Plan
curve quote --token-in USDC --token-out USDT --amount 1.5→ output includesamount_in,amount_out,min_expectedcurve swap --token-in USDC --token-out USDT --amount 1.5 --dry-run→ output includesamount_in,expected_out,min_expectedcurve add-liquidity --pool <addr> --amounts "0,1.5,1.5" --min-mint 0 --dry-run→ output includesamountscurve remove-liquidity --pool <addr> --lp-amount 1.0 --coin-index 1 --dry-run→ output includeslp_amount,estimated_out,min_amountcurve remove-liquidity --pool <addr> --lp-amount 1.0 --dry-run→ output includeslp_amount🤖 Generated with Claude Code