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

`exchangerate` increase in `deposit()` function

Summary

Deposit function allows everyone to deposit tokenA and mints assetToken based on the calculated exchange rate in return.

uint256 mintAmount = (amount * assetToken.EXCHANGE_RATE_PRECISION()) / exchangeRate;
emit Deposit(msg.sender, token, amount);
assetToken.mint(msg.sender, mintAmount);

Vulnerability Details

In the same deposit() function there is a line which updates/increases the exchange rate:

uint256 calculatedFee = getCalculatedFee(token, amount);
assetToken.updateExchangeRate(calculatedFee);

This is not a correct logic. The deposit function should not increase the exchange rate. It can be observed in the POC that two users deposit tokenA. First user is able to redeem his whole balance but due to the above exchange rate increase second user(liquidity provider) cannot redeem his balance.

These 2 lines are already removed from the ThunderLoanUpgraded.sol contract.

Impact

function testNCTCheckDepositRedeemDeposit() public setAllowedToken {
tokenA.mint(user, AMOUNT);
tokenA.mint(liquidityProvider, AMOUNT);
AssetToken assetToken = thunderLoan.getAssetFromToken(tokenA);
vm.startPrank(user);
tokenA.approve(address(thunderLoan), AMOUNT);
thunderLoan.deposit(tokenA, AMOUNT);
vm.stopPrank();
vm.startPrank(liquidityProvider);
tokenA.approve(address(thunderLoan), AMOUNT);
thunderLoan.deposit(tokenA, AMOUNT);
vm.stopPrank();
vm.startPrank(user);
thunderLoan.redeem(tokenA, ((type(uint256).max)));
vm.stopPrank();
uint256 exchangeRateAfter1stRedeem = assetToken.getExchangeRate();
console.log("exchangeRate after 1st redeem",exchangeRateAfter1stRedeem);
console.log("tokenA balance after 1st redeem assetToken",tokenA.balanceOf(address(assetToken)));
console.log("asset balance liquidityProvider after 1st redeem",assetToken.balanceOf(liquidityProvider));
console.log("tokenA balance after 1st redeem user",tokenA.balanceOf(address(liquidityProvider)));
vm.startPrank(liquidityProvider);
vm.expectRevert("ERC20: transfer amount exceeds balance");
thunderLoan.redeem(tokenA, (type(uint256).max));
vm.stopPrank();
}

Tools Used

  • manual code review

  • foundry

Recommendations

Remove below 2 lines:

uint256 calculatedFee = getCalculatedFee(token, amount);
assetToken.updateExchangeRate(calculatedFee);
Updates

Lead Judging Commences

0xnevi Lead Judge over 1 year 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.