Beatland Festival

AI First Flight #4
Beginner FriendlyFoundrySolidityNFT
EXP
View results
Submission Details
Impact: low
Likelihood: low
Invalid

[L-1] createPerformance allows a zero baseReward, wasting attendees' cooldown period for no tokens

Root + Impact

Description

  • createPerformance accepts any value for reward, including zero. When an attendee checks into a zero-reward performance, their hasAttended flag is set and their lastCheckIn timestamp is updated, consuming their 1-hour cooldown but they receive zero BEAT tokens.

function createPerformance(
uint256 startTime,
uint256 duration,
uint256 reward // @> no validation that reward > 0
) external onlyOrganizer returns (uint256) {
require(startTime > block.timestamp, "Start time must be in the future");
require(duration > 0, "Duration must be greater than 0");
performances[performanceCount] = Performance({
startTime: startTime,
endTime: startTime + duration,
baseReward: reward // @> stored as-is, can be 0
});
...
}

Risk

Likelihood:

  • Requires the organizer to accidentally or deliberately set a zero reward when creating a performance.

Impact:

  • Attendees who check in to a zero-reward performance lose their cooldown slot and earn nothing, with no warning.

Proof of Concept

The following shows the organizer creating a zero-reward performance, an attendee checking in, and the attendee's cooldown being consumed while their BEAT balance remains unchanged.

// Organizer creates a performance with 0 reward
uint256 perfId = festivalPass.createPerformance(
block.timestamp + 1,
2 hours,
0 // zero reward
);
// Attendee checks in — cooldown is consumed, 0 BEAT minted
vm.warp(block.timestamp + 1);
vm.prank(attendee);
festivalPass.attendPerformance(perfId);
// attendee's lastCheckIn updated, cooldown wasted, balance unchanged

Recommended Mitigation

Add a require(reward > 0) check alongside the existing validations so that zero-reward performances can never be created. This mirrors the pattern already used for price and duration validation elsewhere in the contract.

function createPerformance(
uint256 startTime,
uint256 duration,
uint256 reward
) external onlyOrganizer returns (uint256) {
require(startTime > block.timestamp, "Start time must be in the future");
require(duration > 0, "Duration must be greater than 0");
+ require(reward > 0, "Reward must be greater than 0");
...
}
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge about 5 hours ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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

Give us feedback!