Submitted by Trust, also found by Aymen0909 and 0x52
Redemption weight is a concept used in Juicebox to determine investors eligible percentage of the non-locked funds. In redeemParams, JB721Delegate calculates users share using:
_totalRedemptionWeight eventually is implemented in DelegateStore:
If we pay attention to _numberOfReservedTokensOutstandingFor() call, we can see it is called with tierId = i, yet storedTier of i+1. It is definitely not the intention as for example, recordMintReservesFor() uses the function correctly:
The impact of this bug is incorrect calculation of the weight of users contributions. The initialQuantity and remainingQuantity values are taken from the correct tier, but _reserveTokensMinted minted is taken from previous tier. In the case where _reserveTokensMinted is smaller than correct value, for example tierID=0 which is empty, the outstanding value returned is larger, meaning weight is larger and redemptions are worth less. In the opposite case, where lower tierID has higher _reserveTokensMinted, the redemptions will receive more payout than they should.
Users of projects can receive less or more funds than they are eligible for when redeeming NFT rewards.
1. Suppose we have a project with 2 tiers, reserve ratio = 50%, redemption ratio = 100%:
When calculating totalRedemptionWeight(), the correct result is
50 * (10 - 3) + 2 + 100 * (30-2) + 2 = 3154
The wrong result will be:
50 * (10 -3) + 4 + 100 * (30-2) + 13  = 3167
Therefore, when users redeem NFT rewards, they will get less value than they are eligible for. Note that totalRedemptionWeight() has an additional bug where the reserve amount is not multiplied by the contribution, which is discussed in another submission. If it would be calculated correctly, the correct weight would be 3450.
Change the calculation to:
Likelihood of impact is very high, because the conditions will arise naturally (different tiers, different reserve minted count for each tier, user calls redeem).
Severity of impact is high because users receive less or more tokens than they are eligible for.
Initially I thought this bug could allow attacker to steal entire unlocked project funds, using a mint/burn loop. However, this would not be profitable because their calculated share of the funds would always be at most what they put in, because reserve tokens are printed out of thin air.
mejango (Juicebox DAO) confirmed 
