Beatland Festival

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

No Mechanism to Update BeatToken Address in FestivalPass

Root + Impact

Description

  • Normal Behavior:
    The FestivalPass contract relies on the beatToken address for all BEAT-related operations (minting, burning, rewards, memorabilia redemption). In the event of a bug, upgrade, or migration, it should be possible for the contract owner to update the beatToken address to a new, valid contract.

    Issue:
    Currently, the beatToken address is set only once in the constructor and cannot be changed. If the BeatToken contract is ever upgraded, deprecated, or compromised, all BEAT-related functionality in FestivalPass will be permanently broken, with no way to recover or migrate.

address public beatToken;
constructor(address _beatToken, address _organizer) ERC1155("ipfs://beatdrop/{id}") Ownable(msg.sender){
setOrganizer(_organizer);
beatToken = _beatToken;
}
// No function to update beatToken after deployment

Risk

Likelihood:

  • Upgrades or migrations are rare, but possible due to bugs, exploits, or protocol evolution.

Impact:

  • If the BeatToken contract is deprecated or compromised, all BEAT-related features in FestivalPass will be permanently broken.

Proof of Concept

If a bug or vulnerability is discovered in BeatToken, or if the protocol needs to migrate to a new token contract, there is no way for the owner to update the beatToken address in FestivalPass. All calls to mint, burn, or transfer BEAT will fail or interact with the wrong contract.

// Owner deploys FestivalPass with initial BeatToken address
FestivalPass festival = new FestivalPass(address(beatTokenV1), owner);
// Later, BeatToken is upgraded or replaced (e.g., beatTokenV2)
// There is no function to update the beatToken address in FestivalPass,
// so all BEAT-related features are now permanently broken.

Recommended Mitigation

Add an onlyOwner function to update the beatToken address, with a zero-address check and event emission.

+ event BeatTokenAddressUpdated(address indexed previous, address indexed newAddress);
+ function setBeatToken(address newBeatToken) external onlyOwner {
+ require(newBeatToken != address(0), "BeatToken cannot be zero address");
+ address old = beatToken;
+ beatToken = newBeatToken;
+ emit BeatTokenAddressUpdated(old, newBeatToken);
+ }
Updates

Lead Judging Commences

inallhonesty Lead Judge 28 days ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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