Beatland Festival

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

Zero Reward Allowed in `FestivalPass::createPerformance`

Impact

The documentation clearly states that participating in performances grants a reward to users. However, the contract allows organizers to create performances with a reward value of zero. This breaks the expected incentive structure and may cause users to engage with performances under the false assumption that they will be rewarded. Additionally, the PerformanceCreated event emitted by the contract does not include the reward amount, which prevents front-end applications from easily displaying or verifying whether a performance actually offers a reward — further increasing the risk of user deception and reducing transparency


Description

The createPerformance function allows organizers to create a performance with a reward of zero. There is no validation to ensure that the reward is greater than zero, despite the system implying that performances should offer a reward to participants. This can lead to misleading or non-incentivized performances

//@audit Zero Reward Allowed
// Organizer creates a performance
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");
//@audit There is no requirement for the reward to be greater than zero
// Set start/end times
performances[performanceCount] = Performance({
startTime: startTime,
endTime: startTime + duration,
baseReward: reward
});
emit PerformanceCreated(performanceCount, startTime, startTime + duration);
return performanceCount++;
}

Risk

Likelihood:

This vulnerability is moderate to high depending on the organizer's behavior.

Proof of Concept

function test_ZeroRewardPerformance() public {
uint256 startTime = block.timestamp + 1 hours;
uint256 duration = 2 hours;
uint256 reward = 0;
vm.prank(organizer);
festivalPass.createPerformance(startTime, duration, reward);
vm.warp(block.timestamp + 1.5 hours);
vm.startPrank(user1);
festivalPass.buyPass{value : BACKSTAGE_PRICE}(3);
uint balanceBefore = beatToken.balanceOf(user1);
festivalPass.attendPerformance(0);
uint balanceAfter = beatToken.balanceOf(user1);
vm.stopPrank();
assertEq(balanceBefore,balanceAfter);
//VM::assertEq(15000000000000000000 [1.5e19], 15000000000000000000 [1.5e19]) [staticcall]
}

Recommended Mitigation

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 zero");
// Set start/end times
performances[performanceCount] = Performance({
startTime: startTime,
endTime: startTime + duration,
baseReward: reward
});
emit PerformanceCreated(performanceCount, startTime, startTime + duration);
return performanceCount++;
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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