Beatland Festival

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

Reentrancy Vulnerability Report: redeemMemorabilia

Reentrancy

Description

  • The redeemMemorabilia()function may be vulnerable to reentrancy attacks if external contracts (like a malicious token) are allowed to call back into it.

    In this case, the contract burns a BEAT token via:

BeatToken(beatToken).burnFrom(msg.sender, collection.priceInBeat);

If burnFrom() is overridden in a malicious token contract, it can call back into redeemMemorabilia() again before the function finishes — allowing multiple redemptions or bypassing conditions like maxSupply.

Risk

Likelihood:

  • Without a nonReentrant modifier, an attacker could:

    • Call redeemMemorabilia()

    • Use a malicious burnFrom() to call it again before currentItemId++ is updated

    • Mint more NFTs than allowed or drain other logic


Proof of Concept

The attacker replaces the real BEAT token with a malicious one:

contract MaliciousToken {
BeatDrop public target;
constructor(address _target) {
target = BeatDrop(_target);
}
function burnFrom(address, uint256) external {
// Reenter before the first redeem finishes
target.redeemMemorabilia(0);
}
}

In a test, calling redeemMemorabilia(0) causes the contract to call it again via burnFrom() — simulating a reentrancy attack.


Recommended Mitigation

Apply the OpenZeppelin ReentrancyGuard and use the nonReentrant modifier:

import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
contract BeatDrop is ReentrancyGuard {
function redeemMemorabilia(uint256 collectionId) external nonReentrant {
// ✅ Now reentrancy is blocked
}
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 26 days ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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