T09 · Insecure Skill Coding Practices
- Location
trader.py:54- Finding
Process-global client caching can retain live-trading authority during a paper-mode run
- Content
View full analysis
SimmerClient: global _client, MAX_POSITION, MIN_VOLUME, MAX_SPREAD, MIN_DAYS, MAX_POSITIONS global YES_THRESHOLD, NO_THRESHOLD, MIN_TRADE, CLUSTER_BIAS, MIN_CLUSTER_SIZE if _client is None: venue = "polymarket" if live else "sim" _client = SimmerClient( api_key=os.environ["SIMMER_API_KEY"], venue=venue, ) if live: _client.live = True try: _client.apply_skill_config(SKILL_SLUG) except AttributeError: pass # apply_skill_config only available in Simmer runtime return _client ``` The cached client is later obtained based on the requested execution mode: ```python def run(live: bool = False) -> None: mode = "LIVE" if live else "PAPER (sim)" safe_print( f"[cluster-momentum] mode={mode} max_pos=${MAX_POSITION} " f"cluster_bias={CLUSTER_BIAS:.0%} min_cluster={MIN_CLUSTER_SIZE}" ) client = get_client(live=live) ``` ### Technical Analysis The module maintains one process-global `_client`, but the cached instance is not associated with the mode used to create it. The `live` argument is only considered while `_client` is `None`. If a persistent process first calls `run(live=True)`, the cached client uses the `polymarket` venue and has `_client.live = True`. A subsequent `run(live=False)` prints `PAPER (sim)` but receives the existing live client. Trade requests later sent through `client.trade()` can consequently reach the live venue despite the current run being presented as simulated. The inverse transition also behaves incorrectly: a client first initialized in simulation mode remains simulated when ...[truncated 1269 chars]- Remediation
View remediation
