Back to skill

Security audit

Polymarket Macro Inflation Chain Trader

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed trading skill, but several advertised financial safeguards are incomplete or fail open before possible live trades.

Review this carefully before installing with a live trading key. It appears designed for legitimate simulated or live market trading, but do not enable live mode or scheduling unless you are comfortable with automatic orders, unpinned SDK code, and the current gaps in liquidity, open-position, and fail-closed safety checks.

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

Error
Location
trader.py:42
Finding

Declared Minimum Market Volume Safeguard Is Not Enforced

Content
View full analysis
tuple[str | None, float, str]: p = market.current_probability q = market.question # Spread gate if market.spread_cents is not None and market.spread_cents / 100 > 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 if p <= YES_THRESHOLD: conviction = (YES_THRESHOLD - p) / YES_THRESHOLD size = max(MIN_TRADE, round(conviction * MAX_POSITION, 2)) edge = YES_THRESHOLD - p return "yes", size, f"YES {p:.0%} edge={edge:.0%} size=${size} -- {q[:70]}" if p >= NO_THRESHOLD: conviction = (p - NO_THRESHOLD) / (1 - NO_THRESHOLD) size = max(MIN_TRADE, round(conviction * MAX_POSITION, 2)) edge = p - NO_THRESHOLD return "no", size, f"NO YES={p:.0%} edge={edge:.0%} size=${size} -- {q[:70]}" return None, 0, f"Neutral at {p:.1%} (outside {YES_THRESHOLD:.0%}/{NO_THRESHOLD:.0%} bands)" ``` ```python def compute_chain_signal(market, chain_dir: str, commodity_p: float, equity_p: float) -> tuple[str | None, float, str]: p = market.current_probability q = market.question # Spread gate if market.spread_cents ...[truncated 1828 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
trader.py:399
Finding

Maximum Open Position Limit Resets on Every Invocation

Content
View full analysis
= MAX_POSITIONS: break side, size, reasoning = compute_signal(m) if not side: safe_print(f" [skip] {reasoning}") continue 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 except Exception as e: safe_print(f" [error] {m.id}: {e}") ``` The chain path repeats the same pattern: ```python placed = 0 for m in equity_markets: if placed >= MAX_POSITIONS: break side, size, reasoning = compute_chain_signal( m, chain_dir, commodity_pressure, equity_optimism ) if not side: safe_print(f" [skip] {reasoning}") continue 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]}") ...[truncated 1361 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
trader.py:180
Finding

Trading Safety Checks Fail Open on Parsing and Context Errors

Content
View full analysis
tuple[bool, str]: """Check flip-flop and slippage safeguards.""" try: ctx = client.get_market_context(market_id) if not ctx: return True, "no context" if ctx.get("discipline", {}).get("is_flip_flop"): reason = ctx["discipline"].get("flip_flop_reason", "recent reversal") return False, f"Flip-flop: {reason}" slip = ctx.get("slippage", {}) if isinstance(slip, dict) and slip.get("slippage_pct", 0) > 0.15: return False, f"Slippage {slip['slippage_pct']:.1%}" for w in ctx.get("warnings", []): safe_print(f" [warn] {w}") except Exception as e: safe_print(f" [ctx] {market_id}: {e}") return True, "ok" ``` ### Technical Analysis Critical controls should fail closed when their required data cannot be parsed or retrieved. Here, malformed resolution data ...[truncated 1381 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
clawhub.json:3
Finding

Privileged Trading SDK Dependency Is Not Version-Pinned

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
  • 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 (4)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill declares use of a sensitive credential (SIMMER_API_KEY) and describes loading tunables from environment variables, but it does not define an explicit tool scope such as permissions or allowed-tools. That omission weakens least-privilege controls and can let the runtime grant broader environment access than the skill actually needs, which is especially relevant for a trading skill that could access credentials used for live execution.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest explicitly enables a managed automaton with an entrypoint for autonomous trading while requiring an API credential, but it provides no user-facing warning or consent mechanism about unattended market actions, financial risk, or credential use. In a trading skill, this omission is more dangerous because users may enable the agent without understanding it can place real trades automatically using supplied secrets.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

When no macro chain signal is present, the skill falls back to generic conviction-based trading across all discovered markets rather than limiting itself to the advertised chain-reaction equity strategy. In an automated trading context, this creates a scope-expansion risk: operators may believe they are running a narrowly constrained macro divergence strategy, while the code can place trades in unrelated commodity, monetary, or equity markets.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The "SAFE BY DEFAULT" text claims real trades occur only with the --live flag, but the code exposes run(live=True) / get_client(live=True) as callable entry points that enable live trading programmatically. This is dangerous because downstream integrators, orchestration code, or other skills may rely on the documentation's stronger guarantee and unintentionally activate real-money trading outside the CLI safeguard.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.