Beatland Festival

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

Incorrect use of `FestivalPass::performanceCount` before increment, leading to wrong emit event

Incorrect use of FestivalPass::performanceCount before increment, leading to wrong emit event

Description

In the FestivalPass:createPerformance() function, the contract emits the PerformanceCreated event using performanceCount as the unique performance identifier. However, performanceCount is only incremented after the event is emitted. This results in an off-by-one mismatch between the event log and the actual mapping index used to store the new performance.

If multiple performances are created rapidly or concurrently, this could lead to confusion during indexing, debugging, or when parsing logs off-chain.

....
// Set start/end times
@> performances[performanceCount] = Performance({
startTime: startTime,
endTime: startTime + duration,
baseReward: reward
});
emit PerformanceCreated(performanceCount, startTime, startTime + duration);
return performanceCount++;

Risk

Likelihood:

  • Happens every time a new performance is created.

Impact:

  • Event logs emit the wrong performanceId (off-by-one).

  • Off-chain consumers relying on events may index incorrect performance metadata.

Proof of Concept

Add this Proof of concept to the festivalPass.t.sol to test this.

function test_PerformanceCreatedEvent_MisalignedId() public {
uint256 startTime = block.timestamp + 1 hours;
uint256 duration = 2 hours;
uint256 reward = 100e18;
// First performance creation
vm.prank(organizer);
vm.expectEmit(true, true, true, true);
emit PerformanceCreated(0, startTime, startTime + duration);
uint256 perfId = festivalPass.createPerformance(startTime, duration, reward);
assertEq(perfId, 0);
uint256 startTime2 = block.timestamp + 3 hours;
uint256 duration2 = 2 hours;
uint256 reward2 = 200e18;
// Second performance creation
vm.prank(organizer);
vm.expectEmit(true, true, true, true);
emit PerformanceCreated(1, startTime2, startTime2 + duration2);
uint256 perfId2 = festivalPass.createPerformance(startTime2, duration2, reward2);
assertEq(perfId2, 1);
assertEq(festivalPass.performanceCount(), 2); // Emit event is incorrect because it uses performanceCount() instead of the actual ID
}

Recommended Mitigation

Increment performanceCount before emitting the PerformanceCreated event to ensure the event’s performanceId correctly reflects the unique identifier of the created performance.

+ uint256 performanceId = performanceCount++;
+ performances[performanceId] = Performance({...});
- performances[performanceCount] = Performance({
startTime: startTime,
endTime: startTime + duration,
baseReward: reward
});
- emit PerformanceCreated(performanceCount, startTime, startTime + duration);
+ emit PerformanceCreated(performanceId, startTime, startTime + duration);
- return performanceCount++;
+ return performanceId;
Updates

Lead Judging Commences

inallhonesty Lead Judge
28 days ago
inallhonesty Lead Judge 27 days ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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