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

Wrong crypto economic incentive makes it possible to steal the liquidity provided by the previous LPs

Summary

There is the explicit expectation in the code that, the exchange rate will always go up.

Vulnerability Details

In the codebase, we have the line

if (newExchangeRate <= s_exchangeRate) {

Let's assume 2 instants in time T1 and T2 spread 2 days apart. At T1, we deposit amount A1 of liquidity to the pool and we get a new exchange rate of E1 and at T2, we deposit amount A1 of liquidity again to the same pool of T1 and we get a new exchange rate of E2.

This means that, E2 > E1 this means that, even though in both cases we're minted amount A1 of AssetTokens, the LP redeems at an exchange rate of E2 will receive more underlying tokens that was supposed to at the expense of the other LPs that haven't yet redeemed even if no flash-loan was taken between T1 and T2.

Let's note that, this is also agravated by the fact that, we fail to adjust the exchange rate to a newer and lower value when LPs withdraw funds in the application in the following methods.

src/protocol/ThunderLoan::redeem
Even though the exchange rate was increased when a deposit was made.

src/protocol/ThunderLoan::repay
Even though the exchange rate was increased when a flash-loan was taken.

POC

put this piece of code in `test/unit/ThunderLoanTest.t.sol`
function testWrongExchangeRateVulnerability() public setAllowedToken {
address randomUser = address(20);
tokenA.mint(liquidityProvider, AMOUNT);
tokenA.mint(randomUser, AMOUNT);
vm.startPrank(randomUser);
tokenA.approve(address(thunderLoan), AMOUNT);
thunderLoan.deposit(tokenA, AMOUNT);
vm.stopPrank();
vm.startPrank(liquidityProvider);
tokenA.approve(address(thunderLoan), AMOUNT);
thunderLoan.deposit(tokenA, AMOUNT);
uint lpBalance = tokenA.balanceOf(liquidityProvider);
thunderLoan.redeem(tokenA, AMOUNT);
uint lpBalanceAfter = tokenA.balanceOf(liquidityProvider);
assertGt(lpBalanceAfter, lpBalance);
vm.stopPrank();
vm.prank(randomUser);
thunderLoan.redeem(tokenA, AMOUNT);
}

run forge test --mt testWrongExchangeRateVulnerability -vvv

Impact

Malicious LP can steal the liquidity provided by the other LPs.

Tools Used

Manual review

Recommendations

Review the updateExchangeRate method and enable the exchange rate to increase/decrease according to the current liquidity in reserve.

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.