T09 · Insecure Skill Coding Practices
- Location
trade_skill.py:137- Finding
Dry-Run Mode Performs State-Changing Automatic Redemptions
- Content
View full analysis
None: results = client.auto_redeem() for result in results: if result.get("success"): print(f"redeemed market={result.get('market_id')} tx={result.get('tx_hash')}") ``` The function is invoked unconditionally during initialization: ```python def main() -> None: config = load_config() client = get_client(config.venue) print(f"skill={SKILL_SLUG} venue={config.venue} live={config.live}") print( f"query={config.market_query!r} fair_probability={config.fair_probability:.2f} " f"min_edge={config.min_edge:.2f} max_markets={config.max_markets}" ) run_auto_redeem(client) ``` ### Technical Analysis The skill represents dry-run mode as the safe default and checks `config.live` before submitting trades. However, the call to `run_auto_redeem()` occurs before that live-mode check and invokes the authenticated SDK method `client.auto_redeem()` regardless of whether live trading is enabled. Redemption is potentially state-changing. The code itself expects a transaction hash in the result, which indicates that redemption may cause a financial or on-chain transaction. Consequently, running the skill without `--live` does not guarantee a read-only execution. This violates the principle that simulation or dry-run modes must prevent all externally observable state changes, not merely order placement. ### Attack Path 1. A user configures `SIMMER_API_KEY` and runs `python trade_skill.py`, expecting the documented default dry-run behavior. 2. `load_config()` leaves `config.live` set to `False`. 3. The authenticated `SimmerClient` is initialized. 4. `main()` invokes `run_auto_redeem(client)` without checking `config.live`. 5. `client.auto_redeem() ...[truncated 922 chars]- Remediation
View remediation
