When attempting to withdraw all underlying tokens by calling the "redeem" function with the maximum uint256 value, the liquidity provider receives a balance exceeded error. This occurs because, after the deposit, the exchange rate increases, and the calculated quantity of underlying tokens, based on the exchange rate, exceeds the quantity of existing tokens in the balance.
This test demonstrates how a liquidity provider makes a deposit and then attempts to withdraw it but receives an error:
Test:
///solidity
function testDepositCannotRedeemAllUnderlying() public setAllowedToken {
uint256 a = 1;
tokenA.mint(liquidityProvider, 100e18);
AssetToken asset = thunderLoan.getAssetFromToken(tokenA);
vm.startPrank(liquidityProvider);
tokenA.approve(address(thunderLoan), 100e18);
console.log("Balance of addres this in token A", tokenA.balanceOf(address(asset)));
console.log("Balance of liquidityProvider in AssetToken", asset.balanceOf(liquidityProvider));
thunderLoan.deposit(tokenA, 10e18);
console.log("Balance of addres this in token A", tokenA.balanceOf(address(asset)));
console.log("Balance of liquidityProvider in AssetToken", asset.balanceOf(liquidityProvider));
thunderLoan.redeem(tokenA, type(uint256).max);
vm.stopPrank();
console.log("Balance of addres this in token A", tokenA.balanceOf(address(asset)));
console.log("Balance of liquidityProvider in AssetToken", asset.balanceOf(liquidityProvider));
assertEq(a, 1);
}
}
///
Error:
[FAIL. Reason: ERC20: transfer amount exceeds balance] testDepositCannotRedeemAllUnderlying()
Logs:
Balance of addres this in token A 0
Balance of liquidityProvider in AssetToken 0
Balance of addres this in token A 10000000000000000000
Balance of liquidityProvider in AssetToken 10000000000000000000
The consequence of this error is the inability to withdraw all tokens. However, a dishonest liquidity provider can exchange only a portion of AssetTokens and later exchange the remaining when the balance of subordinate tokens increases. In other words, they exploit the vulnerability to take what does not belong to them.
Manual rewiev, forge tests.
It is recommended to prevent liquidity providers from affecting the exchange rate by removing these lines of code in the "deposit" function:
///solidity
uint256 calculatedFee = getCalculatedFee(token, amount);
assetToken.updateExchangeRate(calculatedFee);
///
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.