Back to skill

Security audit

Starknet DeFi Toolkit

Security checks across malware telemetry and agentic risk

Overview

This skill is a disclosed Starknet read/simulate CLI with public API calls and one user-invoked local scaffold write, not hidden or destructive behavior.

Install only if you want a lightweight Starknet query/simulation helper. Do not rely on the generated Cairo skeleton or balance logic as audited production code, and be aware that balance queries disclose the queried wallet address to the selected RPC provider while scaffold may overwrite a local file.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (9)

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The top-level docstring describes the tool as a 'read-only Starknet DeFi CLI' while also listing a 'scaffold' subcommand that emits a Cairo ERC-20 skeleton. The implementation of that command writes a new .cairo file to disk, which is not read-only behavior and goes beyond DeFi querying/simulation.

Intent-Code Divergence

Medium
Confidence
91% confidence
Finding
The comments state 'Use the well-known ERC-20 selector for balanceOf' and 'use the canonical Starknet selector,' but nearby comments also admit derived logic 'won't work' and the actual RPC call still uses the same hard-coded placeholder-looking selector. This is an active contradiction between the explanatory comments and what the code really does.

Missing User Warnings

Low
Confidence
85% confidence
Finding
The scaffold command performs a filesystem write via open(..., "w") and will overwrite an existing file with the same derived name, but the code provides no pre-write disclosure, confirmation prompt, or comment warning about this side effect. The module docstring describes the scaffold feature, but it does not warn that invoking it creates or overwrites a local file.

External Transmission

Medium
Category
Data Exfiltration
Content
def cmd_price(args):
    sym = args.symbol.upper()
    cg_id = {"STRK": "starknet", "ETH": "ethereum", "USDC": "usd-coin", "USDT": "tether"}.get(sym, sym.lower())
    url = f"https://api.coingecko.com/api/v3/simple/price?ids={cg_id}&vs_currencies=usd"
    try:
        with urllib.request.urlopen(url, timeout=15) as r:
            data = json.loads(r.read().decode())
Confidence
60% confidence
Finding
https://api.coingecko.com/

Context Window Stuffing

Medium
Category
Memory Poisoning
Content
if not token_addr:
        print(f"Unknown token {args.token}. Known: {', '.join(MAINNET_TOKENS)}", file=sys.stderr)
        sys.exit(1)
    selector_balance = "0x2e4263f5f8b3b3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e"
    # Real balanceOf selector is 0x2e4263f5f8b3b3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e
    # Use the well-known ERC-20 selector for balanceOf
    BALANCE_OF_SELECTOR = 0x2e4263f5f8b3b3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e
Confidence
80% confidence
Finding
3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e

Context Window Stuffing

Medium
Category
Memory Poisoning
Content
print(f"Unknown token {args.token}. Known: {', '.join(MAINNET_TOKENS)}", file=sys.stderr)
        sys.exit(1)
    selector_balance = "0x2e4263f5f8b3b3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e"
    # Real balanceOf selector is 0x2e4263f5f8b3b3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e
    # Use the well-known ERC-20 selector for balanceOf
    BALANCE_OF_SELECTOR = 0x2e4263f5f8b3b3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e
    # Use the correct felt encoding: balanceOf selector name_hash
Confidence
80% confidence
Finding
3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e

Context Window Stuffing

Medium
Category
Memory Poisoning
Content
selector_balance = "0x2e4263f5f8b3b3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e"
    # Real balanceOf selector is 0x2e4263f5f8b3b3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e
    # Use the well-known ERC-20 selector for balanceOf
    BALANCE_OF_SELECTOR = 0x2e4263f5f8b3b3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e
    # Use the correct felt encoding: balanceOf selector name_hash
    import hashlib
    sel = hashlib.sha256(b"balanceOf").hexdigest()[:62]
Confidence
80% confidence
Finding
3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e

Context Window Stuffing

Medium
Category
Memory Poisoning
Content
import hashlib
    sel = hashlib.sha256(b"balanceOf").hexdigest()[:62]
    # The above won't work; use the canonical Starknet selector (short string)
    # Real value: balanceOf -> 0x2e4263f5f8b3b3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e
    calldata = [to_felt_int(token_addr), to_felt_int(args.address)]
    try:
        result = rpc(
Confidence
80% confidence
Finding
3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e

Context Window Stuffing

Medium
Category
Memory Poisoning
Content
[
                {
                    "contract_address": token_addr,
                    "entry_point_selector": "0x2e4263f5f8b3b3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e",
                    "calldata": [to_felt_int(args.address)],
                },
                "latest",
Confidence
80% confidence
Finding
3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e

VirusTotal

64/64 vendors flagged this skill as clean.

View on VirusTotal

Static analysis

No suspicious patterns detected.