The buyPass()
function contains a reentrancy vulnerability due to incorrect ordering of state updates and external calls. The function calls _mint()
before incrementing passSupply[collectionId]
, and since _mint()
triggers the ERC1155 onERC1155Received
hook on recipient contracts, malicious contracts can re-enter buyPass()
during the minting process. During reentrancy, the passSupply
counter has not yet been updated, allowing the attacker to bypass the require(passSupply[collectionId] < passMaxSupply[collectionId])
check multiple times and purchase more passes than the configured maximum supply limit.
Organizer configures pass type with limited maxSupply
(e.g., 3 VIP passes for venue capacity control)
Attacker deploys malicious contract implementing onERC1155Received
hook
Attacker calls buyPass()
with sufficient ETH for multiple passes
buyPass()
checks passSupply[1] < maxSupply[1]
(0 < 3) and proceeds
Function calls _mint()
which triggers onERC1155Received()
on attacker's contract
Attacker's hook calls buyPass()
again while passSupply
is still 0
Second call passes the same supply check (0 < 3) and calls _mint()
again
Process repeats 5 times through nested reentrancy calls
Only after all reentrancy calls complete does passSupply
get incremented to 5
Attacker receives 5 passes despite maxSupply
being only 3
Once attacker exceeds maxSupply
through reentrancy, all subsequent buyPass()
calls from legitimate users will revert with "Max supply reached"
despite passes being artificially oversold leading to DoS
Selling more passes than venue capacity creates dangerous overcrowding conditions, especially if the attacker distributes the excess passes to different people who then attend performances, resulting in actual physical overcrowding beyond safety limits
Exceeding fire codes and building capacity limits poses serious injury risks
Create a AttackContract.sol
file and put it into the test
folder
Place this import into the FestivalPass.t.sol
file
Place this test after the setUp()
in the FestivalPass.t.sol
file
Run forge test --match-test test_ReentrancyAttack_BuyPass -vvv
in the terminal
Implement the Checks-Effects-Interactions pattern by moving state updates before external calls:
Alternatively, implement OpenZeppelin's ReentrancyGuard
modifier for additional protection.
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.