# User can accidentally burn their iPT tokens during redemption

Redeemer.redeem burns a user's iPT tokens even when holdings is empty, so calling it before the external-PT redeem returns zero underlying.

- Payout: Contest reward
- Severity: high
- Program: Illuminate
- Credited: Jeiwan
- Disclosed: 2022-10-15
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2022-10-illuminate-judging/issues/222
- Library page: https://bugbountylibrary.com/r/sherlock%3A2022-10-illuminate%3AH-4
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:high tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** Redeemer.sol redeem function (iPT redemption)
**Root cause:** redeem computes redeemed = amount * holdings[u][m] / totalSupply and unconditionally authBurns the user's full iPT balance; when holdings is empty redeemed is 0 but tokens are still burned.
**Steps:**
1. After maturity, call `redeem(u, m)` on Redeemer before the external-PT redeem has populated `holdings[u][m]`.
2. Observe `redeemed = amount * holdings[u][m] / totalSupply()` evaluates to 0.
3. `token.authBurn(msg.sender, amount)` burns the full iPT balance.
4. `Safe.transfer(IERC20(u), msg.sender, 0)` sends nothing; user loses principal tokens for zero underlying.
**How found:** Code reading of Redeemer.redeem: noticed authBurn executes unconditionally while redeemed can be zero when holdings mapping is empty.
**Exploitation:** User self-inflicts loss by calling the wrong redeem function (identical names) after maturity but before the external-PT redeem populates holdings; iPT burned, zero underlying returned.
**Insight:** When a burn/transfer is unconditional but the payout is proportional to a state variable, check the zero/empty-state path: users can trigger irreversible burns for zero return by calling functions in the wrong order.
