DittoETH

Ditto
DeFiFoundryOracle
55,000 USDC
View results
Submission Details
Severity: low
Invalid

ERC721 token receiver check

Summary

ERC721 token receiver check

Vulnerability Details

The vulnerabi.lity in lines 223 to 229 is related to the implementation of the ERC721 token receiver check The _checkOnERC721Received function is designed to ensure that the recipient of the token transfer is capable of receiving ERC721 tokens. However, the function only checks if the recipient's contract code length is greater than 0, and if so, it attempts to call the onERC721Received function on the recipient contract. If the recipient contract does not implement the onERC721Received function correctly or at all, the function call will fail and the token transfer will be reverted. However, if the recipient is a contract with a code length of 0, the function will return true without any further checks. This could potentially allow tokens to be transferred to contracts that are not capable of handling them, resulting in the permanent loss of the tokens.

Tools Used

vscode

Recommendations

To resolve this issue, you should add an additional check to ensure that the recipient contract implements the IERC721Receiver interface correctly. This can be done by checking if the return value of the onERC721Received function call is equal to the correct magic value. If the return value is not equal to the correct magic value, the function should revert the transaction. Here is the modified code:

function _checkOnERC721Received(
address from,
address to,
uint256 tokenId,
bytes memory data
) private returns (bool) {
if (to.isContract()) {
try IERC721Receiver(to).onERC721Received(msg.sender, from, tokenId, data)
returns (bytes4 retval) {
return retval == IERC721Receiver.onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert Errors.ERC721InvalidReceiver(to);
} else {
assembly {
revert(add(32, reason), mload(reason))
}
}
}
} else {
return true;
}
}

In this modified code, the isContract function is used to check if the recipient is a contract. This function should return true if the recipient is a contract and false if it is an externally owned account. If the recipient is a contract, the function attempts to call the onERC721Received function on the recipient contract and checks if the return value is equal to the correct magic value. If the recipient is not a contract, the function returns true without any further checks. This ensures that tokens cannot be transferred to contracts that are not capable of handling them.

Updates

Lead Judging Commences

0xnevi Lead Judge
over 1 year ago
0xnevi Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Other

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.