Skip to content

Fix Compound dust rendering and add tx simulation - #7

Merged
szhygulin merged 2 commits into
mainfrom
fix/compound-decimals-and-tx-simulation
Apr 13, 2026
Merged

Fix Compound dust rendering and add tx simulation#7
szhygulin merged 2 commits into
mainfrom
fix/compound-decimals-and-tx-simulation

Conversation

@szhygulin

Copy link
Copy Markdown
Collaborator

Summary

Two fixes surfaced during a live session with wallet 0xC0f5…4075:

  • Compound V3 dust rendering — when the base token's decimals() multicall entry transiently failed, the reader fell back to 18. A 184 K USDC (6-decimal) supply in cUSDCv3 then rendered as ~0.0000002 USDC in get_portfolio_summary, while get_compound_positions (on a retry) decoded correctly. Fix: skip the market when decimals are unknown and the base balance is nonzero, rather than emit wrong-scale amounts.

  • Blind signing without simulation — the agent had no way to verify a contract call before asking for a Ledger signature (e.g. is sending ETH to WETH9's fallback actually the canonical wrap). Now:

    • New simulate_transaction MCP tool — generic eth_call with viem-decoded revert reasons.
    • enrichTx runs an eth_call on every prepared tx and attaches tx.simulation to the preview.
    • send_transaction re-simulates right before forwarding to Ledger and refuses when the tx would revert — no gas burned, no misleading device prompt for a guaranteed failure.

Multi-step approve → action pairs legitimately show ok: false on step 2 at prepare time (no allowance yet) and pass at send time once the approve is mined.

Test plan

  • npm test — 209 tests pass (6 new in test/simulation.test.ts, 1 new in test/session-regression.test.ts)
  • npm run build — clean typecheck
  • Manual: call simulate_transaction against WETH9 with value: 0.5 ETH and confirm ok: true
  • Manual: verify get_portfolio_summary now correctly shows Compound V3 USDC supply for the affected wallet

🤖 Generated with Claude Code

szhygulin and others added 2 commits April 13, 2026 19:16
When the base token's decimals() multicall entry transiently fails, the
reader silently fell back to 18. For USDC-backed markets (6 decimals) a
nonzero supply rendered as ~0.0000002 USDC — which is how wallet
C0f5...4075's 184k USDC cUSDCv3 position appeared in get_portfolio_summary
while get_compound_positions (on a retry) decoded correctly.

Skip the market when decimals are unknown and the base balance is
nonzero, so the aggregator doesn't surface wrong-scale numbers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two related changes to the signing path:

- New simulate_transaction MCP tool — generic eth_call with viem-decoded
  revert reasons. Lets the agent verify a contract call (e.g. is sending
  ETH to WETH9's fallback actually safe, does this custom calldata
  revert) without asking for a Ledger signature.

- enrichTx now runs an eth_call on every prepared tx and attaches the
  result as tx.simulation; send_transaction re-simulates right before
  forwarding to Ledger and refuses when the tx would revert. The agent
  previously had no way to check, and the user would spend gas on a
  guaranteed failure to find out.

Multi-step approve→action pairs legitimately show ok:false on step 2
at prepare time (no allowance yet) and pass at send time once the
approve is mined.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@szhygulin
szhygulin merged commit 87e3b62 into main Apr 13, 2026
2 checks passed
@szhygulin
szhygulin deleted the fix/compound-decimals-and-tx-simulation branch April 25, 2026 02:15
szhygulin added a commit that referenced this pull request Apr 27, 2026
The address-book PR (#284) and the pre-existing sign_message_btc /
sign_message_ltc tools together expand the signing surface beyond
sign-transaction flows. SECURITY.md previously covered only the
contacts blob signing trade-off (path C) and did not describe the
free-form public sign-message tools at all.

This commit:
  - Updates the contacts "EVM signing trade-off" paragraph to point
    at skill v4 Invariant #7 as the agent-side defense (decoration,
    tamper warning, sign-message-during-prepare anomaly check, post-
    add_contact verify cross-check), correctly attributing the
    contacts JSON preimage as NOT subject to character-by-character
    matching (its user-side defense is the recognizable domain
    prefix + JSON shape, per the skill's own carve-out).
  - Adds a new "Free-form message signing" section describing the
    public sign_message_btc / sign_message_ltc tools, the substitution
    threat, and skill v4 Invariant #8's MESSAGE-PREVIEW block as the
    agent-side defense (the user verifies the previewed string
    against the device screen character-by-character).
  - Notes that EVM has no equivalent public free-form signer
    (personal_sign is restricted to the contacts signer) and
    eth_signTypedData_v4 remains excluded from the WC namespace.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
szhygulin added a commit that referenced this pull request Apr 28, 2026
Demo saga followups: items #3#7 from plan parking lot
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant