T09 · Insecure Skill Coding Practices
Warning
- Location
- trader.py:32
- Finding
- Declared Minimum-Volume Safeguard Is Not Enforced<![CDATA[ ## Vulnerability Details **File Location**: `trader.py:32`, `trader.py:75-77`, and `trader.py:350-356` **Vulnerability Type**: Missing enforcement of a documented financial-risk control **Risk Level**: Medium ### Vulnerable Code ```python MIN_VOLUME = float(os.environ.get("SIMMER_MIN_VOLUME", "5000")) ``` The setting is refreshed after applying the skill configuration: ```python # Re-read params in case apply_skill_config updated os.environ. MAX_POSITION = float(os.environ.get("SIMMER_MAX_POSITION", str(MAX_POSITION))) MIN_VOLUME = float(os.environ.get("SIMMER_MIN_VOLUME", str(MIN_VOLUME))) ``` However, the order is submitted without checking the market's volume against `MIN_VOLUME`: ```python r = client.trade( market_id=m.id, side=side, amount=size, source=TRADE_SOURCE, skill_slug=SKILL_SLUG, reasoning=reasoning, ) ``` ### Technical Analysis `SIMMER_MIN_VOLUME` is documented as a minimum market-volume filter and is exposed as a configurable risk parameter. The code loads this value but never uses it when discovering markets, computing signals, or submitting orders. Consequently, any market that matches the broad crypto-classification rules may become tradeable regardless of liquidity. The spread check does not provide an equivalent control: a market can temporarily report an acceptable spread while still having insufficient depth or volume for reliable execution. This is a fail-open implementation of a financial safeguard. Missing or unavailable volume information also does not prevent trading. ### Attack Path 1. An attacker creates or influences a low-volume prediction market whose question matches a crypto term such as `crypto`, `Bitcoin price`, or `BTC above`. 2. The market is returned by `get_markets()` or `find_markets()`. 3. A geopolitical/crypto divergence causes `compute_signal()` to produce a trade. 4. The spread and resolution-date checks pass. 5. Because no volume check exists, live mode submits an order ...[truncated 598 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Obtain a trusted market-volume field and enforce the threshold before signal evaluation and again immediately before order submission: ```python volume = getattr(market, "volume", None) if volume is None: return None, 0, "Market volume unavailable" if float(volume) < MIN_VOLUME: return None, 0, f"Volume ${volume:,.2f} below minimum ${MIN_VOLUME:,.2f}" ``` 2. Fail closed when volume is absent, malformed, stale, or cannot be verified. 3. Prefer executable depth or recent-volume metrics over lifetime volume where supported. 4. Revalidate liquidity immediately before live submission to reduce time-of-check/time-of-use risk. 5. Add automated tests proving that markets below the configured threshold cannot reach `client.trade()`. ]]>
