Beatland Festival

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

Festival Contract in BeatToken.sol Can Only Be Set Once

Root + Impact

Description

  • The setFestivalContract() function in BeatToken.sol allows the festival contract address to be set only once, enforced by:

    require(festivalContract == address(0), "Festival contract already set");
  • This means that once an address is assigned—even accidentally—it cannot be changed.

  • This creates an upgradability bottleneck: if the contract needs to migrate or if the deployer makes a mistake, the token contract becomes permanently tied to a single address.

function setFestivalContract(address _festival) external onlyOwner {
@> require(festivalContract == address(0), "Festival contract already set");
festivalContract = _festival;
}

Risk:

  • Prevents the system from recovering if the original festivalContract is compromised or needs replacement.

  • Freezes BEAT token minting and burning features, blocking major user flows like attendance rewards and memorabilia redemptions.

Likelihood:

  • This issue will occur during deployment when the wrong address is accidentally assigned to festivalContract, locking the token contract to an incorrect or unusable contract.

  • It is also likely during contract upgrades or redeployments, where the address of the new FestivalPass contract must be reassigned, but the hard restriction prevents it.



Impact:

  • Break future integration posibilities.

  • Prevents safe redeployment in the event of a bug in FestivalPass

Proof of Concept:

This demonstrates that the contract is intentionally immutable after the first festival is assigned. While this prevents re-use for future festivals, it's good to confirm whether this is a design decision or a potential limitation depending on intended use.

// Assuming 'beatToken' is already deployed and 'owner' is the contract owner
// First call - sets the festivalContract successfully
beatToken.setFestivalContract(address(0x123));
// Second call - attempts to overwrite the festivalContract
beatToken.setFestivalContract(address(0x456));
// This will revert with "Festival contract already set"

Recommended Mitigation:

Update the setFestivalContract function to allow future updates by ensuring only the owner can set a new, valid (non-zero) address, instead of permanently locking it after the first assignment. This improves flexibility in case the initial address needs to be corrected or upgraded.

This ensures that only the contract owner can update the festival contract address, while also preventing accidental assignment to the zero address.

function setFestivalContract(address _festival) external onlyOwner {
require(_festival != address(0), "Invalid festival address");
festivalContract = _festival;
}
Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 month ago
Submission Judgement Published
Invalidated
Reason: Design choice
Assigned finding tags:

`setFestivalContract` only callable once

This is intended. It's done like that because the festival contract requires beat token's address and vice versa.

Support

FAQs

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