Beatland Festival

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

Lack of Emergency Controls (Pause Mechanism) in FestivalPass

Root + Impact

Description

  • FestivalPass does not implement a pause mechanism. The owner cannot halt critical functions such as pass sales (buyPass), memorabilia redemption (redeemMemorabilia), reward distribution (attendPerformance), or even the creation of new memorabilia collections and performances, even if a vulnerability or exploit is discovered. This is against best practices for ERC1155 contracts and exposes the contract to unlimited exploitation in emergencies.

// @> FestivalPass.sol
contract FestivalPass is ERC1155, Ownable2Step, IFestivalPass {
// @> No Pausable inheritance or pause logic
function buyPass(uint256 collectionId) external payable {
// @> No whenNotPaused modifier
...
}
function attendPerformance(uint256 performanceId) external {
// @> No whenNotPaused modifier
...
}
function redeemMemorabilia(uint256 collectionId) external {
// @> No whenNotPaused modifier
...
}
function createPerformance(...) external onlyOrganizer returns (uint256) {
// @> No whenNotPaused modifier
...
}
function createMemorabiliaCollection(...) external onlyOrganizer returns (uint256) {
// @> No whenNotPaused modifier
...
}
}

Risk

Likelihood:

  • When a bug, exploit, or abuse is discovered, the owner cannot stop further damage.

  • All critical functions (pass sales, NFT minting, reward distribution, new collection/performance creation) remain callable at all times.

Impact:

  • Unlimited pass sales, NFT minting, or reward distribution is possible.

  • New memorabilia collections or performances could be created maliciously.

  • User assets and project reputation are at risk.

Proof of Concept

Without a pause mechanism, any vulnerability in buyPass(), attendPerformance(), redeemMemorabilia(), createPerformance(), or createMemorabiliaCollection() can be exploited continuously, as the contract owner cannot intervene to halt these operations.

// Example: If a bug is found in redeemMemorabilia(), the owner cannot stop attackers from minting unlimited NFTs or draining BEAT tokens.
// Example: If a bug is found in buyPass(), attackers can buy unlimited passes even if the system is under attack.

Recommended Mitigation

Add OpenZeppelin’s Pausable and use the whenNotPaused modifier on all sensitive functions, allowing the owner to pause pass sales, memorabilia redemption, reward distribution, and creation of new collections/performances in emergencies.

- contract FestivalPass is ERC1155, Ownable2Step, IFestivalPass {
+ import "@openzeppelin/contracts/security/Pausable.sol";
+ contract FestivalPass is ERC1155, Ownable2Step, Pausable, IFestivalPass {
...
+ function pause() external onlyOwner { _pause(); }
+ function unpause() external onlyOwner { _unpause(); }
- function buyPass(uint256 collectionId) external payable {
+ function buyPass(uint256 collectionId) external payable whenNotPaused {
...
}
- function attendPerformance(uint256 performanceId) external {
+ function attendPerformance(uint256 performanceId) external whenNotPaused {
...
}
- function redeemMemorabilia(uint256 collectionId) external {
+ function redeemMemorabilia(uint256 collectionId) external whenNotPaused {
...
}
- function createPerformance(...) external onlyOrganizer returns (uint256) {
+ function createPerformance(...) external onlyOrganizer whenNotPaused returns (uint256) {
...
}
- function createMemorabiliaCollection(...) external onlyOrganizer returns (uint256) {
+ function createMemorabiliaCollection(...) external onlyOrganizer whenNotPaused returns (uint256) {
...
}
}
Updates

Lead Judging Commences

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

Support

FAQs

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