Thunder Loan

AI First Flight #7
Beginner FriendlyFoundryDeFiOracle
EXP
View results
Submission Details
Severity: low
Valid

updateFlashLoanFee changes a critical parameter without emitting an event

Summary

updateFlashLoanFee changes the protocol-wide flash-loan fee but emits no event. Off-chain monitors, frontends, indexers, and LPs cannot reliably observe the configuration change without polling storage.

Evidence

src/protocol/ThunderLoan.sol:253-258 validates and assigns s_flashLoanFee = newFee but declares or emits no corresponding fee-update event. The upgraded implementation has the same omission at lines 251-256.

Impact

A fee change can occur without an auditable application-level signal, delaying detection of unexpected or governance-driven changes and causing integrations to quote stale fees.

Minimal patch

Declare event FlashLoanFeeUpdated(uint256 oldFee, uint256 newFee); and emit it after storing the new value. Include both values for monitoring and incident analysis.

Regression test

Call updateFlashLoanFee as owner, expect the event with old and new values, and assert the stored fee changed. Verify a non-owner call still reverts.

Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge about 1 hour ago
Submission Judgement Published
Validated
Assigned finding tags:

[L-02] updateFlashLoanFee() missing event

## Description `ThunderLoan::updateFlashLoanFee()` and `ThunderLoanUpgraded::updateFlashLoanFee()` does not emit an event, so it is difficult to track changes in the value `s_flashLoanFee` off-chain. ## Vulnerability Details ```solidity function updateFlashLoanFee(uint256 newFee) external onlyOwner { if (newFee > FEE_PRECISION) { revert ThunderLoan__BadNewFee(); } @> s_flashLoanFee = newFee; } ``` ## Impact In Ethereum, events are used to facilitate communication between smart contracts and their user interfaces or other off-chain services. When an event is emitted, it gets logged in the transaction receipt, and these logs can be monitored and reacted to by off-chain services or user interfaces. Without a `FeeUpdated` event, any off-chain service or user interface that needs to know the current `s_flashLoanFee` would have to actively query the contract state to get the current value. This is less efficient than simply listening for the `FeeUpdated` event, and it can lead to delays in detecting changes to the `s_flashLoanFee`. The impact of this could be significant because the `s_flashLoanFee` is used to calculate the cost of the flash loan. If the fee changes and an off-chain service or user is not aware of the change because they didn't query the contract state at the right time, they could end up paying a different fee than they expected. ## Recommendations Emit an event for critical parameter changes. ```diff + event FeeUpdated(uint256 indexed newFee); function updateFlashLoanFee(uint256 newFee) external onlyOwner { if (newFee > s_feePrecision) { revert ThunderLoan__BadNewFee(); } s_flashLoanFee = newFee; + emit FeeUpdated(s_flashLoanFee); } ```

Support

FAQs

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

Give us feedback!