Submitted by adriro, also found by minhquanym, minhquanym, zaskoh, cccz, and peanuts
The function completeRedemptions present in the CashManager contract is used by the manager to complete redemptions requested by users and also to process refunds.
https://github.com/code-423n4/2023-01-ondo/blob/main/contracts/cash/CashManager.sol#L707-L727
The total refunded amount that is returned from the internal call to _processRefund is then used to calculate the effective amount of CASH burned (redemptionInfoPerEpoch[epochToService].totalBurned - refundedAmt). This resulting value is then used to calculate how much each user should receive based on how much CASH they redeemed and the total amount that was burned.
The main issue here is that the refunded amount is not updated in the totalBurned storage variable for the given epoch. Any subsequent call to this function wont take into account refunds from previous calls.
If the manager completes the refunds and redemptions at different steps or stages for a given epoch, using multiple calls to the completeRedemptions, then any refunded amount wont be considered in subsequent calls to the function.
Any redemption that is serviced in a call after a refund will be calculated using the total burned without subtracting the previous refunds. The function completeRedemptions will call the internal function _processRedemption passing the burned amount as the quantityBurned argument, the value is calculated in line 755:
https://github.com/code-423n4/2023-01-ondo/blob/main/contracts/cash/CashManager.sol#L755
This means that redemptions that are processed after one or more previous refunds will receive less collateral tokens even if they redeemed the same amount of CASH tokens (i.e. greater quantityBurned, less collateralAmountDue), causing loss of funds for the users.
In the following test, Alice, Bob and Charlie request a redemption. The admin first calls completeRedemptions to process Alices request and refund Charlie. The admin then makes a second call to completeRedemptions to process Bobs request. Even though they redeemed the same amount of CASH (each 200e18), Alice gets 150e6 tokens while Bob is sent ~133e6.
Update the totalBurned amount to consider refunds resulting from the call to _processRefund:
ali2251 (Ondo Finance) confirmed
ypatil12 (Ondo Finance) resolved
