# If collateral factor is high enough, flutter ends up being out of bounds

In USSDRebalancer, if collateralFactor exceeds all flutterRatios, the loop leaves flutter == flutterRatios.length, causing out-of-bounds indexing and permanent rebalance revert.

- Payout: Contest reward
- Severity: medium
- Program: USSD
- Credited: J4de
- Disclosed: 2023-05-15
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2023-05-USSD-judging/issues/889
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-05-USSD%3AM-10
- Tags: domain:web3 impact:dos kind:contest platform:sherlock sev:medium tech:evm tech:solidity technique:source-review vuln:dos

**Target:** USSDRebalancer.SellUSSDBuyCollateral (Solidity contract)
**Root cause:** The loop searching flutterRatios exits with flutter == flutterRatios.length when cf exceeds every ratio, and that index is then used to read collateral[i].ratios[flutter], which is out of bounds.
**Steps:**
1. Note flutterRatios and collateral[i].ratios are same length per project tests.
2. Loop `for (flutter=0; flutter<flutterRatios.length; flutter++) if (cf < flutterRatios[flutter]) break;`
3. When cf >= all flutterRatios, flutter == flutterRatios.length after loop.
4. Subsequent `collateral[i].ratios[flutter]` reads out of bounds and reverts.
5. Any rebalance calling SellUSSDBuyCollateral reverts once cf reaches that level.
**How found:** Code reading of the flutter search loop and noticing the loop variable equals array length on no-break, then tracing its use as an index into the ratios array.
**Insight:** When a loop variable is reused as an index after the loop, check the no-break exit case: it equals length and any later array access reverts or reads garbage.
