`require` in view/pure functions don't revert on public networks

There is known issue that require in view/pure functions don't revert on public networks.

See the following open issues:

require works as expected with Remix VM and ganache-cli.

Address return type

Where address is the return data type in a view function with a require the zero address is returned on revert.

Example is ERC721 ownerOf

function ownerOf(uint256 tokenId) public view returns (address) {
    address owner = _tokenOwner[tokenId];
    require(owner != address(0), "ERC721: owner query for nonexistent token");
    return owner;
}

uint256 return type

Where uint256 is the return type in a view function with a require, 3963877391197344453575983046348115674221700746820753546331534351508065746944 is returned on revert.

The hex value for this is 8C379A000000000000000000000000000000000000000000000000000000000 which is the function selector for function Error(string).

Example is ERC721 balanceOf:

function balanceOf(address owner) public view returns (uint256) {
    require(owner != address(0), "ERC721: balance query for the zero address");

    return _ownedTokensCount[owner].current();
}

Check

I have deployed an ERC721 token inheriting from OpenZeppelin Contracts ERC721 implementation. On Ropsten Etherscan: 0x7E2b9716726529ba01FE5CE3dF752d94298C0b49

Call balanceOf with the zero address 0x0000000000000000000000000000000000000000

Call ownerOf with a non-existent tokenId 0
ownerOf


Thanks to @Aniket-Engg https://github.com/OpenZeppelin/openzeppelin-contracts/issues/1870

5 Likes