_mintAndIncrement calls OpenZeppelin's _safeMint, which — when the recipient is a contract — triggers onERC721Received on that contract before returning. This is the intended ERC-721 safety callback, but it hands execution to untrusted external code while the protocol has not yet recorded that the operation is complete.
buyPresent has no reentrancy guard:
A malicious contract deployed as the NFT recipient can exploit the onERC721Received callback to call buyPresent again before the first invocation completes. Each recursive call burns another 1e18 SantaTokens from the victim and mints another NFT to the attacker — all within a single top-level transaction.
Attack path:
Attacker deploys a contract (MaliciousReceiver) implementing onERC721Received.
Attacker calls buyPresent(victim).
Protocol burns 1e18 from the victim, then calls _safeMint(attacker_contract, tokenId).
ERC-721 triggers attacker_contract.onERC721Received(...).
Inside the callback, attacker calls buyPresent(victim) again — burning another 1e18, minting another NFT.
Steps 4–5 repeat until the attacker's re-entry counter exits or the victim's balance is zero.
This is compounded by H-02 below: buyPresent burns from the victim's address unconditionally, so the attacker never needs to hold or spend any tokens themselves.
A victim's entire SantaToken balance can be drained in a single transaction.
The attacker receives one NFT per re-entry at zero cost to themselves.
No attacker prerequisites beyond deploying a contract: no tokens, no approval, no special status.
Attack contract (test/unit/SantasListTest.t.sol:229):
Test (test/unit/SantasListTest.t.sol:156):
Result: A single external call to buyPresent produces 4 NFTs for the attacker and 0 remaining tokens for the victim.
Add OpenZeppelin's ReentrancyGuard and apply nonReentrant to buyPresent:
The contest is live. Earn rewards by submitting a finding.
Submissions are being reviewed by our AI judge. Results will be available in a few minutes.
View all submissionsThe contest is complete and the rewards are being distributed.