Moonwell

Moonwell
DeFiFoundry
15,000 USDC
View results
Submission Details
Severity: high
Invalid

``repayBadDebtWithReserves()`` function breaks the core invariant.

Summary

repayBadDebtWithReserves() function breaks the core invariant.

Vulnerability Details

One of the core invariant of this protocol is:

exchange rate cannot change from calling functions repayBadDebtWithCash, repayBadDebtWithReserves, or fixUser.

But this invariant doesn't hold true when calling repayBadDebtWithReserves().

The exchange rate is defined as:

exchangeRate = (bad debt + cash + total borrows - reserves) / totalSupply

In case of calling fixUser() function,

./MErc20DelegateFixer.sol
function fixUser(address liquidator, address user) external {
...
uint256 principal = borrowBalanceStored(user);
...
/// @dev increment the bad debt counter
badDebt = SafeMath.add(badDebt, principal);
/// @dev subtract the previous balance from the totalBorrows balance
totalBorrows = SafeMath.sub(totalBorrows, principal);
emit UserFixed(user, liquidator, liquidated);
}

Here, totalBorrows is subtracted by principal amount which will change the exchange rate but badDebt is also increased by the same principal amount which will balance the exchange rate.

But, let's look at repayBadDebtWithReserves() function:

./MErc20DelegateFixer.sol
function repayBadDebtWithReserves() external nonReentrant {
uint256 currentReserves = totalReserves;
uint256 currentBadDebt = badDebt;
require(currentReserves != 0, "reserves are zero");
require(currentBadDebt != 0, "bad debt is zero");
uint256 subtractAmount = currentBadDebt < currentReserves ? currentBadDebt : currentReserves;
/// bad debt -= subtract amount
badDebt = SafeMath.sub(currentBadDebt, subtractAmount);
/// current reserves -= subtract amount
totalReserves = SafeMath.sub(currentReserves, subtractAmount);
emit BadDebtRepayedWithReserves(badDebt, currentBadDebt, totalReserves, currentReserves);
}

Here, totalReserves is subtracted by some subtractAmount and badDebt is also subtracted by the same amount. For the subtraction of totalReserves and badDebt by some amount, there is no equivalent addition of the subtraction amount. This will decrease the exchange rate and thus breaking the core invariant.

Impact

This issue breaks one of the core invariant of the protocol. Sudden change of exchange rate will hamper the current market with healthy users and it will be unfair to the current holders of the mTokens.

Tools Used

Manual Analysis

Recommendations

Decreasing the totalSupply() by the equivalent amount will balance the exchange rate.

Updates

Lead Judging Commences

0xnevi Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.