# User cannot claim rewards or close_position, due to vulnerable division by zero handling

MANTRA farm-manager divides user_weight by zero contract_weights during reward calculation, permanently locking user rewards and blocking position closure.

- Payout: Audit contest
- Severity: high
- Program: MANTRA
- Found by: oakcobalt
- Disclosed: 2025-03-31
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2024-11-mantra-dex#h-07
- Library page: https://bugbountylibrary.com/r/c4%3A2024-11-mantra-dex%3AH-07
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:solidity technique:incomplete-fix technique:source-review vuln:accounting-error vuln:dos

**Target:** CosmWasm farm-manager contract calculate_rewards / reconcile_user_state
**Root cause:** calculate_rewards uses contract_weights as denominator in checked_mul_floor without checking it is non-zero; reconcile_user_state only clears LAST_CLAIMED_EPOCH when the user has no open positions, so epochs with zero contract weight remain in the iteration range.
**Steps:**
1. Create two positions in different lp_denoms (lp_denom_1, lp_denom_2).
2. Advance epochs, claim, then close the lp_denom_1 position so its contract weight becomes 0 in the next epoch.
3. reconcile_user_state skips LAST_CLAIMED_EPOCH.remove because lp_denom_2 position is still open.
4. Advance epochs and create a new position in lp_denom_1.
5. Call claim: calculate_rewards iterates from LAST_CLAIMED_EPOCH+1 and hits `checked_mul_floor((user_weight, 0))`, reverting with 'Cannot divide by zero'.
6. Run PoC `test_query_rewards_divide_by_zero_cause_rewards_locked` in contracts/farm-manager/tests/integration.rs.
**How found:** Code review of calculate_rewards noting contract_weights fetched with unwrap_or(zero) then used as denominator; traced the compensating LAST_CLAIMED_EPOCH clearing in reconcile_user_state and observed it is skipped when other lp_denom positions remain open.
**Insight:** When a contract 'handles' an edge case at the source (clearing state) rather than at the division site, check every branch that can skip that cleanup — multi-position users bypass the guard and re-expose the zero denominator.

