Risk Level
LOW
Location
core/src/exchanges/opinion/normalizer.ts:63-68
Code
// In normalizeMarketsFromEvent (categorical markets):
const parentVolume24h = parseNumStr(raw.volume24h);
const totalChildVolume = children.reduce((sum, c) => sum + parseNumStr(c.volume), 0);
for (const child of children) {
const childVolume = parseNumStr(child.volume);
const childVolume24h = totalChildVolume > 0
? (childVolume / totalChildVolume) * parentVolume24h
: 0;
// childVolume24h is set on the UnifiedMarket
}
(parseNumStr wraps parseFloat)
Problem
childVolume24h is computed as a proportion: (childVolume / totalChildVolume) * parentVolume24h. This is a divide-then-multiply chain on three independent parseFloat values:
- Division
childVolume / totalChildVolume can produce a repeating binary fraction
- Multiplication of that fraction by
parentVolume24h amplifies the error
The result is used for sorting markets by volume and for the event-level volume roll-up. While this doesn't affect order building, it can:
- Cause inconsistent market ordering across fetches (non-deterministic sort)
- Produce child volume sums that don't equal
parentVolume24h
Example Failure
parentVolume24h = 1000.0
children volumes: [300, 350, 350]
totalChildVolume = 1000.0
childVolume24h[0] = (300 / 1000) * 1000 = 300.0 ✓
childVolume24h[1] = (350 / 1000) * 1000 = 350.00000000000006 ← float error
childVolume24h[2] = (350 / 1000) * 1000 = 350.00000000000006
sum of childVolume24h = 1000.00000000000012 ≠ 1000.0
Event-level volume aggregation then double-counts 0.00000000000012 USDC per fetch.
Suggested Fix
This is display/sorting only and low severity, but can be fixed by rounding the proportion result:
const childVolume24h = totalChildVolume > 0
? Math.round((childVolume / totalChildVolume) * parentVolume24h * 1e6) / 1e6
: 0;
Found by automated float safety audit
Risk Level
LOW
Location
core/src/exchanges/opinion/normalizer.ts:63-68Code
(
parseNumStrwrapsparseFloat)Problem
childVolume24his computed as a proportion:(childVolume / totalChildVolume) * parentVolume24h. This is a divide-then-multiply chain on three independentparseFloatvalues:childVolume / totalChildVolumecan produce a repeating binary fractionparentVolume24hamplifies the errorThe result is used for sorting markets by volume and for the event-level volume roll-up. While this doesn't affect order building, it can:
parentVolume24hExample Failure
Event-level volume aggregation then double-counts 0.00000000000012 USDC per fetch.
Suggested Fix
This is display/sorting only and low severity, but can be fixed by rounding the proportion result:
Found by automated float safety audit