Beginner FriendlyFoundryDeFiOracle
100 EXP
View results
Submission Details
Severity: high
Valid

ThunderLoan flashloan function can be manipulated and used to extract pool funds.

Vulnerability

In the ThunderLoan.sol contract the FlashLoan() function can be manipulated since it does a check that requires the balance of the pool be the greater than the borrowed amount + fees.

Impact

Calling flashLoan() function and deposit() can be exploited to drain the pool.

Proof of Concept

In ThunderLoan.flashloan we check that the balance of the pool after executing operation is greater than the balance of the initial borrowed amount.

uint256 endingBalance = token.balanceOf(address(assetToken));
if (endingBalance < startingBalance + fee) {
revert ThunderLoan__NotPaidBack(
startingBalance + fee,
endingBalance
);
}

With this an attacker can borrow all the funds in the pool by using flashloan() then in the execute operation the attacker deposits back the borrowed funds + fees using the contract's deposit() function, the attacker then gets minted reciept token in accordance to the depost function's logic:

assetToken.mint(msg.sender, mintAmount);

Then becomes the highest Lp provider. After wards the attacker can call the redeem() function and since the redeem function requires that the caller has the reciept tokens before releasing the equivalent amount of tokens to the caller. The attacker will pass this check completely and drain the pool.

To simulate the attack, add the provided codes in the gist file to the 2021-11-ThunderLoan codebase as follows:

  • in the /test/mocks create a file and paste the code here, this is the flashLoan reciever.

  • then in the /test/unit create another file and paste the code here, this is the test to run the attack.

Finally you can run the tests using forge t and confirm the exploit.

Recommended Mitigation Steps

Use the same check used in the repay() function to lock the deposit() when flasloan is active:

if (!s_currentlyFlashLoaning[token]) {
revert ThunderLoan__CurrentlyFlashLoaning();
}

The above could be added and the deposit() would reevert if flashloan is active.

Updates

Lead Judging Commences

0xnevi Lead Judge about 2 years ago
Submission Judgement Published
Validated
Assigned finding tags:

flash loan funds stolen by a deposit

Support

FAQs

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