Check if a Contract Implements ERC1155 Receiver / Holder interface

Hi,

I have a minter contract that should send tokens to other contracts.

These receiving contracts should be verified and registered before the minter send any token.

That is, I need to ensure that the contract is capable of receiving Tokens ERC1155 even before the Minter contract sends.

I've been trying to implement staticcall, but I was unsuccessful. And it's not yet clear how to do this verification.

The receiver contract:

contract ContracReceiver is ERC1155Holder {

   constructor() {}

    function onERC1155Received(
        address,
        address,
        uint256 id,
        uint256,
        bytes memory
    ) public virtual override onlySupplier returns (bytes4) {
        _tokens[id] = true;
        return this.onERC1155Received.selector;
    }

    // Receive multiple ERC1155 tokens representing a cocoa batch
    function onERC1155BatchReceived(
        address,
        address,
        uint256[] memory ids,
        uint256[] memory,
        bytes memory
    ) public virtual override onlySupplier returns (bytes4) {
        for (uint256 i = 0; i < ids.length; i++) {
            _tokens[ids[i]] = true;
        }
        return this.onERC1155BatchReceived.selector;
    }

}

The verification in minter contract:

     /**
     * If the account is a contract, but does not implement the ERC1155Receiver interface,
     * the transfer will fail.
     */
    function _doSafeHolderAcceptanceCheck(address account) internal view {
        if (account.code.length > 0) {
            // Externall call to the contract to check if it accepts token transfers
            (bool success, bytes memory returnData) = account.staticcall(
                abi.encodeWithSignature(
                    "onERC1155Received(address,address,uint256,uint256,bytes)"
                )
            );

            // Check if the call was successful
            require(
                success,
                "Holder contract does not implement ERC1155Receiver interface"
            );

            // Check if the return value is the expected one
            require(
                abi.decode(returnData, (bytes4)) == 0xf23a6e61,
                "Holder contract does not implement ERC1155Receiver interface correctly"
            );
        }
    }

But I always receive

Holder contract does not implement ERC1155Receiver interface

Why ? static calls revert when state changes and your onERC1155Received and onERC1155BatchReceived change state.

ERC1155Holder implements ERC165, use supportsInterface instead

1 Like