Back to skill

Security audit

Polymarket Crypto Onchain Trader

Security checks for vulnerabilities and agentic risk

Overview

This skill is not malicious, but it should be reviewed carefully because it can place real Polymarket trades and its documented strategy and safeguards do not fully match the implementation.

Install only if you are comfortable granting a high-value trading credential and using this as a heuristic trading template, not as a verified on-chain or ETF-flow strategy. Keep it in paper mode unless you have independently reviewed the SDK, restricted the API key, and fixed or accepted the incomplete risk controls around liquidity, order size, and aggregate exposure.

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

Declared Minimum-Volume Safeguard Is Not 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, ) ``` ### Technical Analysis `MIN_VOLUME` is read from the environment, reloaded after managed configuration is applied, and displayed as a risk parameter. However, neither `compute_signal()` nor the order loop compares a market's volume against this value before calling `clien ...[truncated 1410 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
trader.py:303
Finding

Minimum Trade Floor Can Override the Maximum Position Limit

Content
View full analysis
= NO_THRESHOLD: conviction = min(1.0, (p - NO_THRESHOLD) / (1 - NO_THRESHOLD) * bias) size = max(MIN_TRADE, round(conviction * MAX_POSITION, 2)) edge = p - NO_THRESHOLD return "no", size, f"NO YES={p:.0%} edge={edge:.0%} bias={bias:.2f}x size=${size} — {q[:65]}" ``` The relevant tunable ranges are: ```json { "env": "SIMMER_MAX_POSITION", "default": 35, "range": [ 1, 200 ], "step": 1, "label": "Max position size (USD)" } ``` ```json { "env": "SIMMER_MIN_TRADE", "type": "number", "default": 5, "range": [ 1, 100 ], "step": 1, "label": "Min trade size (USD)" } ``` ### Technical Analysis The calculated order amount uses `max(MIN_TRADE, calculated_size)` without subsequently applying a `MAX_POSITION` cap. The independently permitted configuration ranges allow `MIN_TRADE` to exceed `MAX_POSITION`. For example, `MAX_POSITION=1` and `MIN_TRADE=100` produce a $100 order for every qualifying signal, even though the configured maximum position is $1. The conviction value is capped at `1.0`, but this protects only the `conviction * MAX_POSITION` branch. It does not constrain the minimum-trade branch. Consequently, the code contradicts the documented assertion that order sizing is capped at `MAX_POSITION`. ### Attack Path 1. A user, managed runtime, or configuration deployment sets `S ...[truncated 732 chars]
Remediation
View remediation
0` - `MIN_TRADE > 0` - `MIN_TRADE <= MAX_POSITION` 2. Reject invalid configurations rather than silently weakening the maximum. 3. Apply the maximum cap explicitly to the final amount: ```python calculated = round(conviction * MAX_POSITION, 2) size = min(MAX_POSITION, max(MIN_TRADE, calculated)) ``` 4. Add a final invariant immediately before `client.trade()`: ```python if not 0 < size <= MAX_POSITION: raise ValueError("Trade amount violates configured position limits") ``` 5. Make the UI configuration ranges dependent or constrain `SIMMER_MIN_TRADE` so it cannot exceed `SIMMER_MAX_POSITION`. 6. Add boundary tests covering the smallest maximum, largest minimum, zero conviction, and managed environment overrides. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
trader.py:347
Finding

Maximum Concurrent-Position Limit Counts Only Orders Placed During the Current Run

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 ``` ### Technical Analysis `MAX_POSITIONS` is described as the maximum number of concurrent open positions, but the implementation initializes `placed` to zero on every process invocation. It counts successful order responses during only that invocation and never queries the account's existing open positions. The variable therefore limits orders per run, not concurrent positions. Repeated manual runs or external scheduling can continually add positions. Concurrent executions introduce an additional race: each process independently sees a local count of zero and can place up to the full limit. The code also counts successful orders rather than unique open markets. Depending on SDK behavior, multiple orders may affect the same position, while previously opened positions remain entirely absent from the calculation. ### Attack Path 1. The account already has open positions, or the trader completes one run and opens up to `MAX_POSITIONS` positions. 2. The trader is invoked again manually or by an external scheduler. ...[truncated 639 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
clawhub.json:3
Finding

Trading SDK Dependency Is Installed Without a Version or Integrity Pin

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

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The documentation materially misrepresents what the skill does: it claims 'no external API' and a specific structural-edge strategy, while the described behavior depends on SimmerClient/external execution and broad heuristic keyword trading. This is dangerous because users may grant trading authority and trust risk assumptions under false premises, leading to unintended live trades, overbroad market exposure, and poor auditability.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
83% confidence
Finding

The skill declares access to sensitive environment-backed credentials (SIMMER_API_KEY) but does not define any explicit tool scope or permission boundaries. In an agent setting, missing scope declarations make it easier for the runtime or future revisions of the skill to access more capability than users expect, especially where financial actions and secrets are involved.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The file says the strategy uses no external API, yet the described edge sources depend on external publication channels such as ETF flow data and protocol-upgrade information. Security-relevant documentation inconsistencies can cause operators to underestimate network, trust, and data-dependency risks when deciding whether to enable the skill or provide credentials.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The 'default signal' is presented as requiring no external API while being justified by external-data-driven advantages like ETF flow timing and regulatory information. This mismatch is dangerous in a trading skill because users may believe the model is using verified informational edges when it is actually using simplified proxies, increasing the chance of misplaced trust and financially risky deployment.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The keyword list is broad and underconstrained, covering many asset classes and narratives without clear exclusions or context checks. In a credentialed trading skill, this can trigger overbroad market discovery and execution on loosely related or low-quality markets, increasing exposure to unintended trades and manipulation-prone categories.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The manifest and in-code comments describe three stacked structural edges and imply a data-backed strategy, but the implementation only applies keyword classification, UTC hour adjustments, and a date-based BTC cycle multiplier to market metadata. This is a security-relevant integrity issue because it can mislead users, reviewers, or automation into trusting a trading agent's risk model and enabling live trades without the represented decision inputs actually existing.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The code claims it can trade on ETF flow divergence, but it never ingests ETF flow or any comparable external signal; decisions are based only on market text, prices, timing, and hardcoded heuristics. In an automated trading skill, this mismatch is dangerous because operators may enable live trading under the false belief that the system uses a validated informational edge, leading to systematically unsound financial decisions.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.