Back to skill

Security audit

Polymarket Central Bank Trader

Security checks for vulnerabilities and agentic risk

Overview

The skill is openly a trading bot, but its live-trading risk controls are under-scoped and some documented safeguards are not actually enforced.

Review carefully before installing, especially for live trading. Use a tightly permissioned API key, keep the skill in paper mode until the dependency is pinned and the volume, exposure, and classification safeguards are fixed, and do not run it on a funded account without external account-level limits.

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)

T08 · Insecure Dependencies

Error
Location
clawhub.json:3
Finding

Unpinned Trading SDK Creates a Supply-Chain Execution Risk

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
trader.py:404
Finding

Minimum Market Volume Safeguard Is Declared but Never Enforced

Content
View full analysis
= MAX_POSITIONS: break side, size, reasoning = compute_signal(m) if not side: print(f" [skip] {reasoning}") continue ok, why = context_ok(client, m.id) if not ok: 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}" print(f" [trade] {side.upper()} ${size} {tag} {status} — {reasoning[:70]}") if r.success: placed += 1 except Exception as e: print(f" [error] {m.id}: {e}") ``` ### Technical Analysis `MIN_VOLUME` is loaded from the environment and documented as the minimum market-volume filter, but neither `compute_signal()` nor the execution loop compares a market's volume against it. The value is therefore informational only and does not protect order execution. The strategy discovers markets through broad keyword searches. Without a liquidity gate, a market can reach `client.trade()` solely because its current probability crosses a configured threshold and the other limited checks pass. Low-volume markets are more susceptible to distorted prices, manipulation, poor fills, and inability to exit a position. This is particularly significant in live mode because the code submits transactions using real USDC. ## ...[truncated 1342 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
trader.py:410
Finding

Configured Maximum Open Positions Only Limits Orders Per Invocation

Content
View full analysis
= MAX_POSITIONS: break side, size, reasoning = compute_signal(m) if not side: print(f" [skip] {reasoning}") continue ok, why = context_ok(client, m.id) if not ok: 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}" print(f" [trade] {side.upper()} ${size} {tag} {status} — {reasoning[:70]}") if r.success: placed += 1 except Exception as e: print(f" [error] {m.id}: {e}") print(f"[polymarket-central-bank-trader] done. {placed} orders placed.") ``` ### Technical Analysis The configuration describes `SIMMER_MAX_POSITIONS` as the maximum number of concurrent open positions. The implementation instead initializes `placed` to zero each time `run()` executes and increments it only for successful orders submitted during that invocation. The skill never queries the portfolio to determine: - The number of positions already open. - Existing positions opened by earlier runs. - Pending or partially filled orders. - Whether an order adds a new position or increases an existing position. - Positions created by another simultaneous process. As a result, the control limits successful orders per invocation rather than concurrent portfolio exposure. Repeated or concurrent runs can exceed the documented ceiling. ### Attack Path 1. The live account already has open positions, or the skill completes one run and opens up to `MA ...[truncated 1334 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
trader.py:233
Finding

Classification Order Increases Exposure to Emergency Rate Markets Instead of Dampening It

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • 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
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (5)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill declares access to a high-value credential (SIMMER_API_KEY) and describes live trading behavior, but it does not declare explicit tool scope or allowed tools. That creates ambiguous authority boundaries for an agent runtime and can permit broader-than-intended access to environment-backed capabilities, especially if the platform infers capabilities from context rather than explicit policy.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill states that default operation uses keyword-based market discovery without tight activation boundaries, which risks triggering on ordinary macroeconomic or financial discussion. In a trading skill, vague triggers can lead to unintended market selection, accidental trade recommendations, or execution against irrelevant events, increasing operational and financial risk.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The monitored keyword list is very broad and includes many terms common in general economics commentary, politics, and news. Because this skill can influence or execute trades, such overlap increases the chance of false-positive market discovery and mis-scoped actions, especially when paired with conviction-based sizing and optional live mode.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The keyword search list includes institutions and topics broader than the declared central-bank-decision focus, including Bank of England, BOJ, RBA, Norges Bank, recession, unemployment, NFP, and Sahm Rule. Because discovery drives what the bot can trade, these terms can pull in unrelated or weakly related markets and cause unintended automated positions outside the advertised mandate.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The trading logic expands beyond narrow central-bank decision markets into broader macro and quasi-political categories such as recession, GDP contraction, yield curve, employment, and leadership/succession questions. In an automated live-trading skill, this scope drift is dangerous because it can place real-money trades on markets with very different resolution mechanics, risk profiles, and thesis validity than the stated strategy, undermining operator expectations and risk controls.

Content

No source excerpt is available for this finding.