Beatland Festival

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

Reentrancy in redeemMemorabilia

The redeemMemorabilia function likely includes a call to an external contract (e.g., for minting an ERC1155 NFT) before** **updating internal state. If an attacker can exploit this with a fallback function, they could reenter redeemMemorabilia and redeem more items than intended. This violates the integrity of the redemption system and could drain BEAT tokens or inflate the NFT supply


Risk

Likelihood

  • The function is publicly accessible.

  • External minting is commonly delegated to external contracts.

  • If state changes (e.g., currentItemId++, burn(), etc.) happen after the call, reentrancy is exploitable.

Impact

  • Attacker can redeem multiple NFTs for a single BEAT cost.

  • Tokenomics and user trust may be severely damaged.

  • Potential full depletion of redeemable inventory or BEAT reserves.

#This contract will call redeemMemorabilia() again via fallback before state is updated, if no reentrancy protection exists.
contract Attack {
IFestivalPass fp;
bool attacked = false;
function attack() external {
fp.redeemMemorabilia(1); // trigger first call
}
fallback() external {
if (!attacked) {
attacked = true;
fp.redeemMemorabilia(1); // reenter before state is updated
}
}
}

Recommended Mitigation


#Add a reentrancy guard and follow the Checks-Effects-Interactions pattern. Update all internal state before making external calls.
- function attendPerformance(uint256 performanceId) external {
- rewards[msg.sender] += calculateReward(performanceId);
- }
+ mapping(address => mapping(uint256 => bool)) public hasAttended;
+ function attendPerformance(uint256 performanceId) external {
+ require(!hasAttended[msg.sender][performanceId], "Already attended");
+ hasAttended[msg.sender][performanceId] = true;
+ rewards[msg.sender] += calculateReward(performanceId);
+ }
Updates

Lead Judging Commences

inallhonesty Lead Judge 3 months ago
Submission Judgement Published
Invalidated
Reason: Too generic

Support

FAQs

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