T09 · Insecure Skill Coding Practices
- Location
trader.py:245- Finding
Minimum Trade Floor Can Bypass the Maximum Position Limit
- Content
View full analysis
= NO_THRESHOLD: conviction = min(1.0, (p - NO_THRESHOLD) / (1 - NO_THRESHOLD) * bias) size = max(MIN_TRADE, round(conviction * MAX_POSITION, 2)) ``` ### Technical Analysis The computed order size is protected by a lower bound through `max(MIN_TRADE, ...)`, but it is not subsequently constrained by `MAX_POSITION`. Consequently, the minimum trade setting takes precedence over the maximum position setting whenever `MIN_TRADE` is greater than `MAX_POSITION`. This condition is reachable through the supported configuration. `clawhub.json` permits `SIMMER_MAX_POSITION` to be as low as `1` and `SIMMER_MIN_TRADE` to be as high as `50`. The resulting order can therefore be up to 50 times the configured maximum position. The defect affects both YES and NO orders and applies to live Polymarket execution when the program is launched with `--live`. ### Attack Path 1. Set `SIMMER_MAX_POSITION=1`. 2. Set `SIMMER_MIN_TRADE=50`. 3. Provide a valid `SIMMER_API_KEY`. 4. Run `python trader.py --live`. 5. Allow the market search to find a coffee market whose probability satisfies either trading threshold. 6. `compute_signal()` calculates the size with `max(50, conviction × 1)`. 7. The resulting $50 amount is passed to `client.trade()`, despite the configured $1 maximum. ### Impact Assessment A live order can exceed the user-defined per-trade exposure limit. The immediate scope is the trading authority availabl ...[truncated 319 chars]- Remediation
View remediation
MAX_POSITION: raise ValueError("SIMMER_MIN_TRADE cannot exceed SIMMER_MAX_POSITION") ``` 2. Apply an explicit upper bound to every calculated order: ```python raw_size = round(conviction * MAX_POSITION, 2) size = min(MAX_POSITION, max(MIN_TRADE, raw_size)) ``` 3. Repeat the maximum-amount check immediately before `client.trade()` to provide defense in depth. 4. Add tests covering equal limits, inverted limits, zero or negative values, and the maximum values allowed by `clawhub.json`. ]]>
