Beatland Festival

First Flight #44
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Impact: low
Likelihood: medium
Invalid

[ L-5 ] - Missing Events for Access Control

Missing Events for Access Control + Off-Chain Monitoring Blindness

Description

  • Normal Behavior:
    In well-designed smart contracts, any change to critical access control parameters (such as the organizer or owner) should emit an event. Events are essential for off-chain systems, dApps, and users to track changes, audit contract activity, and respond to potential threats or misconfigurations. They are the primary mechanism for external observers to monitor contract state changes without constant polling.

  • Issue:
    In the FestivalPass contract, the setOrganizer function changes the critical organizer role but does not emit an event. This omission means that off-chain systems, such as block explorers, analytics dashboards, and security monitors, cannot detect or respond to changes in the organizer role. This can lead to missed alerts for malicious or accidental changes, and makes it difficult for users and auditors to track the contract’s history.

  • Relevant Code Example:

function setOrganizer(address _organizer) external onlyOwner {
@> organizer = _organizer;
// Missing: emit OrganizerChanged(_organizer);
}

Risk

Likelihood:

  • This will occur every time the organizer is changed, which may happen during normal operations, upgrades, or in response to a security incident.

  • The risk is present in all deployments where off-chain monitoring or transparency is important.

Impact:

  • Monitoring Blindness: Off-chain systems and users cannot detect or respond to changes in the organizer role, missing potential attacks or misconfigurations.

  • Audit Difficulty: Auditors and users cannot reconstruct the history of access control changes, making it harder to verify the contract’s integrity and governance.

  • Delayed Response: Security incidents or mistakes may go unnoticed for longer, increasing the risk of damage.

Proof of Concept

To reproduce this issue, copy and paste the following test code into your test file (e.g., test/contract.t.sol). This test demonstrates that changing the organizer does not emit an event, making it invisible to off-chain listeners:

function test_MissingEventForSetOrganizer() public {
// Listen for OrganizerChanged event
vm.recordLogs();
// Change the organizer
address newOrganizer = address(0x1234);
vm.prank(owner);
festivalPass.setOrganizer(newOrganizer);
// Retrieve logs
Vm.Log[] memory entries = vm.getRecordedLogs();
// Check that no OrganizerChanged event was emitted
bool eventFound = false;
for (uint256 i = 0; i < entries.length; i++) {
if (entries[i].topics.length > 0 && entries[i].topics[0] == keccak256("OrganizerChanged(address)")) {
eventFound = true;
break;
}
}
assertFalse(eventFound, "No OrganizerChanged event should be emitted");
}

Explanation:

  • The test changes the organizer and records all logs.

  • It checks for the presence of an OrganizerChanged event.

  • Since the event is missing, off-chain systems cannot detect the change.

Recommended Mitigation

Add an event declaration and emit it whenever the organizer is changed. This enables off-chain monitoring and improves transparency.

+ event OrganizerChanged(address indexed newOrganizer);
function setOrganizer(address _organizer) external onlyOwner {
require(_organizer != address(0), "Organizer cannot be zero address");
organizer = _organizer;
+ emit OrganizerChanged(_organizer);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge about 2 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

Missing events / Events not properly configured

Informational. This protocol doesn't rely on events to function, they are just nice to have, but not mandatory.

Support

FAQs

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