updateFlashLoanFee() is an onlyOwner function that modifies s_flashLoanFee — the protocol's core revenue parameter that directly sets the percentage borrowers pay on every flash loan.
No event is emitted when the fee changes. Off-chain monitors, integrators, front-ends, and LPs have no way to detect fee changes without scanning all transactions to the owner address and decoding calldata manually.
This violates the standard practice of emitting events for all state-changing governance actions, and it breaks any tooling that relies on event-based state tracking (subgraphs, LP dashboards, alerts).
Likelihood: High — every call to updateFlashLoanFee produces no on-chain log. Any monitoring or integration relying on events will miss fee changes entirely.
Impact: Low — no direct fund loss, but fee changes silently take effect. LPs and integrators depending on the current fee rate for off-chain calculations will work with stale data until they re-query storage directly.
Static analysis / grep confirms no event is defined or emitted for fee updates:
Add a FlashLoanFeeUpdated event and emit it inside updateFlashLoanFee:
## 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); } ```
The contest is live. Earn rewards by submitting a finding.
Submissions are being reviewed by our AI judge. Results will be available in a few minutes.
View all submissionsThe contest is complete and the rewards are being distributed.