# Reported issues for Recon Crypto MCP

Pod holds 22 of 56 problems reported by people outside the maintainer team. Issues filed by the project's own owners, members and collaborators are excluded entirely — a maintainer's release checklist is not a warning to a prospective user.

Back to [Recon Crypto MCP](/mcp/recon-crypto-mcp).

## Most discussed

### fund-safety: Solana durable-nonce retry after 10s broadcast abort silently re-pins advanced nonce → double execution (#732 / #706)

## Summary — a Solana value-moving action can execute TWICE
When `broadcastSolanaTx` aborts at the #706 10s client timeout **but the node still lands the tx**, a subsequent `preview_solana_send` (or fresh `prepare_*`) on the still-alive handle silently re-fetches the **advanced** durable nonce and re-pins a **byte-different, independently-valid** tx that repeats the same transfer. The deterministic-signature dedupe does NOT collapse it (different nonce → different bytes → different signature). *

[Read the thread](https://github.com/agenthill/vaultpilot-mcp/issues/788) · 2026-07-19 · closed · outside contributor · 4 comments

### arch(substrate): hand-maintained fail-open enumerations are this codebase's default guard habit — 4 instances (#757/#764/#772/#771)

## Substrate review (Role: ARCH) — the codebase's default guard HABIT, not a subsystem pattern

Canon cross-issue failure-class trigger fired (`~/.claude/CLAUDE.md §Issue & Bug Work`): ≥3 issues sharing one failure class on a shared substrate route the next dispatch to a substrate review, not another point fix. SEC (2026-07-19) has now identified a FOURTH instance across a FOURTH unrelated subsystem — the threshold is well past.

**The class:** a guard implemented as a HAND-MAINTAINED ENUMERATIO

[Read the thread](https://github.com/agenthill/vaultpilot-mcp/issues/776) · 2026-07-19 · open · outside contributor · 8 comments

### security: shape-based redaction misses custom/unlisted-provider RPC keys — add exact-match scrubbing of the user's configured secrets (follow-up to #768)

## Summary

#768 broadened `redactSecrets` (`src/shared/error-message.ts`) to cover more provider-key URL shapes, but keyed the new path-token and bare-`?key=` patterns off a KNOWN PROVIDER HOST SET (`quiknode.pro`, `rpcpool.com`, `triton.one`, `nownodes.io`, `getblock.io`, `helius-rpc.com`, `infura.io`, `alchemy.com`). This deliberately avoids over-redacting non-provider content — but it is inherently INCOMPLETE: a key embedded in a custom RPC URL from a provider NOT in the set (e.g. Ankr path 

[Read the thread](https://github.com/agenthill/vaultpilot-mcp/issues/771) · 2026-07-19 · closed · outside contributor · 4 comments

### INCIDENT: LiFi Diamond `allowedAbi: null` — block 5 does not run at all; arbitrary calldata + arbitrary native value to a recognized destination, blind-sign class (ARCHITECTURE.md §3.4)

## Impact

Severity: high — ranked **92/100 exploitability**, the highest of thirteen candidate classes in the SEC pass, above INCIDENT #757.

SEC verdict on ARCHITECTURE.md §3.4, held open by ARCH pending a security seat. Sibling of #757 (same layer, different mechanism: #757 is selector-membership-without-argument-check; this is **no selector check at all**). Feeds ARCH's in-flight #757 seam design.

I have verified every claim against current `main`. Here are the verdicts.

---

# SEC verdict

[Read the thread](https://github.com/agenthill/vaultpilot-mcp/issues/760) · 2026-07-19 · closed · outside contributor · 8 comments

### INCIDENT: pre-sign block 5 checks selector but never arguments — recipient-bearing fns on RECOGNIZED destinations are signable drain paths (Aave/Morpho/Uniswap/Lido)

## Impact

Severity: INCIDENT

Pre-sign **block 5 validates WHICH function is called, never WHERE the value goes**. Block 4 — the only argument-agnostic catch-all — is skipped *precisely when the destination is recognized*. Consequence: every recipient-bearing function in a pinned protocol ABI is a signable drain path to an arbitrary address, and **no acknowledgement flag is load-bearing anywhere in the chain**.

This inverts the security model. An **unknown** destination is refused unless acked

[Read the thread](https://github.com/agenthill/vaultpilot-mcp/issues/757) · 2026-07-19 · closed · outside contributor · 5 comments

### security: transfer(address,uint256) via prepare_custom_call may be ack-bypassable to arbitrary recipient (sibling of #711)

## Impact
Sibling of #711 (fixed in #727), surfaced at that PR's review. #727 added a recipient gate for `transferFrom(address from,address to,uint256)` (checks args[1]). But `transfer(address to,uint256)` (0xa9059cbb) via `prepare_custom_call` may still be ack-bypassable to an ARBITRARY recipient — and `transfer` moves the WALLET'S OWN tokens, so an ack-stamped `transfer(ATTACKER, amount)` on a known/allowlisted token could exfil the wallet's funds. Severity: **IMPORTANT/security** pending veri

[Read the thread](https://github.com/agenthill/vaultpilot-mcp/issues/737) · 2026-07-18 · closed · outside contributor · 8 comments

### QA: isTransportError omits AbortError — latent false not-Ownable all-clear on future fetchWithTimeout EVM reads

From REVIEW's post-merge audit of #702–#706 (origin/main @ bf3d3055, verdict CLEAN — this is a latent pre-existing concern, not a regression).

`isTransportError` (src/modules/security/permissions.ts:31-49) omits `"AbortError"` from its transport-error set. Harmless today: permission reads go via the viem EVM client (viem TimeoutError, already in the set), and #706's raw-AbortError sources are disjoint transports. LATENT failure: a future EVM read routed through `data/http.ts` `fetchWithTimeout`

[Read the thread](https://github.com/agenthill/vaultpilot-mcp/issues/731) · 2026-07-18 · closed · outside contributor · 4 comments

### simplification: unify BTC/LTC Esplora indexer into one parametrized client

Role: DEV

## Goal
Replace the ~90%-duplicated `src/modules/btc/indexer.ts` and `src/modules/litecoin/indexer.ts` Esplora clients with one parametrized `modules/utxo/esplora-client.ts` taking chain (`btc`|`ltc`) as a parameter. Implements ARCHITECTURE.md §5.1.

## Current state (evidence — origin/main @ bf3d305, VERIFIED — line counts match doc exactly)
- `src/modules/btc/indexer.ts`: 708 lines. `src/modules/litecoin/indexer.ts`: 676 lines. The LTC file's own header states it is a "Mirror of src

[Read the thread](https://github.com/agenthill/vaultpilot-mcp/issues/716) · 2026-07-18 · open · outside contributor · 4 comments

## Most recent

### render(solana): Verifier-source link points at the pre-#718 file path

Severity: minor

`src/signing/render/solana.ts` (post-#853) renders a `[Verifier source](…/src/signing/render-verification.ts)` link into the Solana user block. The path is stale — the Solana renderer now lives in `render/solana.ts`; the old path is a re-export barrel. Kept deliberately byte-identical during the #718 decomposition because `test/solana-ledger-hash.test.ts:256` pins the string.

Acceptance: the rendered link points at the file that actually contains the Solana renderer, and the pi

[Read the thread](https://github.com/agenthill/vaultpilot-mcp/issues/864) · 2026-08-26 · open · outside contributor · 0 comments

### security: INTERMEDIATE_CHAIN_BRIDGES relaxes the chainId gate on a FALSE premise — 1885080386571452 is TRON's on-chain id, not NEAR's; #237 also still broken

**Filed-by: SEC**

## Impact

Severity: **security_finding, HIGH, exploitability 75/100.** `INTERMEDIATE_CHAIN_BRIDGES` (`src/modules/swap/intermediate-chain-bridges.ts:88-94`) relaxes the `destinationChainId` equality check on a premise that is **factually false**. The consequence runs both ways: it opens a redirect path to TRON for all seven destinations, **and** it does not fix #237, whose live repro still fails today.

This is not a stale-entry problem. The entry was **wrong on arrival**.

#

[Read the thread](https://github.com/agenthill/vaultpilot-mcp/issues/799) · 2026-07-19 · open · outside contributor · 0 comments

### security: prepare_swap(toAddress=ATTACKER) drains to the LiFi Diamond unstamped — #760 closed on a partial fix; intent check is tautological against a rogue agent

## Impact

Severity: **security_finding, exploitability 70/100.** A rogue or prompt-injected agent can route the entire output of a `prepare_swap` to an attacker address, on a **recognized** destination, with no ack, no stamp, and no pre-sign block firing.

This also means **#760 was closed on a partial fix.** #786/#789 closed the *stamped `prepare_custom_call`* door to the LiFi Diamond. The *unstamped `prepare_swap`* door to the same destination is still open. The INCIDENT is closed; the drain 

[Read the thread](https://github.com/agenthill/vaultpilot-mcp/issues/798) · 2026-07-19 · closed · outside contributor · 1 comment

### fund-safety: fresh prepare_solana_* after an abort-but-landed send double-spends via a NEW handle (#788 sibling — guard is same-handle only)

## Summary — a fresh `prepare_solana_*` after an abort-but-landed send can double-spend (the #788 sibling the same-handle guard does not cover)

PR #792 (Closes #788) fails closed on **re-preview of the SAME handle** after an ambiguous broadcast abort. It does **not** cover the sibling path: a **fresh** `prepare_solana_*` after a landed-but-aborted send mints a new handle with no `broadcastAttempted` flag, re-fetches the advanced durable nonce, and can repeat the transfer. Surfaced during REVIEW

[Read the thread](https://github.com/agenthill/vaultpilot-mcp/issues/797) · 2026-07-19 · closed · outside contributor · 3 comments

### security(refinement): Solana ambiguous-broadcast guard over-refuses provably-non-landed preflight rejects — coarser than EVM #232 (follow-up to #788/#792)

## Context — follow-up to #788 / #792

The #788 double-spend fix (PR #792, commit `4fa77e7`) is correct and passes QA acceptance (fail-closed on any post-signing broadcast attempt; falsifier-verified). This issue tracks a **refinement question** the QA review surfaced — it is **not a #792 blocker** (the behavior below fails *safe*, over-refusing rather than under-refusing).

## Finding — the Solana guard is coarser than the EVM #232 guard it ports (grounded)

`markSolanaBroadcastAttempted(handle

[Read the thread](https://github.com/agenthill/vaultpilot-mcp/issues/794) · 2026-07-19 · open · outside contributor · 0 comments

### harden #714 no-bare-fetch gate: liveness lock test + window.fetch falsifier + node-floor note

## Context

PR #784 (issue #714) stood up eslint + the `no-bare-fetch` rule (bans `fetch` outside `src/data/http.ts`, locking in the #706 un-timed-fetch fixes) + CI wiring. It merged (main @`1e82174`) **without** the REVIEW-recommended follow-up nits, which landed on an orphaned branch (`fix/714-eslint-no-bare-fetch`, commit `057867c`) after the upstream squash-merge race. This issue tracks folding them in so they aren't lost.

## Why this is a gate, not cosmetics

The `no-bare-fetch` rule is a 

[Read the thread](https://github.com/agenthill/vaultpilot-mcp/issues/793) · 2026-07-19 · open · outside contributor · 1 comment

### security(hardening): pin the acknowledgedNonProtocolTarget stamp-writer set — durable guard for #786's 4b LiFi over-block invariant

## Summary

Follow-on to #786 / #789 (the LiFi Diamond stamped-refuse, block `4b`). REVIEW's PASS flagged a latent coupling worth a durable guard: 4b's soundness rests on the invariant **"only `prepare_custom_call` both STAMPS `acknowledgedNonProtocolTarget` AND can target the LiFi Diamond."** True today (exactly three stamp writers: `prepare_custom_call` at `execution/index.ts:1724` + curve ×2, and curve targets factory-validated Curve pools, never LiFi). But the invariant lives ONLY in the 4b 

[Read the thread](https://github.com/agenthill/vaultpilot-mcp/issues/790) · 2026-07-19 · closed · outside contributor · 0 comments

### §3.4/#760-core: refuse stamped (custom_call) txs to the LiFi Diamond — contained incident-preemption fix (reuse #759 D8 discriminator)

## §3.4 / #760-core contained point-fix — refuse the stamped (custom_call) partition to the LiFi Diamond

**Role: DEV** · design-soundness: ARCH (this issue) + a quick SEC confirm (LiFi surface) before build; SEC + REVIEW gate the implementation PR.

### Problem (INCIDENT #760-core, SEC 92/100 — the broad bypass #759 did NOT close)
The LiFi Diamond is recognized at pre-sign with `allowedAbi: null` (`src/signing/pre-sign-check.ts:167`; `LIFI_DIAMOND` hardcoded literal `:42`), so block 5 early-ret

[Read the thread](https://github.com/agenthill/vaultpilot-mcp/issues/786) · 2026-07-19 · closed · outside contributor · 3 comments

### security(enhancement): send path does no address-poisoning (lookalike/vanity) screening — SEC/ARCH design call (follow-on to #763)

## Summary

Surfaced by #763 / #781 (which corrected the false claim that `prepare_token_send` "applies the address-poisoning checks"). The send path (`prepareTokenSend` / `prepareNativeSend`) does label resolution + EIP-55 checksum but does **NOT** screen the resolved recipient for address-poisoning (lookalike / vanity-address attacks). `annotatePoisoning` runs ONLY on `get_transaction_history`'s read-side display. So a user sending to a poisoned lookalike address gets no send-time warning.

##

[Read the thread](https://github.com/agenthill/vaultpilot-mcp/issues/782) · 2026-07-19 · open · outside contributor · 1 comment

### security: lookupKnownSpender implemented twice (known-spenders.ts + permit2.ts) — guaranteed drift, single-source it

`lookupKnownSpender` is implemented TWICE — `src/security/known-spenders.ts:35` and a local redefinition at `src/modules/allowances/permit2.ts:195`. Two implementations of one security lookup is guaranteed drift (they will diverge; a spender allowlisted in one path, not the other). Same failure class #765's D10 single-sourcing exists to prevent, sitting outside D10's scope.

Found by SEC while auditing candidate surfaces for the #776 substrate review (2026-07-19).

**Fix:** single-source it — on

[Read the thread](https://github.com/agenthill/vaultpilot-mcp/issues/780) · 2026-07-19 · closed · outside contributor · 0 comments

### test: WC eth_sendTransaction sink detector in demo structural check has no positive liveness test (follow-up to #772/#774)

## Summary

Surfaced by REVIEW's PASS audit of #774 (#772). The structural demo sink-gating check (`test/support/sink-reachability.ts`) has a sink detector for the WalletConnect `eth_sendTransaction` broadcast site (a `method: "eth_sendTransaction"` call-literal matcher), but it has **no positive liveness test** — because `send_transaction` resolves to the TRON broadcast sink first, the WC method-literal matcher never fires on any current tool. So that detector branch is UNTESTED: a future EVM-o

[Read the thread](https://github.com/agenthill/vaultpilot-mcp/issues/778) · 2026-07-19 · closed · outside contributor · 1 comment

### security(demo): add_contact/remove_contact reach a real Ledger personal_sign under demo mode (message-signing sink class — SEC scope call, follow-up to #772)

## Summary

Surfaced by REVIEW's PASS audit of #774 (#772 demo-mode fund-sink containment). `add_contact` / `remove_contact` reach a REAL Ledger EIP-191 `personal_sign` in demo mode (`src/modules/contacts/index.ts` `signBlobForChain` → `requestPersonalSign` / `signBtcMessageOnLedger`), ungated. #774's structural sink-gating check deliberately excludes the message-signing sink class, so it does not catch this.

## Why it is NOT a fund-safety escape

The signed blob is hardwired with `CONTACTS_DOM

[Read the thread](https://github.com/agenthill/vaultpilot-mcp/issues/777) · 2026-07-19 · open · outside contributor · 0 comments

### security(demo): submit_safe_tx_signature posts to the off-chain Safe Transaction Service under demo mode (off-chain-write sink class, follow-up to #772)

## Summary

Surfaced by the adversarial review of #772 / PR #774 (the demo-mode fund-safety fix). `submit_safe_tx_signature` (src/index.ts ~L2216) posts an already-produced signature to the off-chain **Safe Transaction Service** under `isDemoMode()`. It is NOT a device signature or an on-chain broadcast (outside #772's sink set, lower severity), but it IS a real network write that produces off-chain state — a pending Safe multisig tx gains a signature — while the user believes demo mode means no

[Read the thread](https://github.com/agenthill/vaultpilot-mcp/issues/775) · 2026-07-19 · closed · outside contributor · 0 comments

### feat(security): #759 signed-contact leg — restore wallet-or-signed-contact allowance behind a sound trust root (B1 + §6.1 + §6.2 prereqs)

## Context

#759 ships a **wallet-only** recipient hard gate (`recipient === tx.from`). The signed-contact leg — allowing a hard-gated protocol recipient to resolve to a *device-signed saved contact*, not just the wallet — was **deferred** here because SEC's round-3 review (#759 comment) found the signed-contact trust root unsound at its foundation: `verifyEvmBlob` recovers a signature against `blob.anchorAddress` (`src/contacts/verify.ts:221-226`), a field *inside the signed payload*, and no co

[Read the thread](https://github.com/agenthill/vaultpilot-mcp/issues/773) · 2026-07-19 · open · outside contributor · 0 comments

The remaining reports are on [the project's issue tracker](https://github.com/szhygulin/recon-crypto-mcp/issues).
