Back to skill

Security audit

Polymarket Macro Asymmetric Longshot Trader

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed automated trading skill, but several advertised financial risk controls are not actually enforced in the code.

Review carefully before installing, especially before enabling --live. Use a least-privilege Simmer/Polymarket API key if possible, keep live account funds limited, verify the SDK version, and do not rely on the documented volume, concurrent-position, or longshot-size safeguards until the code enforces them.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (4)

T09 · Insecure Skill Coding Practices

Warning
Location
trader.py:326
Finding

Declared Minimum-Volume Safeguard Is Not Enforced

Content
View full analysis
MAX_SPREAD: return None, 0, f"Spread {market.spread_cents/100:.1%} > {MAX_SPREAD:.1%}" # Days-to-resolution gate if market.resolves_at: try: resolves = datetime.fromisoformat(market.resolves_at.replace("Z", "+00:00")) days = (resolves - datetime.now(timezone.utc)).days if days < MIN_DAYS: return None, 0, f"Only {days}d to resolve" except Exception: pass # Longshot gate: only trade markets priced between 2% and LONGSHOT_CEILING if not is_longshot(p): return None, 0, f"Not a longshot: p={p:.1%} (need {0.02:.0%}-{LONGSHOT_CEILING:.0%})" # Compute macro support score support_score, support_reason = compute_macro_support(market, all_markets) if support_score < MIN_SUPPORT: return None, 0, ( f"Weak macro support: {support_score:.2f} < {MIN_SUPPORT:.2f} " f"({support_reason}) -- {q[:50]}" ) # Longshot = always buy YES (we are betting the unlikely event happens) # Conviction scales with how far below the ceiling AND macro support conviction = ((LONGSHOT_CEILING - p) / LONGSHOT_CEILING) * support_score conviction = min(1.0, conviction) # Cap position size for longshots (high risk) max_longshot_size = LONGSHOT_SIZE_CAP * MAX_POSITION size = max(MIN_TRADE, round(conviction * max_longshot_size, 2)) ``` ### Technical Analysis The `MIN_VOLUME` setting is initialized at `trader.py:40` and reloaded at `trader.py:85`, while `SKILL.md:136` describes it as a minimum market-volume filter. However, `compute_signal()` checks only spread, time to resolution, longshot probability, and macro support. It never compares market volume with `MIN_VOLUME`. Consequently, the documented liqui ...[truncated 1420 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
trader.py:442
Finding

Concurrent Position Limit Ignores Existing Open Positions

Content
View full analysis
= {MIN_SUPPORT:.2f}") for support_score, m, side, size, reasoning in scored: if placed >= MAX_POSITIONS: break ok, why = context_ok(client, m.id) if not ok: safe_print(f" [skip] {why}") continue try: r = client.trade( market_id=m.id, side=side, amount=size, source=TRADE_SOURCE, skill_slug=SKILL_SLUG, reasoning=reasoning, ) tag = "(sim)" if r.simulated else "(live)" status = "OK" if r.success else f"FAIL:{r.error}" safe_print(f" [trade] {side.upper()} ${size} {tag} {status} -- {reasoning[:100]}") if r.success: placed += 1 ``` ### Technical Analysis `MAX_POSITIONS` is documented as the maximum number of concurrent open positions, but the implementation initializes `placed` to zero on every invocation. The counter records only successful orders submitted during the current process. The code never queries the trading account for existing open positions and does not calculate the remaining capacity from the configured maximum. Therefore, repeated manual, automated, or overlapping runs can each place up to ...[truncated 1381 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
trader.py:356
Finding

Minimum Trade Floor Can Override the Longshot Position Cap

Content
View full analysis
Remediation
View remediation
max_longshot_size: return None, 0, ( f"Minimum trade ${MIN_TRADE:.2f} exceeds " f"longshot cap ${max_longshot_size:.2f}" ) raw_size = round(conviction * max_longshot_size, 2) size = min(max_longshot_size, max(MIN_TRADE, raw_size)) ``` ]]>

T08 · Insecure Dependencies

Note
Location
clawhub.json:6
Finding

Security-Sensitive Trading SDK Is Installed Without a Version Pin

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (2)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill explicitly requires a high-value credential (SIMMER_API_KEY) and discusses trade execution, but it does not declare any tool scope, permissions, or allowed-tools boundaries. That mismatch means an agent runtime may grant broader environment or execution access than users expect, increasing the risk of secret exposure or unauthorized live trading if the skill is integrated permissively.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest explicitly requires a SIMMER_API_KEY, which implies outbound authenticated network access, but the file provides no user-facing disclosure about credential use or what external service receives data. In an automated trading skill, silent credentialed network access is more sensitive because users may grant keys that can place trades or access account data without clearly understanding the scope.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.