Thunder Loan

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

updateExchangeRate Divides by totalSupply() Before Any Deposit — First User Can Permanently Brick the Pool

Root + Impact

Description

  • Describe the normal behavior in one or more sentences

  • Explain the specific issue or problem in one or more sentences

# [M-#] `updateExchangeRate` Divides by `totalSupply()` Before Any Deposit — First User Can Permanently Brick the Pool
## Summary
The `AssetToken.updateExchangeRate` function calculates the new exchange rate using a division by `totalSupply()`. Before any liquidity provider (LP) deposits tokens into the pool, `totalSupply()` evaluates to zero. If the function is called during this uninitialized phase, it triggers a Division by Zero panic error, rendering the pool permanently unusable.
## Vulnerability Details
In `AssetToken.sol`, the exchange rate calculation is implemented as follows:
```solidity
newExchangeRate = s_exchangeRate * (totalSupply() + fee) / totalSupply();
```
If `updateExchangeRate` is invoked (for instance, via a flash loan or operational fee calculation) before the first LP deposit has occurred, the execution reaches this line while `totalSupply()` is `0`. Solidity automatically triggers a panic error (`Panic(0x12)`) due to division by zero, causing the entire transaction to revert.
A malicious actor can easily exploit this by front-running the first legitimate deposit with a zero-deposit flash loan transaction. This forces an immediate call to `updateExchangeRate`, inducing the panic and permanently preventing the pool from initializing or accepting initial liquidity.
## Impact
**Medium.** Any newly deployed token pool that processes a flash loan or fee update before its initial deposit becomes completely and permanently broken. Liquidity providers are blocked from entering, forcing a redeployment of the contract and resulting in a complete denial of service for that specific pool.
## Proof of Concept
Add the following test to your test suite to demonstrate the vulnerability:
```solidity
function test_PoC2_UpdateExchangeRate_DivByZero() public {
// 1. Setup asset token with 0 total supply
AssetToken assetToken = new AssetToken(address(underlying), address(thunderLoan));
// 2. Simulate a call from the authorized ThunderLoan contract before any deposits exist
vm.prank(address(thunderLoan));
// 3. The transaction reverts with a Division by Zero panic error
vm.expectRevert(); // Panic(0x12) division by zero
assetToken.updateExchangeRate(100);
}
```
## Tools Used
* Manual Code Review
## Recommendations
Add a conditional guard check at the beginning of `updateExchangeRate` to handle cases where no liquidity exists yet:
```solidity
function updateExchangeRate(uint256 fee) external onlyThunderLoan {
// @audit-issue Guard against division by zero if there are no LPs yet
if (totalSupply() == 0) {
return; // No LPs to accrue fees to
}
// ... existing logic
newExchangeRate = s_exchangeRate * (totalSupply() + fee) / totalSupply();
}
```
// Root cause in the codebase with @> marks to highlight the relevant section

Risk

Likelihood:

  • Reason 1 // Describe WHEN this will occur (avoid using "if" statements)

  • Reason 2

Impact:

  • Impact 1

  • Impact 2

Proof of Concept

Recommended Mitigation

- remove this code
+ add this code
Updates

Lead Judging Commences

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