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 10 months 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.

Give us feedback!