# Bond max-buyer might end up buying the max buy of the next epoch

MuteBond.deposit with max_buy=true recomputes maxPurchaseAmount at execution, so a new epoch starting before inclusion makes the buyer purchase the entire next epoch.

- Payout: Contest reward
- Severity: high
- Program: Mute.io
- Credited: 0xA5DF
- Disclosed: 2023-04-27
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-03-mute-findings/issues/25
- Library page: https://bugbountylibrary.com/r/c4%3A2023-03-mute%3AH-01
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:solidity technique:race-window vuln:business-logic

**Target:** MuteBond.deposit() bond purchase function
**Root cause:** When max_buy is true, value is overwritten with maxPurchaseAmount() at execution time rather than the amount the user saw when signing; epoch rollover between signing and inclusion changes that value.
**Steps:**
1. Buy 99% of current epoch's maxPurchaseAmount() so only ~1 wad remains.
2. Victim sends deposit(0, addr, true) expecting to buy the remaining ~1 wad.
3. Before inclusion, a new epoch starts (innocent or attacker-triggered), resetting available amount to 100 wad.
4. Victim's tx executes, maxPurchaseAmount() returns 100 wad, and the full next-epoch amount is purchased at a lower price than intended.
**How found:** Code reading of deposit() showing max_buy overwrites value with maxPurchaseAmount() at execution; PoC demonstrates maxPurchaseAmount jumping from 1 to 100 wad across an epoch boundary.
**Exploitation:** Attacker or ordinary epoch rollover between victim tx broadcast and inclusion causes max_buy to consume the entire new epoch allocation; no direct theft, victim overpays in size and receives worse pricing.
**Insight:** For any 'max'/'all' convenience flag, check whether the amount is resolved at execution rather than at signing—epoch/round boundaries make the resolved value diverge from user intent.
