Thunder Loan

AI First Flight #7
Beginner FriendlyFoundryDeFiOracle
EXP
View results
Submission Details
Impact: high
Likelihood: medium
Invalid

Division by Zero in `updateExchangeRate()` When `totalSupply()` is Zero

Root + Impact

Description

The updateExchangeRate() function performs a division by totalSupply() without checking if it's zero. If all AssetTokens are redeemed and totalSupply() becomes zero, any subsequent flash loan that tries to update the exchange rate will revert due to division by zero, breaking the flash loan functionality.
function updateExchangeRate(uint256 fee) external onlyThunderLoan {

// 1. Get the current exchange rate

// 2. How big the fee is should be divided by the total supply

// 3. So if the fee is 1e18, and the total supply is 2e18, the exchange rate be multiplied by 1.5

// if the fee is 0.5 ETH, and the total supply is 4, the exchange rate should be multiplied by 1.125

// it should always go up, never down

// newExchangeRate = oldExchangeRate * (totalSupply + fee) / totalSupply

// newExchangeRate = 1 (4 + 0.5) / 4

// newExchangeRate = 1.125

uint256 newExchangeRate = s_exchangeRate * (totalSupply() + fee) / totalSupply(); // @> Division by zero if totalSupply() == 0

if (newExchangeRate <= s_exchangeRate) {

revert AssetToken__ExhangeRateCanOnlyIncrease(s_exchangeRate, newExchangeRate);

}

s_exchangeRate = newExchangeRate;

emit ExchangeRateUpdated(s_exchangeRate);

}

```

If `totalSupply()` is zero, the division will revert, preventing any flash loans from completing successfully.

Risk

Likelihood:

  • * This occurs when all AssetTokens have been redeemed, leaving `totalSupply()` at zero

    * Any flash loan attempted after this point will call `updateExchangeRate()` which will revert

    * While this is an edge case, it's a realistic scenario if all liquidity providers withdraw

Impact:

  • * Flash loan functionality becomes completely broken when totalSupply is zero

    * Protocol cannot process any flash loans until new deposits are made

    * This is a denial of service for the flash loan feature

    * Could be exploited to temporarily disable the protocol's flash loan functionality

Proof of Concept

```solidity
// Scenario:
// 1. Initial deposits: 1000e18 tokens, 1000e18 AssetTokens minted
// 2. All users redeem their AssetTokens: totalSupply() = 0
// 3. Exchange rate is now, say, 1.1e18 (from previous fees)
// 4. Someone tries to take a flash loan
// 5. Flash loan calls updateExchangeRate(fee)
// 6. Calculation: newExchangeRate = 1.1e18 * (0 + fee) / 0
// 7. Division by zero - transaction reverts
// 8. Flash loan cannot complete
```

Recommended Mitigation

Add a check to handle the zero supply case:
```diff
function updateExchangeRate(uint256 fee) external onlyThunderLoan {
+ uint256 currentSupply = totalSupply();
+ if (currentSupply == 0) {
+ revert AssetToken__CannotUpdateWhenSupplyIsZero();
+ }
// 1. Get the current exchange rate
// 2. How big the fee is should be divided by the total supply
// 3. So if the fee is 1e18, and the total supply is 2e18, the exchange rate be multiplied by 1.5
// if the fee is 0.5 ETH, and the total supply is 4, the exchange rate should be multiplied by 1.125
// it should always go up, never down
// newExchangeRate = oldExchangeRate * (totalSupply + fee) / totalSupply
// newExchangeRate = 1 (4 + 0.5) / 4
// newExchangeRate = 1.125
- uint256 newExchangeRate = s_exchangeRate * (totalSupply() + fee) / totalSupply();
+ uint256 newExchangeRate = s_exchangeRate * (currentSupply + fee) / currentSupply();
if (newExchangeRate <= s_exchangeRate) {
revert AssetToken__ExhangeRateCanOnlyIncrease(s_exchangeRate, newExchangeRate);
}
s_exchangeRate = newExchangeRate;
emit ExchangeRateUpdated(s_exchangeRate);
}
```
Also add the error to the contract:
```diff
contract AssetToken is ERC20 {
error AssetToken__onlyThunderLoan();
error AssetToken__ExhangeRateCanOnlyIncrease(uint256 oldExchangeRate, uint256 newExchangeRate);
error AssetToken__ZeroAddress();
+ error AssetToken__CannotUpdateWhenSupplyIsZero();
```
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge 16 days ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!