When you use OpenZeppelin's ERC721 implementation, in most cases you call _safeMint
function. _safeMint
does some obvious basic operations except this one:
require(
_checkOnERC721Received(address(0), to, tokenId, _data),
"ERC721: transfer to non ERC721Receiver implementer"
);
Makes sense it tries to prevent wrong implementation of ERC721Receiver implementation. But it isn't clear when I try to dig deeper:
try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
return retval == IERC721Receiver.onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert("ERC721: transfer to non ERC721Receiver implementer");
} else {
assembly {
revert(add(32, reason), mload(reason))
}
}
}
It's comparing retval
to the function selector to confirm the token transfer. Cool.
But what is assemby trying to do?