I wrote this test in which three people deposit and then withdraw without any flash loaning in the interim. They should each get back the amount they put in, but the first two depositors get back more than they should, leaving the third depositor with less than they should get. Redeem reverts for the third person trying to redeem because there are not enough underlying tokens left to give them their full redemption. You have to add two additional prank LPs.
function testMultipleDepositsMultipleRedeems() public setAllowedToken {
AssetToken asset = thunderLoan.getAssetFromToken(tokenA);
tokenA.mint(liquidityProvider, DEPOSIT_AMOUNT);
uint256 lpInitialBalance = tokenA.balanceOf(liquidityProvider);
console.log("liquidityprovider initial balance:", lpInitialBalance);
tokenA.mint(lp2, AMOUNT);
uint256 lp2InitialBalance = tokenA.balanceOf(lp2);
console.log("lp2 initial balance:", lp2InitialBalance);
tokenA.mint(lp3, AMOUNT);
uint256 lp3InitialBalance = tokenA.balanceOf(lp3);
console.log("lp3 initial balance:", lp3InitialBalance);
vm.startPrank(liquidityProvider);
tokenA.approve(address(thunderLoan), DEPOSIT_AMOUNT);
thunderLoan.deposit(tokenA, DEPOSIT_AMOUNT);
uint256 lpAssetTokens = asset.balanceOf(liquidityProvider);
vm.stopPrank();
vm.startPrank(lp2);
tokenA.approve(address(thunderLoan), AMOUNT);
thunderLoan.deposit(tokenA, AMOUNT);
uint256 lp2AssetTokens = asset.balanceOf(lp2);
vm.stopPrank();
vm.startPrank(lp3);
tokenA.approve(address(thunderLoan), AMOUNT);
thunderLoan.deposit(tokenA, AMOUNT);
uint256 lp3AssetTokens = asset.balanceOf(lp3);
vm.stopPrank();
vm.startPrank(lp2);
thunderLoan.redeem(tokenA, lp2AssetTokens);
uint256 lp2EndingBalance = tokenA.balanceOf(lp2);
console.log("lp2 ending balance:", lp2EndingBalance);
vm.stopPrank();
vm.startPrank(liquidityProvider);
thunderLoan.redeem(tokenA, lpAssetTokens);
uint256 lpEndingBalance = tokenA.balanceOf(liquidityProvider);
console.log("lp ending balance:", lpEndingBalance);
vm.stopPrank();
vm.startPrank(lp3);
thunderLoan.redeem(tokenA, lp3AssetTokens);
uint256 lp3EndingBalance = tokenA.balanceOf(lp3);
console.log("lp3 ending balance:", lp3EndingBalance);
vm.stopPrank();
assertEq(lpInitialBalance, lpEndingBalance);
assertEq(lp2InitialBalance, lp2EndingBalance);
assertEq(lp3InitialBalance, lp3EndingBalance);
}
Here are the console logs...there is no ending balance for lp3 because redeem reverted because there wasn't enough tokens to send to lp3. You can see that lp2 and lp got more tokens than they should have:
Some depositors get more than their fair share of the underlying tokens and others can't withdraw because there aren't sufficient tokens in the asset token contract to fully redeem them, so redeem reverts.
To figure out the cause of this, I tried running the same test but commented out these two lines in the deposit function and this time around the test passed. I recommend removing these lines.