Beatland Festival

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

Block timestamp manipulation allows invalid performance timing

M-2: Block timestamp manipulation allows invalid performance timing

Description

The createPerformance() function validates that a performance start time is in the future by comparing against block.timestamp. This ensures performances cannot be backdated or scheduled in the past.

However, block.timestamp can be manipulated by miners within a ±15 minute window without block rejection by the network. A malicious or bribed miner could manipulate the timestamp to cause legitimate performance creation transactions to fail, or conversely, allow performances scheduled too close to the present to be created.

function createPerformance(
uint256 startTime,
uint256 duration,
uint256 reward
) external onlyOrganizer returns (uint256) {
@> require(startTime > block.timestamp, "Start time must be in the future"); // Vulnerable to timestamp manipulation
require(duration > 0, "Duration must be greater than 0");
performances[performanceCount] = Performance({
startTime: startTime,
endTime: startTime + duration,
baseReward: reward
});
emit PerformanceCreated(performanceCount, startTime, startTime + duration);
return performanceCount++;
}

Risk

Likelihood: Low

  • Requires miner participation or control over block production

  • More likely on networks with few validators or during low network activity

  • Economic incentive for manipulation is low in most cases

  • Becomes higher risk during critical festival operations

Impact: Medium

  • Organizer cannot create performances scheduled 5-10 minutes in future if miner pushes timestamp forward

  • Performances could be created with start times already passed if miner pulls timestamp backward

  • Disrupts festival scheduling and user experience

  • Could cause missed performance windows or double-bookings

Proof of Concept

// Scenario: Organizer tries to schedule performance 10 minutes in future
// Current real time: 12:00 PM
// Current block.timestamp: 12:00 PM (manipulated by miner to 12:11 PM)
uint256 startTime = block.timestamp + 10 minutes; // Organizer thinks this is 12:10 PM
// But block.timestamp = 12:11 PM (miner manipulation)
// So startTime = 12:21 PM
festivalPass.createPerformance(
block.timestamp + 10 minutes, // Thinks it's 12:10, actually 12:21
1 hours,
100e18
);
// In next block (miner returns timestamp to normal):
// block.timestamp = 12:01 PM
// Performance startTime = 12:21 PM, but organizer expected 12:10 PM
// Performance doesn't become active when expected
// Opposite scenario:
// Organizer schedules for exactly 12:01 PM
// Miner sets block.timestamp to 12:01:01 PM
// require(12:01 PM > 12:01:01 PM) fails
// Transaction reverts unexpectedly

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(startTime > block.timestamp + 15 minutes, "Start time must be at least 15 minutes in future");
require(duration > 0, "Duration must be greater than 0");
+ require(duration <= 365 days, "Duration exceeds maximum allowed");
+ require(reward > 0, "Reward must be greater than 0");
performances[performanceCount] = Performance({
startTime: startTime,
endTime: startTime + duration,
baseReward: reward
});
emit PerformanceCreated(performanceCount, startTime, startTime + duration);
return performanceCount++;
}
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge 14 days 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!