first of all im sorry for any inconvenience in reading the code or in anything as this is my first submission.
The buyPass() function currently violates the Checks-Effects-Interactions (CEI) pattern by invoking an external call to BeatToken.mint before all internal state transitions are securely finalized. Although passSupply is incremented prior to the external call, this alone does not fully safeguard the function. The external mint call may trigger untrusted behavior (e.g., via future modifications to BeatToken or ERC1155 receiver hooks), which could enable reentrant entry into buyPass.
the contract does not implement any reentrancy protection mechanisms such as a nonReentrant modifier or proper isolation of internal logic. This opens the possibility for an attacker to exploit the contract through reentrancy before internal logic is complete, potentially bypassing supply constraints or claiming BEAT token rewards multiple times.
Likelihood:
A malicious contract implementing the ERC1155Receiver interface can:
In the onERC1155Received() callback, call buyPass() again recursively.
Since passSupply is incremented only after the external _mint() call, the nested call sees outdated state and incorrectly allows further minting.
Consequences:
Attacker can mint unlimited festival passes
Attacker can claim unlimited BEAT token bonuses tied to VIP or BACKSTAGE passes.
Results in financial loss and broken pass distribution logic.
Impact:
Attacker having more then one Passes breaking the protocol's functonality
Contracts's security severly damaged and financial loss
This PoC demonstrates a reentrancy vulnerability in the buyPass function of the FestivalPass contract. It does so by deploying a malicious contract (AttackerContract) that exploits the fact that FestivalPass calls an external contract (BeatToken.mint) before completing its internal state updates.
In this specific test:
The attacker initiates a buyPass call with enough ETH for a single VIP pass.
Upon receiving the ERC1155 token, the attacker’s onERC1155Received callback re-enters buyPass again, bypassing supply limits.
This results in the attacker receiving 2 VIP passes and 10 BEAT tokens, despite paying only once and when only 1 pass was expected.
The test confirms the vulnerability by checking that:
The attacker receives BEAT tokens for both mints.
The festival contract receives payment only once.
This clearly proves that the function is vulnerable to reentrancy and allows unauthorized repeated state manipulation and token minting.
This is the code which will not have reentrancy issue.
A good Recommendation from me would be that use ReentrancyGuard on functions that are:
Transfer ETH or tokens (e.g., payable or mint/burn).
Interact with untrusted contracts (external calls).
Modify critical state variables that could be exploited if called recursively.
It accepts ETH
It updates state
It calls an external contract.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.