BOOK THIS SPACE FOR AD
ARTICLE ADSummary
Whitehat CKK Sec, who is a recipient of Immunefi’s Whitehat Scholarship, disclosed a critical vulnerability in Mushrooms Finance to Immunefi on June 8 that consisted of a logic error, leading to a flash loan attack vector that could have resulted in the loss of 19 wBTC, which at market rate at the time of the report comes out to $635,000.
After receiving the report, Mushrooms Finance paused the contracts and is paying the whitehat a bounty of $60,000 for his find, $18,000 of which went to the Immunefi Whitehat Scholarship. The scholarship helps budding security researchers get a chance to take time off from full-time work, so they can hunt for bugs full-time. While the bounty is listed at $50,000 for critical bugs, Mushrooms Finance is paying $10,000 above that amount in recognition of the size of funds at risk. We thank Mushrooms Finance for their generosity and for taking security and responsibility seriously.
Vulnerability Analysis
The vulnerability exists as a result of the interaction between two contracts in Mushrooms Finance: StrategyCmpdWbtcV1 (Strategy) and the MMVault (Vault). The Strategy contract has a flashloan function, mushroomsFlashloan(), that can be called by any user, which liquidates the held wBTC cTokens from Compound and supplies that wBTC to the Vault. This is obviously erroneous due to its original purpose for MMVault callback only. What this means is that an attacker can flashloan from the Vault and repay it via a vulnerable function present in Strategy. However, the vulnerability is not only possible because of that. The vulnerable mushroomsFlashloan() consists of a check that verifies if the Strategy contract has enough balance to even complete the flashloan taken from MMVault.
require(balanceOfWant() >= _amount, ‘!invalidFlashAmount’);
This check can be bypassed due to the attacker being able to not only define the amount (_amount) but also the fee paid with the flashloan (_fee). The reason behind this is, that the vulnerable flashloan function was not intended to be callable by anyone, but instead to be called by the Vault only when the Vault’s flashloan is called. With the additional _fee-parameter the attacker could have bypassed several checks (which could make the attack more troublesome), and it would result in the Strategy-contract to withdraw wBTC from Compound which it supplied before.
The attack involves three flash loans and can be illustrated in the following steps:
1. Flash loan wBTC from elsewhere (e.g. Uniswap)
2. Deposit wBTC to MMVault, receiving shares of Mushroom cTokens. This step and step 1 are only required, because the MMVault generally does not hold wBTC.
3. Now that the MMVault has wBTC, flashloan wBTC from MMVault to the attack contract (this wBTC becomes the attack profit and will be kept in the attack contract).
4. Attack contract calls mushroomsFlashloan on StrategyCmpdWbtcV1, repaying the MMVault flash loan you just took in wBTC. In effect, the Strategy contract repays the flash loan, not the attacker, and this is what generates profit for the attacker. The repayment happens because the Strategy first withdraws underlying wBTC from Compound in require(ICToken(cwbtc).redeemUnderlying(total) == 0, “!redeemFlashDeleverage”); with total being _amount + _fee (since _amount is 0, it’s only _fee) and then transfers the withdrawn wBTC to the MMVault in the last line of mushroomsFlashloan() IERC20(want).transfer(mwbtc, total);
5. MMVault flash loan finishes, returning to caller (attack contract)
6. Withdraw shares from wBTC MMVault, receiving additional wBTC. Note: the initially supplied wBTC in step 2 is no longer only owned by the attacker but the attacker now only owns it partially based on its shares. But the main profit would have happened in step 4
7. Repay wBTC flashloan from elsewhere (e.g. Uniswap)
Vulnerability Fix
Flashloan support has been disabled on all Mushrooms Vaults and flashloan related logic re-implemented according to EIP3156.
Acknowledgements
We’d like to thank the Mushrooms Finance team for their rapid and effective response to the bug report. Mushrooms Finance paid out a bounty of $60,000 to the whitehat, of which $18,000 went to the Whitehat Scholarship. To report additional vulnerabilities, please see Mushrooms Finance’s bug bounty program with Immunefi. If you’re interested in protecting your project with a bug bounty like Mushrooms Finance, visit the Immunefi services page and fill out the form.