# All yield could be drained if users set any ````> 0```` allowance to others

Tranche.redeemWithYT transfers all accrued yield regardless of pyAmount, letting anyone with a 1 wei YT allowance drain the victim's unclaimed yield.

- Payout: Contest reward
- Severity: high
- Program: Napier
- Credited: DenTonylifer
- Disclosed: 2024-01-24
- Write-up quality: 7/10
- Original: https://github.com/sherlock-audit/2024-01-napier-judging/issues/28
- Library page: https://bugbountylibrary.com/r/sherlock%3A2024-01-napier%3AH-1
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:high tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic vuln:reward-distribution

**Target:** Tranche.redeemWithYT yield redemption (Solidity)
**Root cause:** redeemWithYT computes accruedInTarget from the full YT balance of `from` but transfers the entire accruedInTarget to the adapter regardless of how much pyAmount the caller is redeeming, so a spender with any allowance receives all accrued yield.
**Steps:**
1. Issue 1000e6 underlying to get PT/YT via `tranche.issue(address(this), 1_000e6)`.
2. Warp 30 days and increase scale to accrue yield.
3. Victim calls `tranche.approve(bob, 1)` and `yt.approve(bob, 1)`.
4. Bob calls `tranche.redeemWithYT(victim, bob, 1)`; accruedInTarget is computed from victim's full YT balance and fully transferred, yielding >494e6 underlying to bob.
**How found:** Code review of redeemWithYT: noticed accruedInTarget is computed from `_yt.balanceOf(from)` (full balance) but transferred in full at L283 independent of pyAmount, breaking the proportional allowance semantics.
**Exploitation:** Attacker needs only a 1 wei YT allowance from a victim holding YT. Calling redeemWithYT with pyAmount=1 burns 1 wei of PT/YT but transfers the victim's entire accruedInTarget to the adapter and prefundedRedeem sends the full amount to the attacker, draining all unclaimed yield.
**Insight:** When a redeem/burn function computes accrued rewards from the owner's full balance but transfers them unconditionally, check whether the spender-controlled pyAmount should scale the payout; any nonzero allowance becomes a full-balance drain.
