In my transfer function, I want to only allow the to address to be a contract that implements a certain interface.

I used this to check:

require(IERC165(to).supportsInterface(0xabcdef), "Wrong interface");

This works correctly if to is a contract address that implements ERC165. But when to is an EOA or a contract that doesn't implements ERC165, the statement will revert without any revert message. It seems like supportsInterface might have been "undefined" and hence the error. I might not have done the check safely and correctly since to really can be any address.

How should I do a check for the interface in a safe and more graceful way?

1 Answer 1


A way is to isContract to detect EOA and then use try/catch for contracts

require(isContract(to), "Not a contract");

try IERC165(to).supportsInterface(0xabcdef) returns (bool supported) {
    // Contracts support ERC-165
    require(supported, "Unsupported interface");
} catch (bytes memory /*lowLevelData*/) {
    // Contracts doesn't support ERC-165
    require(supported, "Unsupported ERC-165");

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.