# Possible underflow while unwinding in the LockingController.startUnwinding

Rounding in LockingController reward-weight math makes unwinding deduct more than was added, underflowing globalRewardWeight and blocking users from starting withdrawal.

- Payout: Contest reward
- Severity: medium
- Program: infiniFi
- Credited: 0xAres
- Disclosed: 2025-05-23
- Write-up quality: 6/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_infinifi_april2025.pdf#3.2.23
- Library page: https://bugbountylibrary.com/r/cantina%3Ainfinifi_april2025%3A3.2.23
- Tags: domain:web3 impact:dos kind:contest platform:cantina sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:business-logic vuln:dos vuln:precision-loss

**Target:** LockingController.startUnwinding in infiniFi locking module
**Root cause:** Per-position reward weight uses mulWadDown on creation but mulDivUp on unwind, so rounding losses accumulate and the summed decrease can exceed the summed increase, underflowing globalRewardWeight.
**Steps:**
1. Create two positions of 1020 receipt tokens with multiplier 2: each adds 1060 reward weight, globalRewardWeight = 2120.
2. As alice, approve gateway for 2040 share tokens.
3. Call `gateway.startUnwinding(2040, 2)`; computed rewardWeightDecrease = 2121 > 2120.
4. `globalRewardWeight -= rewardWeightDecrease` reverts with arithmetic underflow (0x11).
**How found:** Code reading of the create vs unwind reward-weight formulas spotted asymmetric rounding (mulWadDown vs mulDivUp), then a PoC with small amounts to amplify rounding loss.
**Exploitation:** Not weaponized; griefing/DoS where the last unwinding user (or any user after accumulated rounding) cannot start unwinding their locked position.
**Insight:** When a global accumulator is incremented with one rounding direction and decremented with another, small amounts amplify the drift; test create-then-unwind round trips with tiny values to force underflow.
