Thunder Loan

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

Missing Event Emission in `updateFlashLoanFee()`

Root + Impact

Description

  • The `updateFlashLoanFee()` function updates the `s_flashLoanFee` state variable without emitting an event. This reduces transparency and makes it difficult to track fee changes off-chain, which is important for protocol monitoring and user awareness.


    The function updates state without emitting an event:

    ```solidity

    function updateFlashLoanFee(uint256 newFee) external onlyOwner {

    if (newFee > s_feePrecision) {

    revert ThunderLoan__BadNewFee();

    }

    s_flashLoanFee = newFee; // @> State updated without event

    }

    ```

Risk

Likelihood:

  • * This occurs every time the owner updates the flash loan fee

    * No special conditions required

Impact:

  • * Reduced transparency for fee changes

    * Off-chain monitoring systems cannot easily track fee updates

    * Users may not be aware of fee changes

    * Makes protocol governance less transparent

Proof of Concept

```solidity
// Scenario:
// 1. Owner calls updateFlashLoanFee(5e15) to change fee from 0.3% to 0.5%
// 2. State variable updated
// 3. No event emitted
// 4. Off-chain systems cannot detect the change
// 5. Users may not be aware of the fee increase
```

Recommended Mitigation

Add an event emission:
```diff
event Deposit(address indexed account, IERC20 indexed token, uint256 amount);
event AllowedTokenSet(IERC20 indexed token, AssetToken indexed asset, bool allowed);
event Redeemed(
address indexed account, IERC20 indexed token, uint256 amountOfAssetToken, uint256 amountOfUnderlying
);
event FlashLoan(address indexed receiverAddress, IERC20 indexed token, uint256 amount, uint256 fee, bytes params);
+event FlashLoanFeeUpdated(uint256 oldFee, uint256 newFee);
function updateFlashLoanFee(uint256 newFee) external onlyOwner {
if (newFee > s_feePrecision) {
revert ThunderLoan__BadNewFee();
}
+ uint256 oldFee = s_flashLoanFee;
s_flashLoanFee = newFee;
+ emit FlashLoanFeeUpdated(oldFee, newFee);
}
```
Updates

Lead Judging Commences

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