Back to skill

Security audit

Polymarket Micro Pulse Revert Trader

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed trading skill, but users should review it because live mode can place real-money trades while some documented risk controls are not actually enforced.

Install only if you are comfortable reviewing and limiting a live-trading bot. Keep it in paper mode until the volume filter, true open-position enforcement, interval-continuity checks, and dependency pinning are fixed; use a narrowly scoped SIMMER_API_KEY and do not run overlapping live instances.

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:27
Finding

Configured Minimum-Volume Safeguard Is Not Enforced

Content
View full analysis
list: """ Find active crypto 5-min interval markets via keyword search + bulk fetch fallback, deduplicated. """ seen: set[str] = set() unique: list = [] # Fast markets (best source for 5-min intervals) try: for m in client.get_fast_markets(): market_id = getattr(m, "id", None) if market_id and market_id not in seen: q = getattr(m, "question", "") if is_crypto_5min_market(q): seen.add(market_id) unique.append(m) except Exception as e: safe_print(f"[fast_markets] {e}") # Keyword search for kw in KEYWORDS: try: for m in client.find_markets(query=kw): market_id = getattr(m, "id", None) if market_id and market_id not in seen: q = getattr(m, "question", "") if is_crypto_5min_market(q): seen.add(market_id) ...[truncated 2543 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
trader.py:374
Finding

Position Limit Counts Only Successful Orders During the Current Run

Content
View full analysis
= MAX_POSITIONS: break sorted_ivs = sorted(ivs, key=lambda iv: iv.sort_key) if len(sorted_ivs) < 2: continue # Walk consecutive pairs: if interval[i] is extreme, trade interval[i+1] for i in range(len(sorted_ivs) - 1): if placed >= MAX_POSITIONS: break ``` It is incremented only after a successful order in that same process: ```python if r.success: placed += 1 ``` ### Technical Analysis `SIMMER_MAX_POSITIONS` is documented as the maximum number of concurrent open positions. However, `placed` represents only successful orders submitted during the current execution. The code never queries the account's existing open positions and does not determine whether a new order increases an existing position or creates a distinct position. Because `placed` resets to zero every time `run()` starts, repeated manual runs, an external scheduler, or overlapping processes can each submit up to `MAX_POSITIONS` additional orders. The configured value therefore functions as a per-process order cap rather than a concurrent-position cap. There is also no synchronization between multiple running instances. Even if each instance queried position state independently, concurrent executions could race unless reservation or atomic enforcement is provided by the service. ### Attack Path 1. The authorized account already has `MAX_POSITIONS` open positions. 2. The program is launched again, setting `pla ...[truncated 848 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
trader.py:379
Finding

Adjacent Discovered Markets Are Assumed to Be Consecutive Five-Minute Intervals

Content
View full analysis
= MAX_POSITIONS: break prev = sorted_ivs[i] target = sorted_ivs[i + 1] # Check if previous interval is an extreme pulse pulse_dir = None if prev.p > PULSE_HIGH: pulse_dir = "up" elif prev.p < PULSE_LOW: pulse_dir = "down" if pulse_dir is None: continue pulses_found += 1 safe_print( f" [PULSE] {coin} {date_str} {prev.start_time} " f"p={prev.p:.0%} ({pulse_dir}) -> target {target.start_time} " f"p={target.p:.0%}" ) ``` No check establishes that the target starts exactly when the previous market ends or that both markets represent five-minute windows. ### Technical Analysis The strategy explicitly depends on trading the interval immediately following an extreme pulse. Sorting records by start time establishes order but not continuity. Market discovery uses multiple SDK sources and may return incomplete results. If an intermediate market is absent, two nonconsecutive intervals become adjacent in `sorted_ivs`. The later interval is then incorrectly treated as the next five-minute interval. The parser also stores date and time as strings and derives its sorting key only from the start time, rather than constructing a complete timezone-aware timestamp. This is a strategy-integrity and financ ...[truncated 1092 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
clawhub.json:3
Finding

Trading SDK Dependency Is Installed Without Version or Integrity Pinning

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • 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
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (2)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding

The skill references a high-value credential (SIMMER_API_KEY) and describes trading behavior, but it does not declare an explicit tool/permission scope such as allowed environment access. In an agent setting, undeclared env capability weakens least-privilege controls and can let the skill access secrets more broadly than reviewers or orchestrators expect, which is especially sensitive for a trading skill that could place real-money orders when run live.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The comment says 'mean-revert: sell NO on the next interval', but the code returns side='no' at L246/L254, which indicates buying NO shares rather than selling them. This is an active contradiction in inline documentation about the strategy's execution semantics.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.