# More outstanding reserved tokens are distributed than anticipated leading to less redeemable assets and therefore loss of user funds

JBController._reservedTokenAmountFrom divides by MAX_RESERVED_RATE minus reservedRate instead of reservedRate, minting excess reserved tokens and diluting redeemable assets.

- Payout: Contest reward
- Severity: medium
- Program: Juicebox
- Credited: berndartmueller
- Disclosed: 2022-10-11
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-07-juicebox-findings/issues/285
- Library page: https://bugbountylibrary.com/r/c4%3A2022-07-juicebox%3AM-14
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:precision-loss

**Target:** JBController.distributeReservedTokensOf / _reservedTokenAmountFrom (Solidity contract)
**Root cause:** The reserved token amount is computed as unprocessed*MAX/(MAX-reservedRate) - unprocessed instead of unprocessed*reservedRate/MAX, inflating the minted reserved amount whenever reservedRate is nonzero.
**Steps:**
1. Call `JBController.distributeReservedTokensOf` for a project with a nonzero `reservedRate` and outstanding unprocessed tokens.
2. Observe `_reservedTokenAmountFrom` computes `mulDiv(unprocessed, MAX_RESERVED_RATE, MAX_RESERVED_RATE - reservedRate) - unprocessed`.
3. With unprocessed=1000, reservedRate=10, MAX=100 the result is ~111 instead of the correct 100.
4. Reserved tokens are minted to splits/owner, raising total supply.
5. Higher supply reduces assets redeemable per user in `JBSingleTokenPaymentTerminalStore.recordRedemptionFor`.
**How found:** Code review of the reserved-token math; noticed the divisor uses MAX_RESERVED_RATE - reservedRate rather than reservedRate, then worked a numeric example to confirm the discrepancy.
**Exploitation:** Any project with a nonzero reserved rate and outstanding unprocessed tokens over-mints reserved tokens on distribution, diluting all holders' redeemable terminal assets; no attacker capital needed, triggered by normal distribution.
**Insight:** In share/rate math, verify the formula against a hand-computed small example; a divisor of (MAX - rate) instead of rate is a classic inversion that silently inflates mints and dilutes redeemers.
