User can collect NFT gift continuously.
The if check that attempts to check the balance of a user before granting access to mint is not conclusive. A user can own the NFT, transfer it to another address, and still be eligible to collect again because his original address balance now reads zero which satisfies the requirement check.
Manual
The ownership of the NFT can be tracked with a mapping so that when a user collects once, the mapping is updated and there is further logic to prevent the user from collecting again based on this updated mapping.
mapping (address =>bool) public hasCollected; // list of addresses to boolean values that indicate if an address has or has not collected
require(!hasCollected[msg.sender],"You have already collected your gift");
//The logic for minting goes here
//...
hasCollected[msg.sender] = true; // Prevents this user from collecting again.
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.