# Pool weight calculation in computepoolweights/computepoolweight always return wrong an- swer because totalusdvalue returns 0

Opal's pool weight calculation returns zero USD value due to decimal mismatch in getUSDPrice, making all pool weights equal and incorrect.

- Payout: Contest reward
- Severity: high
- Program: Opal
- Credited: pks271
- Disclosed: 2024-03-30
- Write-up quality: 6/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_opal_feb2024.pdf#3.2.19
- Library page: https://bugbountylibrary.com/r/cantina%3Aopal_feb2024%3A3.2.19
- Tags: domain:web3 impact:integrity kind:contest platform:cantina sev:high tech:evm tech:solidity technique:source-review vuln:oracle-manipulation vuln:precision-loss

**Target:** OmnipoolController.sol pool weight computation
**Root cause:** getUSDPrice divides Chainlink's 8-decimal price by token decimals (e.g. 1e6 for USDC), yielding a tiny value; multiplying by totalUnderlying scaled to 1e18 then mulDown truncates to 0.
**Steps:**
1. Call computePoolWeights/computePoolWeight on OmnipoolController
2. getUSDPrice(USDC) returns 1e8/1e6 = 100 instead of scaled price
3. usdValue = 3 * 1e12 * 100 / 1e18 == 0
4. totalUSDValue stays 0, poolWeight returns ScaledMath.ONE / pools.length
**How found:** Code reading of getUSDPrice and noticing Chainlink returns 8-decimal prices while the function divides by token decimals, then tracing the multiplication through ScaledMath.mulDown to observe truncation to zero.
**Insight:** When a price oracle returns fixed 8-decimal values, check every division/multiplication against the token's own decimals; a single mismatched scaling factor silently truncates to zero under mulDown and can equalize all weights.
