diff --git a/contracts/handler/DefaultCallbackHandler.sol b/contracts/handler/DefaultCallbackHandler.sol index a68f7ee91..61746509e 100644 --- a/contracts/handler/DefaultCallbackHandler.sol +++ b/contracts/handler/DefaultCallbackHandler.sol @@ -4,10 +4,11 @@ pragma solidity >=0.7.0 <0.9.0; import "../interfaces/ERC1155TokenReceiver.sol"; import "../interfaces/ERC721TokenReceiver.sol"; import "../interfaces/ERC777TokensRecipient.sol"; +import "../interfaces/IERC165.sol"; /// @title Default Callback Handler - returns true for known token callbacks /// @author Richard Meissner - -contract DefaultCallbackHandler is ERC1155TokenReceiver, ERC777TokensRecipient, ERC721TokenReceiver { +contract DefaultCallbackHandler is ERC1155TokenReceiver, ERC777TokensRecipient, ERC721TokenReceiver, IERC165 { string public constant NAME = "Default Callback Handler"; string public constant VERSION = "1.0.0"; @@ -48,4 +49,17 @@ contract DefaultCallbackHandler is ERC1155TokenReceiver, ERC777TokensRecipient, // We implement this for completeness, doesn't really have any value } + + function supportsInterface(bytes4 interfaceId) + virtual + override + external + view + returns (bool) + { + return interfaceId == type(ERC1155TokenReceiver).interfaceId + || interfaceId == type(ERC721TokenReceiver).interfaceId + || interfaceId == type(IERC165).interfaceId; + } + } \ No newline at end of file diff --git a/contracts/interfaces/IERC165.sol b/contracts/interfaces/IERC165.sol new file mode 100644 index 000000000..1c3d67331 --- /dev/null +++ b/contracts/interfaces/IERC165.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: LGPL-3.0-only +pragma solidity >=0.7.0 <0.9.0; + +/// @notice More details at https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/IERC165.sol +interface IERC165 { + /** + * @dev Returns true if this contract implements the interface defined by + * `interfaceId`. See the corresponding + * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] + * to learn more about how these ids are created. + * + * This function call must use less than 30 000 gas. + */ + function supportsInterface(bytes4 interfaceId) external view returns (bool); +} \ No newline at end of file diff --git a/test/handlers/DefaultCallbackHandler.spec.ts b/test/handlers/DefaultCallbackHandler.spec.ts index 4da2d0ab8..1b6af4453 100644 --- a/test/handlers/DefaultCallbackHandler.spec.ts +++ b/test/handlers/DefaultCallbackHandler.spec.ts @@ -10,6 +10,13 @@ describe("DefaultCallbackHandler", async () => { }); describe("ERC1155", async () => { + it('should supports ERC1155 interface', async () => { + const handler = await getDefaultCallbackHandler() + await expect( + await handler.callStatic.supportsInterface("0x4e2312e0") + ).to.be.eq(true) + }) + it('to handle onERC1155Received', async () => { const handler = await getDefaultCallbackHandler() await expect( @@ -26,6 +33,13 @@ describe("DefaultCallbackHandler", async () => { }) describe("ERC721", async () => { + it('should supports ERC721 interface', async () => { + const handler = await getDefaultCallbackHandler() + await expect( + await handler.callStatic.supportsInterface("0x150b7a02") + ).to.be.eq(true) + }) + it('to handle onERC721Received', async () => { const handler = await getDefaultCallbackHandler() await expect( @@ -40,4 +54,13 @@ describe("DefaultCallbackHandler", async () => { await handler.callStatic.tokensReceived(AddressZero, AddressZero, AddressZero, 0, "0x", "0x") }) }) + + describe("ERC165", async () => { + it('should not support random interface', async () => { + const handler = await getDefaultCallbackHandler() + await expect( + await handler.callStatic.supportsInterface("0xbaddad42") + ).to.be.eq(false) + }) + }) }) \ No newline at end of file