Thunder Loan

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

Division by Zero in updateExchangeRate When Total Supply is Zero

[M-1] Division by Zero in updateExchangeRate When Total Supply is Zero

Description

The AssetToken.updateExchangeRate function divides by totalSupply() to calculate the new exchange rate. When the total supply of AssetTokens is zero (before any liquidity providers deposit), this function will revert with a division by zero error.

This prevents flash loans from being executed when there are no AssetToken holders, even if underlying tokens exist in the contract.

function updateExchangeRate(uint256 fee) external onlyThunderLoan {
// @> Division by totalSupply() will revert if totalSupply == 0
uint256 newExchangeRate = s_exchangeRate * (totalSupply() + fee) / totalSupply();
if (newExchangeRate <= s_exchangeRate) {
revert AssetToken__ExhangeRateCanOnlyIncrease(s_exchangeRate, newExchangeRate);
}
s_exchangeRate = newExchangeRate;
emit ExchangeRateUpdated(s_exchangeRate);
}

Risk

Likelihood:

  • Occurs when attempting flash loans before any deposits are made

  • Occurs when all AssetTokens are redeemed and someone attempts a flash loan

  • Requires specific timing but is not attacker-dependent

Impact:

  • Flash loans become temporarily unavailable when total supply is zero

  • Protocol functionality is degraded during periods of no liquidity provider participation

  • Initial bootstrapping of the protocol is more complex

  • Denial of service during edge case scenarios

Proof of Concept

function testFlashLoanRevertsWhenTotalSupplyZero() public setAllowedToken {
// No deposits made - totalSupply() == 0
// Manually send tokens to AssetToken contract (simulating direct transfer)
AssetToken assetToken = thunderLoan.getAssetFromToken(tokenA);
tokenA.mint(address(assetToken), 1000e18);
// Attempt flash loan
vm.expectRevert(); // Reverts with division by zero
thunderLoan.flashloan(
address(mockFlashLoanReceiver),
tokenA,
100e18,
""
);
}

Recommended Mitigation

Add a check to handle the case when total supply is zero. When there are no AssetToken holders, fees should not update the exchange rate since there's no one to distribute the fees to.

function updateExchangeRate(uint256 fee) external onlyThunderLoan {
+ uint256 totalSupply = totalSupply();
+
+ // If no AssetTokens exist, don't update exchange rate
+ if (totalSupply == 0) {
+ return;
+ }
+
- uint256 newExchangeRate = s_exchangeRate * (totalSupply() + fee) / totalSupply();
+ uint256 newExchangeRate = s_exchangeRate * (totalSupply + fee) / totalSupply;
if (newExchangeRate <= s_exchangeRate) {
revert AssetToken__ExhangeRateCanOnlyIncrease(s_exchangeRate, newExchangeRate);
}
s_exchangeRate = newExchangeRate;
emit ExchangeRateUpdated(s_exchangeRate);
}
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge 11 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!