# IndexPool: Poor conversion from Balancer V1's corresponding functions

IndexPool's port of Balancer V1 math functions had wrong return, missing brackets, and native multiplication, corrupting pool share/swap calculations.

- Payout: Audit contest
- Severity: high
- Program: Sushi
- Found by: GreyArt
- Disclosed: 2021-11-22
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2021-09-sushitrident-findings/issues/40
- Library page: https://bugbountylibrary.com/r/c4%3A2021-09-sushitrident%3AH-06
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:regression technique:source-review vuln:accounting-error vuln:precision-loss

**Target:** IndexPool Solidity contract math functions (_compute, _pow, _computeSingleOutGivenPoolIn)
**Root cause:** Erroneous port of Balancer V1's bpow/bpowi/_calcSingleOutGivenPoolIn: `output = wholePow` instead of `return`, missing loop braces in `_pow`, and native `*` instead of `_mul` causing precision/overflow divergence.
**Steps:**
1. Compare `_compute()` to Balancer `bpow()`: `if (remain == 0) output = wholePow;` assigns but does not return, so execution falls through to `_powApprox` and `_mul`.
2. In `_pow()`, loop body lacks `{}` so only `a = _mul(a,a)` is inside the loop; `if (n % 2 != 0) output = _mul(output, a);` runs once after loop.
3. In `_computeSingleOutGivenPoolIn()`, `tokenOutRatio` uses `_pow()` instead of `_compute()`, and `zaz` uses native `*` instead of `_mul()`.
4. Apply provided fixed implementations using `return wholePow`, braced loop, and `_mul`/`_compute` throughout.
**How found:** Code review comparing Sushi's ported IndexPool math against the original Balancer V1 BNum/BMath reference implementations line by line, spotting semantic divergences (assignment vs return, missing braces, native vs safe math).
**Insight:** When a protocol ports battle-tested math libraries, diff each function against the upstream reference; subtle control-flow changes (assignment vs return, missing loop braces) silently corrupt pricing math that unit tests with round numbers won't catch.

