Cast to IERC20Metadata when possible

I'm trying to do something like this:

        for (uint i = 0; i < reserves.length; i++) {
            address resTok = reserves[i];
            try IERC20Metadata(resTok).name() returns (string memory result) {
                // import "hardhat/console.sol";
                console.log("Reserve token name %d = %s", i, result);
            catch {
                console.log("Reserve token address %d = %s", i, resTok);

because sometimes reserves[i] cannot cast to IERC20Metadata so instead I just display the address.
Unfortunately, when the token cannot be casted to IERC20Metadata I'm getting:

Error: Transaction reverted: function returned an unexpected amount of data

Instead of the try/catch catching the error... Any idea how I can achieve the same piece of code in a different way that works? Thanks!

Hey Ekami,

Welcome to the community!

Before the try code, you can cast that address to ERC165 and pass in the bytes4 interface ID value of IERC20 to check whether that contract implements ERC-20. If it does, you know most of the time that it would implement ERC20Metadata and therefore have a name and symbol.

Check these out : EIP-165, OpenZep Introspection, ERC-165 Explained

It's giving me a reversion :frowning: , or maybe I'm not doing this the right way?

        for (uint i = 0; i < reserves.length; i++) {
            address resTok = reserves[i];

            bool hasSupport = IERC721(resTok).supportsInterface(type(IERC20Metadata).interfaceId);