T09 · Insecure Skill Coding Practices
Warning
- Location
- trader.py:303
- Finding
- Minimum Market Volume Safeguard Is Not Enforced<![CDATA[ ## Vulnerability Details **File Location**: `trader.py:32`, `trader.py:303-330` **Vulnerability Type**: Missing enforcement of a declared financial-risk control **Risk Level**: Medium ### Vulnerable Code ```python MIN_VOLUME = float(os.environ.get("SIMMER_MIN_VOLUME", "1000")) ``` ```python def run(live: bool = False) -> None: mode = "LIVE" if live else "PAPER (sim)" print(f"[polymarket-food-agriculture-trader] mode={mode} max_pos=${MAX_POSITION} min_vol=${MIN_VOLUME} max_spread={MAX_SPREAD:.0%} min_days={MIN_DAYS}") client = get_client(live=live) markets = find_markets(client) print(f"[polymarket-food-agriculture-trader] {len(markets)} candidate markets") placed = 0 for m in markets: if placed >= 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 The application reads `SIMMER_MIN_VOLUME` and displays its value, but it never compares this threshold against a market's trading volume. Markets returned by `find_markets()` proceed directly through signal, context, and order-submission logic. This contradicts the documented purpose of `SIMMER_MIN_VOLUME` as a minimum-volume market filter. A configured safeguard that is not enforced creates a false sense of protection, particularly in live mode. Low-volume prediction markets are more susceptible to: - High price impact and poor execution. - Market-price manipulation. - Unreliable probability signals. - Difficulty exiting a position. - Slippage no ...[truncated 1105 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Enforce the liquidity threshold before signal calculation and before any order can reach `client.trade()`: ```python def market_has_sufficient_volume(market) -> bool: try: volume = float(market.volume) except (AttributeError, TypeError, ValueError): return False return volume >= MIN_VOLUME ``` Use the check in the trading loop: ```python for m in markets: if not market_has_sufficient_volume(m): print(f" [skip] Insufficient or unavailable market volume") continue ``` Additional hardening should include: 1. Treat missing, malformed, stale, or negative volume as a failure rather than allowing the trade. 2. Confirm which SDK field represents the relevant volume and whether it is expressed in USD, USDC, cents, or another unit. 3. Consider requiring both minimum total volume and minimum order-book depth. 4. Revalidate liquidity immediately before live order submission. 5. Add tests proving that markets below the threshold, with missing volume, and with malformed volume never reach `client.trade()`. 6. Reconcile the documented default in `SKILL.md` with the effective default in `clawhub.json` and `trader.py`. ]]>
