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

LP deposit and withdrawal invariant invalid

Summary

The simplest case where one LP deposit and then want to redeem will fail.
2. The protocol should never lose liquidity provider deposits, it should always go up

Vulnerability Details

This simple test will fail

function testDepositMintsAssetAndWithdraw() public setAllowedToken {
tokenA.mint(liquidityProvider, AMOUNT);
tokenA.mint(liquidityProvider2, AMOUNT);
// # LP1 deposit funds
vm.startPrank(liquidityProvider);
tokenA.approve(address(thunderLoan), AMOUNT);
thunderLoan.deposit(tokenA, AMOUNT);
vm.stopPrank();
// LP2 deposit funds
vm.startPrank(liquidityProvider2);
tokenA.approve(address(thunderLoan), AMOUNT);
thunderLoan.deposit(tokenA, AMOUNT);
vm.stopPrank();
// LP 1 redeem funds
vm.startPrank(liquidityProvider);
thunderLoan.redeem(tokenA, type(uint256).max);
vm.stopPrank();
// check invariant:
// 2. The protocol should never lose liquidity provider deposits,
// it should always go up.
assertGe(tokenA.balanceOf(address(liquidityProvider)), AMOUNT);
// the number of token remaining in the vault should be more than
// the AMOUNT of token deposit by LP2
AssetToken asset = thunderLoan.getAssetFromToken(tokenA);
assertGe(tokenA.balanceOf(address(asset)), AMOUNT);
}

as you can see from the trace

[FAIL. Reason: Assertion failed.] testDepositMintsAssetAndWithdraw() (gas: 1239547)
Logs:
Error: a >= b not satisfied [uint]
Value a: 9954932466300549180
Value b: 10000000000000000000

Impact

huge because LP are loosing underlying token.

Tools Used

foundry unit test

Recommendations

Use a vault standard like erc4626

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.