It is possible to manipulate the requirement balanceOf(msg.sender) > 0
in the function collectPresent()
to receive a NFT present more than once when the EOA or Contract is NICE
or EXTRA_NICE
. The balanceOf(address)
function in an ERC721 contract returns the amount of NFT's owned by an arbitrary address. In sending the collected present (NFT) to another contract the balanceOf the address is again zero and the requirement balanceOf(msg.sender) > 0
is false.
function collectPresent() external {
if (block.timestamp < CHRISTMAS_2023_BLOCK_TIME) {
revert SantasList__NotChristmasYet();
}
@>>> if (balanceOf(msg.sender) > 0) {
revert SantasList__AlreadyCollected();
}
if (s_theListCheckedOnce[msg.sender] == Status.NICE && s_theListCheckedTwice[msg.sender] == Status.NICE) {
_mintAndIncrement();
return;
} else if (
s_theListCheckedOnce[msg.sender] == Status.EXTRA_NICE
&& s_theListCheckedTwice[msg.sender] == Status.EXTRA_NICE
) {
_mintAndIncrement();
i_santaToken.mint(msg.sender);
return;
}
revert SantasList__NotNice();
}
ERC721Receiver contract to get tokenId (or do all the handling in the callback)
Test function
Foundry
Use an internal mapping
which stores the addresses that received already a present.
Relying on balanceOf > 0 in collectPresent() allows the msg.sender to send their present to another address and then collect again.
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.