Moonwell

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

Inflation Attack

Summary

Price of a share can be manipulated

Vulnerability Details

The getCashPrior() function calculates current underlying token balanceOf + badDebt, we will call it as totalCash

exchangeRateStoredInternal function in MToken.sol file, uses getCashPrior to calculate the exchange rate, using this formula
exchangeRate = (totalCash + totalBorrows - totalReserves) / totalSupply

Since one of the parameters (totalCash) can be inflated it opens an opportunity for an inflation attack.

POC

Alice - victim

Bob - attacker

Alice would like to call a function mint in MErc20.sol contract to deposit token and mint shares.

In mintFresh function in MToken.sol contract calculates a number of shares that should me "minted"

function mintFresh{
(vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();
//skipped some code
vars.actualMintAmount = doTransferIn(minter, mintAmount);
//mintTokens = actualMintAmount / exchangeRate
(vars.mathErr, vars.mintTokens) = divScalarByExpTruncate(vars.actualMintAmount, Exp({mantissa: vars.exchangeRateMantissa}));
}
function exchangeRateStoredInternal(){
exchangeRate = (getCashPrior() + totalBorrows - totalReserves) / totalSupply
//same as
//exchangeRate = (totalCash + totalBorrows - totalReserves) / totalSupply
//in other words
}

Attack scenario:

  1. Bob back-runs the transaction of an ERC4626 pool creation

  2. Bob mints one share, getCashPrior()==1, totalSupply == 1.

  3. Bob front-runs Alice mint transaction, for instance Alice called mint(20000) by sending 20_000e18+1 of underlying token using transfer method in underlying_token's contract.
    So now getCashPrior()==20_000e18+1+1, totalSupply == 1.

  4. Alice mint(20000) transaction comes and based on the formula above

    exchangeRate = (getCashPrior() + totalBorrows - totalReserves) / totalSupply
    exchangeRate = (20_000e18+1+1 + 0 - 1) / 1
    exchangeRate = 20_000e18+1

mintTokens = actualMintAmount / exchangeRate
mintTokens = 20_000e18 / 20_000e18+1
mintTokens = 0

  1. Alice will recieve 0 shares for deposited 20_000e18

Impact

Alice will recieve 0 shares for deposited X amount

Tools Used

Manual

Recommendations

You may use OZ ERC4626 lib, OR mint as empty share to zero address.

Updates

Lead Judging Commences

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

Support

FAQs

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