The function buyPresent(address presentReceiver) allows any user to burn SantaTokens belonging to an arbitrary address, as long as the SantasList contract has been approved to spend tokens.
However, the NFT minted by _mintAndIncrement() is always assigned to msg.sender, not to the owner of the burned SantaToken.
This creates a critical mismatch between the burned token owner and the NFT recipient, enabling theft of NFTs from legitimate token holders.
https://github.com/CodeHawks-Contests/ai-santas-list/blob/main/src/SantasList.sol#L168-L175
The function burns SantaTokens from presentReceiver:
This assumes the caller is legitimately authorized to burn tokens of presentReceiver.
No check is performed to ensure that msg.sender == presentReceiver.
The NFT is minted to msg.sender:
meaning the caller receives the NFT regardless of whose tokens were burned.
An attacker can:
Monitor the blockchain for approvals to the SantasList contract
Wait until a user approves token spending
Immediately call buyPresent(presentReceiver) using the victim address
Burn the victim’s SantaTokens
Mint and receive the NFT for themselves
➡️ Direct theft of NFTs from users who only approved token spending
This breaks fundamental assumptions of ownership and authorization.
Victim approves SantasList contract:
Attacker monitors the blockchain and detects approval.
Attacker calls:
Outcome:
Victim’s SantaTokens are burned
Attacker receives NFT minted via _mintAndIncrement()
Missing authorization check on presentReceiver
Logical inconsistency between:
token burn source (presentReceiver)
NFT recipient (msg.sender)
Require that the caller is the owner of the tokens being burned:
Alternatively, if delegated burning is intended, then NFT should be minted to presentReceiver instead:
This vulnerability allows any approved contract user to have their SantaTokens burned and lose NFT rewards, while an attacker profits. The inconsistency between burned token owner and NFT recipient leads to a high-severity asset theft issue.
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.