ERC165 Explained in Detail
ERC165 defines a standard way to ask a contract whether it supports an interface. The contract answers through supportsInterface(bytes4 interfaceId).
Interface IDs are built from function selectors. ERC721, ERC1155, receiver hooks, registries, and modular contracts often depend on these answers.
Smart contract example
function supportsInterface(bytes4 interfaceId) public view returns (bool);
The ERC165 interface ID itself is 0x01ffc9a7.
ERC165 in Auditing
ERC165 is not access control, but integrations often trust it before calling a contract. Wrong interface answers can break token transfers, registry checks, receiver hooks, and marketplace integrations.
Auditors verify that advertised interfaces match real behavior.
Red flags in code
-
supportsInterface(0xffffffff)returns true. -
The contract claims an interface it does not implement.
-
Inherited interfaces are missing from the override.
-
Proxy calls expose different interface support than direct implementation calls.
-
Interface checks revert or are too gas-heavy.
How to test or review it
-
Test
0x01ffc9a7,0xffffffff, expected IDs, and random unknown IDs. -
Test through the proxy address when the contract is upgradeable.
-
Confirm receiver hooks and token standards match their expected interface IDs.
-
Check that
super.supportsInterface(interfaceId)is used when inheritance requires it. -
Treat ERC165 as a compatibility signal, not proof that behavior is safe.