in the claimNft
function, the contract attempts to transfer an NFT without verifying ownership, also violating the ERC721 specification requirements. This could lead to failed transactions and potential token lockup scenarios. The function assumes that if the contract has ERC20 tokens to burn and balances are correct, it must also have the NFT to transfer.
The vulnerable implementation is in the claimNft
function:
The function uses safeTransferFrom
, which according to the ERC721 spec:
Throws if _from
is not the current owner
Throws if _to
is the zero address
Throws if _tokenId
is not a valid NFT
When transfer is complete, this function checks if _to
is a smart contract (code size > 0). If so, it calls onERC721Received
on _to
However, from the line in claimNFT
function,
The implementation doesn't check if the contract actually owns the NFT before attempting the transfer. According to the ERC-721 specification, safeTransferFrom
should throw if _from
is not the current owner.
From ERC-721 Documentation:
The current implementation violates this specification by not verifying if the contract (address(this)) is the current owner of the NFT using ownerOf(tokenId)
before attempting the transfer.
Without the ownership check, the function would:
Burn the user's ERC20 tokens
Set their balance to 0
Try to transfer an NFT that the contract doesn't own
The transfer would fail since the contract doesn't own the NFT
The entire transaction would revert
If users attempt to claim an NFT that the contract no longer owns, their ERC20 tokens could become permanently locked. This would result in the transaction reverting after tokens are burned, causing users to waste gas on failed transactions, while the ERC20 tokens remain in circulation without any backing NFTs.
Manual Review
To allow users to claim NFTs without the risk of permanently locking their ERC20 tokens or wasting gas on failed transactions, the contract should verify ownership of the NFT before proceeding with the transfer. By ensuring the contract still owns the NFT, users can avoid unnecessary token burns and revert errors.
This implementation ensures that the contract's ownership of the NFT is verified before burning the user’s ERC20 tokens and transferring the NFT, preventing unnecessary gas expenditure and maintaining a secure and predictable claim process.
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.