Beatland Festival

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

[M-1] Supply management vulneribility in `FestivalPass::configurePass` function


Description

In the `FestivalPass::configurePass` function, the contract resets the current supply `passSupply[passId]`
to zero every time the pass configuration is updated, without checking whether tokens have already been minted:
```javascript
passSupply[passId] = 0; // Reset current supply
```
This opens up a supply misrepresentation issue, where an organizer can reset supply tracking and mint more
tokens than intended, bypassing maxSupply logic.

Risk

Impact:

1. Reset supply to 0 after some tokens are minted.
2. Set a new maxSupply (possibly smaller or larger).
3. Continue minting, violating original supply caps.
This creates a trust and fairness issue in the tokenomics of the pass system.

Proof of Concept

```javascript
// Step 1: Configure VIP pass with maxSupply = 100
festivalPass.configurePass(VIP_PASS, 1 ether, 100);
// Step 2: Mint 80 passes
for (uint i = 0; i < 80; i++) {
festivalPass.buyPass{value: 1 ether}(VIP_PASS);
}
// Step 3: Reconfigure with new maxSupply = 50 (bad reset)
festivalPass.configurePass(VIP_PASS, 1 ether, 50);
// Step 4: Mint again — logic only sees "0 < 50", allowing overmint
for (uint i = 0; i < 50; i++) {
festivalPass.buyPass{value: 1 ether}(VIP_PASS);
}
// Actual passes minted: 130 (exceeds both old and new maxSupply)
```
- Over-minting of VIP, BACKSTAGE, or GENERAL passes
- Violates capped supply assumptions
- Affects token value, secondary market trust, and user confidence
- Could be abused by malicious or negligent organizers

Recommended Mitigation

```diff
function configurePass(
uint256 passId,
uint256 price,
uint256 maxSupply
) external onlyOrganizer {
require(passId == GENERAL_PASS || passId == VIP_PASS || passId == BACKSTAGE_PASS, "Invalid pass ID");
require(price > 0, "Price must be greater than 0");
require(maxSupply > 0, "Max supply must be greater than 0");
passPrice[passId] = price;
passMaxSupply[passId] = maxSupply;
- passSupply[passId] = 0; // Reset current supply
}
```
Updates

Lead Judging Commences

inallhonesty Lead Judge 3 months ago
Submission Judgement Published
Validated
Assigned finding tags:

configurePass resets the current pass supply circumventing the max supply check

This is not acceptable as high because any attack vectors related to organizer trying to milk ETH from participants is voided by the fact that the organizer is trusted.

Support

FAQs

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