feat(spark-savings-plugin): cross-chain Sky Savings Rate skill (v0.1.0)#37
feat(spark-savings-plugin): cross-chain Sky Savings Rate skill (v0.1.0)#37GeoGu360 wants to merge 2 commits intomig-pre:testfrom
Conversation
New skill: spark-savings-plugin — earn Sky Savings Rate (SSR) on USDS via
the sUSDS yield-bearing vault. Supports Ethereum (native ERC-4626 vault)
and Base / Arbitrum (Spark PSM swapExactIn). 6 commands.
Commands:
- quickstart 3-chain parallel scan + 5-status enum + ready-to-run next_command
- apy live SSR + chi + TVL via direct RPC (no API dependency)
- balance USDS / sUSDS / DAI per chain + sUSDS underlying USDS value
- deposit USDS → sUSDS (ERC-4626 on ETH, Spark PSM on Base/Arb)
- withdraw sUSDS → USDS (--amount / --shares-amount / --all)
- upgrade-dai legacy DAI → USDS 1:1 via official Sky DaiUsds migrator (ETH only)
Chain scope (v0.1.0):
- Ethereum: full ERC-4626 vault (deposit/redeem on sUSDS contract)
- Base: Spark PSM at 0x1601843c5E9bC251A3272907010AFa41Fa18347E
- Arbitrum: Spark PSM at 0x2B05F8e1cACC6974fD79A673a341Fe1f58d27266
Optimism / Unichain / Avalanche / Gnosis: have sUSDS but no PSM yet (or
native conversion still pending Q2 2026). Will add in v0.2.0 once the
underlying mechanism ships.
Knowledge-base compliance (verified during development):
- GEN-001 all 6 commands emit structured JSON on stdout
- ONB-001 quickstart skeleton + SUMMARY.md three-section template (first)
- ONC-001 wallet contract-call always invoked with --force
- EVM-001 pre-flight token balance check before approve
- EVM-002 every amount field paired (display + _raw)
- EVM-006 approve followed by wait_for_tx polling, no blind sleep
- EVM-012 surface RPC errors explicitly (no unwrap_or(0) on native_balance)
- EVM-014 retry-on-allowance-revert with 3 patterns: ERC-20 standard,
DAI custom format, OZ v5 ERC20InsufficientAllowance
- EVM-015 explicit --gas-limit override on wallet_contract_call
(approve 60k, main writes 250k) — onchainos eth_estimateGas
under-estimates ERC-4626 / PSM cold-storage operations
- TX-001 wait_for_tx after main submit confirms on-chain status=0x1
before reporting success (prevents broadcast≠success false-positive)
- GAS-001 native gas balance check before write
Bugs surfaced + fixed during real-money testing:
1. (EVM-012) native_balance().unwrap_or(0) silently zeroed RPC failures
→ confusing INSUFFICIENT_GAS when wallet actually had 0.094 ETH
2. (EVM-014 ext) DAI uses non-standard "Dai/insufficient-allowance" revert
string; existing retry pattern only matched standard ERC-20 message
3. (EVM-015) onchainos eth_estimateGas + 1.4× buffer under-estimated
ERC-4626 redeem (estimated 70k → 100k limit → actual 130k → OOG revert)
4. (TX-001) plugin reported ok:true after onchainos broadcast even when
on-chain tx reverted (status=0x0); witnessed via OOG redeem above
Each bug also written into common-bugs-knowledge-base.md as new entries
EVM-014 (extended), EVM-015 (new), TX-001 (new) so future skills don't
repeat them.
Verified end-to-end on Ethereum mainnet:
- C1 upgrade-dai 0.45 DAI → 0.45 USDS via DaiUsds migrator
tx 0x91d3ffb619c1338ed850e68d457eec0ef7d6314eae65e8002aa13011ba97bb0f
- C2 deposit 1 USDS → 0.913 sUSDS via ERC-4626 (chi=1.094 reflected)
tx 0x87255dfc3f3735a642e618398dda81851539f0d333bea423f8409edbf1faf2e5
(EVM-014 retry triggered + saved this one; first submit had stale RPC
allowance view, retried after 5s and succeeded)
- C3 redeem 0.5 sUSDS → 0.547 USDS (chi accrual realized)
tx 0x9c93710a4cc4d73808d17970fa841a48e19dda3c73fb14f80fddef548d2d03ac
(first attempt 0x893db475... reverted with status=0x0 due to OOG;
added explicit gas-limit 250k → succeeded; gasUsed 130829 / 250000)
- TX-001 fix verified: subsequent deposit 0.5 USDS shows
"[deposit] On-chain confirmed (status 0x1)" + "on_chain_status: 0x1"
field in JSON output
Read paths verified: apy returns SSR=3.65% / TVL=$5.4B / chi=1.094 ray
on Ethereum; balance correctly aggregates 3-chain holdings.
L2 Spark PSM path (Base / Arbitrum) NOT yet validated end-to-end —
selectors verified by keccak256 + dry-run produces correct calldata
shape, but real bridge to Base then deposit on PSM blocked by LI.FI
36-min rate-limit cooldown during testing. Will validate in v0.1.1
follow-up after rate-limit clears.
Co-Authored-By: Claude Opus 4.7 (1M context) <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 3: AI Code Review Report — Score: N/A/100
❌ AI review FAILED (HTTP 400): Your credit balance is too low to access the Anthropic API. Please go to Plans & Billing to upgrade or purchase credits.. Request size: 1055996 bytes, plugin content: 143614 bytes. Generated by Claude AI via Anthropic API — review the full report before approving. |
🔨 Phase 2: Build Verification — ✅ PASSED
Build succeeded. Compiled artifact uploaded as workflow artifact. Source integrity: commit SHA `` is the content fingerprint. |
Same E041 fix applied proactively for PR mig-pre#37 (spark-savings) — saw it fail on PR mig-pre#34 (lifi-plugin) so apply the same MIT license here before the CI catches it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
New skill:
spark-savings-plugin— earn Sky Savings Rate (SSR) on USDS via the sUSDS yield-bearing vault. Supports Ethereum (native ERC-4626 vault) and Base / Arbitrum (Spark PSMswapExactIn). 6 commands + onboarding.Why
No existing skill covers Sky/Spark stablecoin savings. Sky Protocol (rebranded MakerDAO) is one of the largest stablecoin issuers ($5.4B sUSDS TVL); the SSR is currently 3.65% APY at zero collateral risk (no liquidation, no leverage). Adding it gives Agents a canonical safe-yield path for USDS / DAI holders.
6 commands
quickstartnext_commandapybalancedeposit--confirm)withdraw--confirm)--amount/--shares-amount/--all)upgrade-dai--confirm)Chain scope (v0.1.0)
deposit/redeemon sUSDS contract)swapExactIn(cross-chain sUSDS is NOT a vault)swapExactInOptimism / Unichain / Avalanche / Gnosis: have sUSDS deployed but no PSM yet (or native conversion still pending Q2 2026 for Avalanche). Will add in v0.2.0 once underlying mechanism ships.
Knowledge-base compliance
quickstartskeleton +SUMMARY.mdwritten FIRST (per CLAUDE.md mandatory order)wallet contract-callalways invoked with--force(defensive)_raw)wait_for_txpolling, no blind sleepunwrap_or(0)on native_balance)--gas-limitoverride; approve 60k, main writes 250kwait_for_txafter main submit confirmsstatus=0x1before reporting success4 real bugs surfaced + fixed during real-money testing
native_balance().unwrap_or(0)silently zeroed RPC failures → confusing INSUFFICIENT_GAS when wallet actually had 0.094 ETHDai/insufficient-allowancerevert string; existing retry pattern only matched standard ERC-20 message → no retry → wasted approve gaseth_estimateGas+ 1.4× buffer under-estimates ERC-4626 redeem (estimated 70k → 100k limit → actual 130k → OOG revert with status=0x0)ok:trueafter onchainos broadcast even when on-chain tx reverted (status=0x0); witnessed via OOG redeem above. Fix: alwayswait_for_txafter main submitAll 3 new/extended entries written into
common-bugs-knowledge-base.mdwith scope, fix templates, gas-limit empirical thresholds per operation type, and grep commands for retroactive scanning of existing skills.Verified end-to-end on Ethereum mainnet
upgrade-dai 0.450x91d3ffb6...11ba97bb0fdeposit 1 USDS0x87255dfc...bf1faf2e50x893db475...c1d0b1eb0x9c93710a...8d2d03ac0x43f78b75...d2dbb8fb[deposit] On-chain confirmed (status 0x1)+"on_chain_status": "0x1"field ✓Read paths verified:
apyreturns SSR=3.65% / TVL=$5.4B / chi=1.094 ray on Ethereum;balancecorrectly aggregates 3-chain holdings.Outstanding for v0.1.1
L2 Spark PSM path (Base / Arbitrum) NOT yet validated end-to-end. Selectors verified by keccak256 + dry-run produces correct calldata shape, but real bridge to Base + deposit on PSM was blocked by LI.FI 36-min rate-limit cooldown during testing. Will validate in v0.1.1 follow-up.
Test plan
cargo build— clean compile, no warnings--helpflag audit vs SKILL.md (perfect match for all 6 commands)quickstart+SUMMARY.mdthree-section template; status enum src ↔ doc fully alignedquickstartreal wallet → statushas_susds_earning, recommends correct next_commandapyreads live SSR/chi/TVL from Ethereum RPCbalanceaggregates 3-chain real holdings correctlydeposit --dry-runproduces correct ERC-4626 calldata + previewed shareswithdraw --dry-runproduces correct redeem calldata + previewed assetsupgrade-dai --dry-runproduces correct DaiUsds migrator calldatagit diff upstream/test --name-only— onlyskills/spark-savings-plugin/filesplugin.yaml api_callsmatches allhttps://source domains (3 RPCs)🤖 Generated with Claude Code