T09 · Insecure Skill Coding Practices
Error
- Location
- trader.py:436
- Finding
- Configured minimum market volume safeguard is never enforced<![CDATA[ ## Vulnerability Details **File Location**: `trader.py:436-455` **Related Configuration**: `trader.py:51`, `SKILL.md:116`, `clawhub.json:40-52` **Vulnerability Type**: Missing enforcement of a documented financial risk control **Risk Level**: High ### Vulnerable Code ```python MIN_VOLUME = float(os.environ.get("SIMMER_MIN_VOLUME", "5000")) ``` The market validation function does not inspect market volume or compare it against `MIN_VOLUME`: ```python def valid_market(market) -> tuple[bool, str]: """Check basic market quality gates.""" p = getattr(market, "current_probability", None) if not isinstance(p, (int, float)): return False, "missing probability" spread_cents = getattr(market, "spread_cents", None) if isinstance(spread_cents, (int, float)) and spread_cents / 100 > MAX_SPREAD: return False, f"Spread {spread_cents/100:.1%} > {MAX_SPREAD:.1%}" resolves_at = getattr(market, "resolves_at", None) if resolves_at: try: resolves = datetime.fromisoformat(resolves_at.replace("Z", "+00:00")) days = (resolves - datetime.now(timezone.utc)).days if days < MIN_DAYS: return False, f"Only {days} days to resolve" except Exception: pass return True, "ok" ``` ### Technical Analysis `SIMMER_MIN_VOLUME` is documented as a minimum market-volume filter and is exposed as a configurable tunable. The application reads it into `MIN_VOLUME`, but no execution path uses that value when validating markets. Consequently, any market that has a valid probability and passes the spread and resolution-time checks can reach `client.trade()`, regardless of its liquidity or trading volume. This is particularly dangerous because the program supports real-USDC trading when invoked with `--live`. Low-volume markets are more susceptible to price manipulation and may have insufficient depth for safe execution. The presence of a documented but inactive c ...[truncated 1155 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Read the authoritative market-volume property supplied by the SDK and reject markets below the configured minimum: ```python volume = getattr(market, "volume", None) if not isinstance(volume, (int, float)): return False, "missing market volume" if volume < MIN_VOLUME: return False, f"Volume ${volume:,.2f} below minimum ${MIN_VOLUME:,.2f}" ``` 2. Confirm the exact SDK field and its units. If multiple volume fields exist, use the field representing the intended period and document that period. 3. Fail closed when volume is absent or malformed in live mode rather than treating missing data as acceptable. 4. Validate all numeric risk parameters for finite, nonnegative values before trading. 5. Add tests covering: - Volume below the threshold. - Volume exactly at the threshold. - Missing or malformed volume. - Simulation and live modes. 6. Log the validated volume with each trade decision to support operational review. ]]>
