Back to skill

Security audit

Passive Savings Crypto

Security checks for vulnerabilities and agentic risk

Overview

This skill is a real crypto wallet tool that can approve, deposit, and transfer funds, but its user-facing framing understates the protocol, approval, and asset-conversion risks.

Review this carefully before installing in any wallet with meaningful funds. Use a dedicated low-balance wallet, verify the Linea contract addresses and sUSDC transfer semantics, avoid or revoke unlimited USDC allowances, and require explicit human approval before any deposit or transfer.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/mintSYT.js:43
Finding
Unlimited USDC Approval Exposes Current and Future Wallet Funds<![CDATA[ ## Vulnerability Details **File Location**: `scripts/mintSYT.js:43-50` **Vulnerability Type**: Excessive ERC-20 token allowance **Risk Level**: High ### Vulnerable Code ```javascript // 2. Approve if necessary if (currentAllowance < amountInWei) { console.log("Allowance insufficient. Sending approval transaction..."); const approveHash = await walletClient.writeContract({ address: USDC_LINEA, abi: erc20Abi, functionName: 'approve', args: [LOCKER_ROUTER, maxUint256] // Infinite approval to save gas on future mints }); ``` ### Technical Analysis When the existing allowance is insufficient, the script grants the hard-coded Locker Router the maximum possible ERC-20 allowance rather than limiting approval to the requested deposit amount. ERC-20 allowances persist until they are consumed or explicitly revoked. Consequently, the router remains authorized to transfer any USDC subsequently held by the wallet. The authorization is substantially broader in amount and duration than necessary to complete the requested deposit. This becomes exploitable if the router contract is malicious, compromised, incorrectly upgradeable, or contains a vulnerability that permits unauthorized use of `transferFrom`. The project does disclose the infinite approval in its README, but disclosure does not eliminate the residual authorization risk. ### Attack Path 1. A user runs `node scripts/mintSYT.js <amount>`. 2. The script detects that the existing allowance is below the deposit amount. 3. The wallet signs an approval granting the router an allowance of `maxUint256`. 4. The requested deposit completes, but the unused authorization remains active. 5. The wallet later receives or retains additional USDC. 6. An attacker compromises or exploits the approved router, or otherwise gains the ability to invoke its token-spending capability. 7. The attacker uses the persistent allowance to transfer USDC from the wallet without a new approv ...[truncated 348 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Approve only the amount required for the current deposit: ```javascript args: [LOCKER_ROUTER, amountInWei] ``` 2. If repeated deposits must be optimized, require explicit user consent before granting an unlimited allowance rather than making it the default. 3. Provide a command that revokes the router allowance by approving zero. 4. Display the existing allowance and the exact requested approval before signing. 5. Verify whether the deployed router is upgradeable and document its administrator and security assumptions. 6. Simulate the deposit before submission and verify the transaction receipt status. 7. Where supported, use signature-based, amount-limited approvals such as Permit or Permit2 with a short expiration. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/getSYTBalance.js:25
Finding
Balance Tool Omits the Promised Underlying USDC Valuation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/getSYTBalance.js:25-45` **Vulnerability Type**: Incomplete and misleading financial balance reporting **Risk Level**: Low ### Vulnerable Code ```javascript const [balance, decimals, symbol] = await Promise.all([ publicClient.readContract({ address: SYT_ADDRESS, abi: balanceAbi, functionName: 'balanceOf', args: [targetAddress] }), publicClient.readContract({ address: SYT_ADDRESS, abi: balanceAbi, functionName: 'decimals' }), publicClient.readContract({ address: SYT_ADDRESS, abi: balanceAbi, functionName: 'symbol' }) ]); const formattedBalance = formatUnits(balance, decimals); console.log(`Address: ${targetAddress}`); console.log(`Balance: ${formattedBalance} ${symbol}`); ``` The output contradicts the following documented requirements: - `SKILL.md:89`: “Report both figures when showing balance.” - `CLAUDE.md:32`: “Report both nominal sUSDC balance and underlying USDC value.” - `CLAUDE.md:45`: “Always report both nominal sUSDC and claimable underlying USDC.” ### Technical Analysis The implementation only queries `balanceOf`, `decimals`, and `symbol`. It does not invoke a conversion, redemption-preview, exchange-rate, or underlying-value function. It therefore cannot produce the promised claimable USDC value. In an agent-driven financial workflow, documentation forms part of the tool contract. An agent may assume that the returned balance already reflects the underlying USDC value because the skill explicitly promises both figures. If nominal token units and redeemable underlying value diverge, decisions based on this output may be inaccurate. This is primarily an integrity and financial-correctness issue. No direct code-execution or privilege-escalation path was identified. ### Attack Path 1. An agent loads the skill instructions, which state that the balance command reports nominal sUSDC ...[truncated 695 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Identify and use the deployed contract's documented conversion or redemption-preview interface. 2. Report the values separately and label their units unambiguously, for example: ```text Nominal balance: 100.25 sUSDC Claimable underlying: 101.03 USDC ``` 3. Include the block number or timestamp used for the valuation. 4. Add tests covering cases where nominal and underlying balances differ. 5. If the contract exposes no reliable conversion interface, remove the unsupported claim from `SKILL.md`, `CLAUDE.md`, and other user-facing documentation. 6. Prevent agents from treating the nominal value as underlying USDC by returning structured fields with distinct names. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/transferSYT.js:43
Finding
Payment Tool Directly Calls sUSDC Transfer Despite Guaranteeing Plain USDC Delivery<![CDATA[ ## Vulnerability Details **File Location**: `scripts/transferSYT.js:7-8, 27, 43-48` **Vulnerability Type**: Unverified asset-conversion behavior in irreversible payment flow **Risk Level**: Medium ### Vulnerable Code ```javascript const SYT_ADDRESS = "0x060c1cBE54a34deCE77f27ca9955427c0e295Fd4"; //sUSDC Linea const transferAbi = parseAbiItem('function transfer(address to, uint256 amount) returns (bool)'); ``` ```javascript console.log(`Preparing to send ${amountStr} sUSDC to ${recipient}...`); ``` ```javascript // 2. Execute Transfer const hash = await walletClient.writeContract({ address: SYT_ADDRESS, abi: [transferAbi], functionName: 'transfer', args: [recipient, amountInWei] }); ``` This implementation conflicts with explicit representations including: - `tools.json:30`: “The recipient receives plain USDC — not a yield token.” - `SKILL.md:69`: “When you send a payment, the recipient receives plain USDC.” - `CLAUDE.md:47`: “The script handles the unwrap so the recipient gets USDC.” ### Technical Analysis The payment script calls the standard ERC-20 `transfer(address,uint256)` selector directly on the sUSDC address. It contains no explicit call to the Locker Router, an unwrap function, a redemption function, or an underlying-USDC transfer. A nonstandard sUSDC implementation could internally convert the asset during `transfer`, but that behavior cannot be established from the ABI fragments or source code included in the audited project. The script also performs no preflight verification or post-transaction check confirming that the recipient's USDC balance increased. Because payments are irreversible, the implementation should not guarantee plain-USDC delivery unless the relevant deployed contract semantics have been verified and tested. The current mismatch can lead an agent or user to authorize a payment under an incorrect understanding of which asset the recipient will receive. ### Attack Path 1. A user asks the agent to ...[truncated 1251 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Verify the deployed sUSDC contract source and document precisely how `transfer` delivers underlying USDC. 2. If conversion requires a router or redemption operation, replace the direct ERC-20 transfer with that verified interface. 3. Simulate the complete payment transaction before submission. 4. Record the recipient's USDC balance before and after execution, or validate authoritative conversion events in the receipt. 5. Check the final receipt status and fail explicitly if the transaction reverted. 6. Add integration tests against a Linea mainnet fork demonstrating that: - The sender's sUSDC decreases by the expected amount. - The recipient's plain USDC increases by the expected amount. - The recipient does not receive sUSDC when plain USDC is promised. 7. Until this behavior is verified, revise `SKILL.md`, `CLAUDE.md`, and `tools.json` so they do not guarantee plain-USDC delivery. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (28)

Description-Behavior Mismatch

High
Confidence
97% confidence
Finding
The skill metadata claims there are 'no protocol interactions, no special steps,' but the documentation clearly describes minting into sUSDC, rebasing balance semantics, and transfers mediated through specialized SYT logic backed by yield-bearing infrastructure. This mismatch can mislead users or agents into treating the asset like plain USDC, causing uninformed fund movement, hidden protocol exposure, and underestimation of smart-contract and custody risk.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The description claims 'no protocol interactions' and 'no special steps,' but the README later documents explicit DeFi actions: approving token spending, minting into a yield product, and interacting with Aave-backed infrastructure. This mismatch can mislead users or autonomous agents into treating a risky onchain conversion as ordinary cash handling, increasing the chance of unintended approvals and deposits.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill is framed as passive savings for idle USDC, but it also enables transfers to arbitrary recipient addresses and direct token interactions not implied by the passive-yield marketing. In an agent context, broad payment capability hidden behind a savings-oriented description can lead to unsafe automatic invocation for routine wallet requests and accidental fund movement.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill is framed as passive savings for idle USDC, but it also enables transfers to arbitrary recipient addresses and direct token interactions not implied by the passive-yield marketing. In an agent context, broad payment capability hidden behind a savings-oriented description can lead to unsafe automatic invocation for routine wallet requests and accidental fund movement.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The skill is framed as passive savings for idle USDC, but it also enables transfers to arbitrary recipient addresses and direct token interactions not implied by the passive-yield marketing. In an agent context, broad payment capability hidden behind a savings-oriented description can lead to unsafe automatic invocation for routine wallet requests and accidental fund movement.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill is framed as passive savings for idle USDC, but it also enables transfers to arbitrary recipient addresses and direct token interactions not implied by the passive-yield marketing. In an agent context, broad payment capability hidden behind a savings-oriented description can lead to unsafe automatic invocation for routine wallet requests and accidental fund movement.

Known Vulnerable Dependency: ws==8.18.3 — 2 advisory(ies): CVE-2026-45736 (ws: Uninitialized memory disclosure); CVE-2026-48779 (ws: Memory exhaustion DoS from tiny fragments and data chunks)

High
Category
Supply Chain
Confidence
94% confidence
Finding
The lockfile pins a direct/transitive dependency on ws 8.18.3, and the reported advisories describe memory disclosure and memory-exhaustion denial of service in that package. In an agent skill that may connect to blockchain nodes or other services over WebSockets, a vulnerable ws version can expose the process to remote crashes, resource exhaustion, or unintended data exposure if an attacker can influence or operate the remote endpoint.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The skill description claims there are 'no protocol interactions' and 'no special steps,' but the script explicitly submits an ERC-20 approval transaction and then a protocol deposit transaction. This is dangerous because users or downstream agents may consent under false assumptions, causing funds to be committed to a third-party contract and exposed to approval/deposit risk they were told did not exist.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The script directly invokes an on-chain ERC-20 transfer using the user's private key, which materially contradicts the skill description claiming passive yield with 'no protocol interactions, no special steps.' This mismatch is dangerous because an agent or user may authorize the skill under false assumptions and unintentionally move tokenized savings assets out of the wallet.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The manifest and metadata claim there are 'no protocol interactions' and 'no special steps,' but the tool explicitly performs a protocol-specific deposit into autoHODL and auto-handles token approval. That mismatch can mislead users or agents into authorizing DeFi actions with custody, approval, yield, and counterparty risks they may not realize they are taking.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill handles private-key-driven minting, balance interpretation, and token transfers involving real on-chain assets, but it does not present clear user-facing warnings about financial risk, irreversible transactions, protocol dependency, or key sensitivity. In an agent setting, this is more dangerous because autonomous systems may execute transfers or conversions without the human operator appreciating that mistakes cannot be easily undone.

Intent-Code Divergence

Medium
Confidence
92% confidence
Finding
The documentation markets the funds as moving 'like regular USDC,' yet also states that spending must go through transferSYT.js and warns never to use raw USDC transfers. That contradiction can cause operators or downstream agents to assume standard ERC-20 behavior when the asset actually has nonstandard transfer semantics, increasing the chance of mistaken transfers, accounting errors, or operational loss.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The text says funds 'move like regular USDC,' but the skill actually converts assets into sUSDC/SYT, a distinct rebasing token with different transfer semantics, redemption assumptions, and risk profile. Misrepresenting a wrapped/yield-bearing token as regular USDC can cause agents or users to make unsafe accounting, transfer, or liquidity decisions.

Rp1

Medium
Category
MCP Rug Pull
Confidence
91% confidence
Finding
Using `npx clawhub@latest install passive-savings-crypto` executes whatever package version is current at install time, creating a supply-chain trust risk. In a wallet/agent skill context, an unexpected CLI update or compromise could install altered skill content or run unreviewed code on the user's machine.

Skill Enumeration

Medium
Category
Agent Snooping
Content
npm run install-skill
```

`npm run install-skill` copies `SKILL.md` to `~/.claude/skills/passive-savings-crypto/SKILL.md` — the directory Claude Code scans for user-installed skills. You only need to run it once, or again after pulling updates.

---
Confidence
80% confidence
Finding
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Skill Enumeration

Medium
Category
Agent Snooping
Content
npm run install-skill
```

`npm run install-skill` copies `SKILL.md` to `~/.claude/skills/passive-savings-crypto/SKILL.md` — the directory Claude Code scans for user-installed skills. You only need to run it once, or again after pulling updates.

---
Confidence
80% confidence
Finding
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill declares access to sensitive environment variables, including a private key, but does not define an explicit tool scope or permission boundary. In an agent setting, that increases the chance of over-broad invocation and secret exposure through unintended tool use or unsafe integrations.

Vague Triggers

Medium
Confidence
84% confidence
Finding
The invocation examples are broad enough to match common wallet-help requests such as checking balances or sending funds. In an agent ecosystem, overly broad trigger phrases can cause the skill to be selected in contexts the user did not intend, which is especially risky because the skill can initiate real blockchain actions.

Vague Triggers

Medium
Confidence
87% confidence
Finding
The statement that Claude Code can invoke the skill automatically when asked about balances, deposits, or transfers lacks clear trigger boundaries. Because the skill has wallet and transfer capability, ambiguous automatic invocation increases the chance of accidental use, context confusion, or routing sensitive finance requests to the wrong skill.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
The script is presented as handling idle USDC, but it actually reads balances for a specific SYT/sUSDC token contract. That mismatch can mislead users or downstream agents about what asset is being tracked, creating a deceptive asset view and increasing the chance of incorrect financial decisions or unintended exposure to a different instrument than plain USDC.

Intent-Code Divergence

Medium
Confidence
90% confidence
Finding
The code flow requires a conditional approval before deposit, which directly contradicts the claim that there are 'no special steps.' In an agent setting, misleading workflow descriptions are security-relevant because they can suppress scrutiny around approvals and cause users to authorize token access they did not expect.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The script grants maxUint256 approval to the router, giving it indefinite authority to spend the wallet's USDC beyond the immediate deposit amount. If the router is compromised, upgraded maliciously, misconfigured, or later behaves unexpectedly, the wallet's USDC can be drained without any further user action.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The code comments and UX language imply ordinary USDC semantics, but the contract address and log messages show the script is actually handling sUSDC/SYT, a distinct tokenized asset. This can mislead users or agents into transferring a wrapped/yield-bearing token they may not understand, creating risk of asset confusion, accounting mistakes, and unintended fund movement.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The script silently loads a private key and uses it to sign a live asset transfer without any user-facing warning, consent gate, or operational safeguards. In the context of an agent skill marketed as passive savings, undisclosed private-key use is more dangerous because users may not expect the skill to possess or exercise spend authority over wallet funds.

Description-Behavior Mismatch

Medium
Confidence
89% confidence
Finding
The transfer tool says funds 'move like regular USDC,' but the implementation routes transfers through sUSDC-specific logic and converts behavior behind the scenes. This abstraction can cause users or agents to misunderstand what asset is being spent, what conversion path is used, and what protocol dependencies or failure modes apply.

Static analysis

No suspicious patterns detected.