Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exchange Rate Manipulation for New and Empty Pools #165

Closed
code423n4 opened this issue Jul 30, 2023 · 2 comments
Closed

Exchange Rate Manipulation for New and Empty Pools #165

code423n4 opened this issue Jul 30, 2023 · 2 comments
Labels
3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working duplicate-92 edited-by-warden unsatisfactory does not satisfy C4 submission criteria; not eligible for awards

Comments

@code423n4
Copy link
Contributor

code423n4 commented Jul 30, 2023

Lines of code

https://github.com/code-423n4/2023-07-moonwell/blob/fced18035107a345c31c9a9497d0da09105df4df/src/core/MToken.sol#L340-L370

Vulnerability details

Impact

mToken is a yield-bearing asset that users can obtain by depositing underlying tokens. The number of mTokens minted for a user depends on the amount of underlying tokens they deposit and the current exchange rate.

However, there is a critical bug in the MToken::mintFresh function that can be exploited to steal funds from initial depositors in a freshly deployed market.

exploitation route:

  1. After the market is deployed, the attacker calls the MErc20::mint function to deposit and mint a small amount of mTokens.
  2. Subsequently, the attacker performs a direct transfer of underlying tokens to the market contract, artificially inflating the underlying.balanceOf(mToken) value.

As a result of the above steps, during the next legitimate user deposit, the mTokens value calculated for the user becomes less than 1 and is effectively rounded down to 0 by Solidity. Consequently, the user receives 0 mTokens against their deposit, and the entire supply of mTokens is now controlled by the attacker.

  1. The attacker can then easily redeem their mTokens for the entire underlying token balance of the mToken contract, effectively stealing the deposited funds.

The exchange rate is calculated using the formula:

exchangeRate = (totalCash + totalBorrows - totalReserves) / totalSupply

The attack is made possible due to the way the exchange rate is calculated during a subsequent call to the contract. After the initial deposit by the attacker, when an unsuspecting user makes a deposit, the exchange rate is calculated by dividing the total cash by the market's total supply(this is since total borrows and total reserves is zero at this state). Let's assume the attacker's mToken balance is 1 mToken, and the market's total supply is 1. If the attacker performs a direct underlying token transfer to the mToken contract amounting to 99,999, assuming the attacker initial deposit is 1, then the exchange rate becomes 100,000.

The number of mTokens to be minted for the user is calculated as amount / exchange rate. As a result, all user deposits below this calculated amount will result in 0 mTokens being minted, due to how Solidity handles floating-point calculations.

The attacker can extend the attack by not redeeming all of their mToken balance but rather redeeming only a portion during every user deposit.

Proof of Concept

https://github.com/code-423n4/2023-07-moonwell/blob/fced18035107a345c31c9a9497d0da09105df4df/src/core/MToken.sol#L340-L370

https://github.com/code-423n4/2023-07-moonwell/blob/fced18035107a345c31c9a9497d0da09105df4df/src/core/MToken.sol#L498-L563

See the Hundred finance hack : https://twitter.com/danielvf/status/1647332221131411463

Tools Used

Research

Recommended Mitigation Steps

To address this issue, I recommend implementing a fix by minting a small amount of mTokens to a dead address when the total supply equals zero. This approach ensures that the exchange rate remains stable for subsequent deposits and prevents the described attack scenario.

Assessed type

Other

@code423n4 code423n4 added 3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working labels Jul 30, 2023
code423n4 added a commit that referenced this issue Jul 30, 2023
@code423n4 code423n4 changed the title First Deposit Bug Exchange Rate Manipulation for New and Empty Pools Jul 31, 2023
@c4-pre-sort
Copy link

0xSorryNotSorry marked the issue as duplicate of #92

@c4-judge
Copy link
Contributor

alcueca marked the issue as unsatisfactory:
Out of scope

@c4-judge c4-judge added the unsatisfactory does not satisfy C4 submission criteria; not eligible for awards label Aug 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working duplicate-92 edited-by-warden unsatisfactory does not satisfy C4 submission criteria; not eligible for awards
Projects
None yet
Development

No branches or pull requests

3 participants