Beatland Festival

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

[L-3] configurePass can change a pass tier's price after passes have already been sold at the original price

Root + Impact

Description

  • configurePass updates passPrice[passId] with no restriction once sales have begun. The organizer can lower the price (disadvantaging early buyers who paid more) or raise it (creating inconsistency mid-sale) at any time without notice.

function configurePass(
uint256 passId,
uint256 price,
uint256 maxSupply
) external onlyOrganizer {
...
// @> price is overwritten with no check on existing sales
passPrice[passId] = price;
passMaxSupply[passId] = maxSupply;
passSupply[passId] = 0;
}

Risk

Likelihood:

  • Requires the organizer to deliberately change the price after passes are already sold.

Impact:

  • Early buyers may feel misled if the price drops. Late buyers may be surprised by a mid-sale price increase.

  • No direct financial loss to the protocol, but damages buyer trust and fairness.

Proof of Concept

The following shows an organizer halving the VIP pass price mid-sale, leaving early buyers who paid the original price with no recourse.

// Organizer sets VIP price at 2 ETH — 50 users buy at 2 ETH
festivalPass.configurePass(VIP_PASS, 2 ether, 100);
// Organizer lowers price to 0.5 ETH mid-sale
// (note: supply also resets — see H-1)
festivalPass.configurePass(VIP_PASS, 0.5 ether, 100);
// Remaining buyers pay 0.5 ETH for the same pass
// Early buyers overpaid by 1.5 ETH with no recourse

Recommended Mitigation

Apply the same guard introduced in H-1: block configurePass once any passes have been sold. This single check prevents both mid-sale price changes (L-3) and supply counter resets (H-1), ensuring all configuration is locked in before the first purchase.

function configurePass(
uint256 passId,
uint256 price,
uint256 maxSupply
) external onlyOrganizer {
require(passId == GENERAL_PASS || passId == VIP_PASS || passId == BACKSTAGE_PASS, "Invalid pass ID");
require(price > 0, "Price must be greater than 0");
require(maxSupply > 0, "Max supply must be greater than 0");
+ require(passSupply[passId] == 0, "Cannot reconfigure a pass tier that already has minted supply");
passPrice[passId] = price;
passMaxSupply[passId] = maxSupply;
- passSupply[passId] = 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!