Beatland Festival

First Flight #44
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Severity: low
Valid

FestivalPass.sol - Inactive Collections Cannot Be Activated Later

Description

The createMemorabiliaCollection function allows organizers to create collections with activateNow = false, but there is no mechanism to activate these collections later. Once a collection is created as inactive, it remains permanently unusable, making it impossible for users to redeem memorabilia from these collections even if the organizer intended to activate them at a later time.

Root Cause

The contract lacks a function to update the isActive status of existing collections:

// Line 196: Collections can be created with isActive = false
isActive: activateNow
// But no function exists to change isActive from false to true later
// Missing: function activateCollection(uint256 collectionId) external onlyOrganizer

Key issues:

  1. No activateCollection or setCollectionActive function exists

  2. The isActive field becomes permanently frozen at creation time

  3. Organizers cannot implement delayed launches or scheduled activations

Risk

Likelihood: Medium - Organizers may reasonably want to create collections in advance and activate them later for marketing or timing purposes.

Impact: Medium - Collections become permanently unusable, wasting organizer effort and preventing intended memorabilia redemptions.

Impact

Medium severity because:

  • Entire memorabilia collections can become permanently unusable

  • Organizers lose the ability to implement delayed collection launches

  • No way to recover from accidentally creating inactive collections

  • Reduces flexibility in memorabilia collection management

  • Users cannot redeem from collections that should be activatable

Proof of Concept

This test demonstrates how collections created as inactive cannot be activated later:

function test_InactiveCollectionCannotBeActivated() public {
// Organizer creates collection but sets it inactive
vm.prank(organizer);
uint256 collectionId = festivalPass.createMemorabiliaCollection(
"Limited Edition",
"ipfs://limited",
100e18,
10,
false // activateNow = false - collection is created but inactive
);
// Give user BEAT tokens to attempt redemption
vm.prank(address(festivalPass));
beatToken.mint(user1, 100e18);
// User tries to redeem from inactive collection - fails
vm.prank(user1);
vm.expectRevert("Collection not active");
festivalPass.redeemMemorabilia(collectionId);
// There's NO function for organizer to activate the collection later!
// The collection is permanently unusable if created with activateNow = false
// This is a design flaw - collections should be activatable after creation
}

Recommended Mitigation

Add a function to allow organizers to update collection activation status:

+ /**
+ * @notice Set the active status of a memorabilia collection
+ * @param collectionId ID of the collection to update
+ * @param active True to activate the collection, false to deactivate
+ */
+ function setCollectionActive(uint256 collectionId, bool active) external onlyOrganizer {
+ require(collections[collectionId].priceInBeat > 0, "Collection does not exist");
+ require(collections[collectionId].isActive != active, "Collection already in requested state");
+
+ collections[collectionId].isActive = active;
+ emit CollectionStatusChanged(collectionId, active);
+ }

Also add the corresponding event to the interface:

+ /**
+ * @notice Emitted when a collection's active status changes
+ * @param collectionId ID of the collection
+ * @param isActive New active status of the collection
+ */
+ event CollectionStatusChanged(uint256 indexed collectionId, bool isActive);

This solution provides organizers with full control over collection activation timing and allows for recovery from creation mistakes.

Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 month ago
Submission Judgement Published
Validated
Assigned finding tags:

createMemorabiliaCollection with isActive false for later usage - flow not properly implemented.

Low because an organizer can use it with active = true and organizer is trusted.

Support

FAQs

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