From e8c35ca5a59766fe1b278da8def2f8a9a8419b3b Mon Sep 17 00:00:00 2001 From: YamenMerhi Date: Wed, 28 Aug 2024 13:50:24 +0300 Subject: [PATCH] feat: add ERCTokenCallbacks Extension --- .../contracts/ERCTokenCallbacks.sol | 62 +++++++++++++++++++ .../tests/ERCTokenCallbacks.test.ts | 31 ++++++++++ 2 files changed, 93 insertions(+) create mode 100644 packages/lsp17-contracts/contracts/ERCTokenCallbacks.sol create mode 100644 packages/lsp17-contracts/tests/ERCTokenCallbacks.test.ts diff --git a/packages/lsp17-contracts/contracts/ERCTokenCallbacks.sol b/packages/lsp17-contracts/contracts/ERCTokenCallbacks.sol new file mode 100644 index 000000000..144718598 --- /dev/null +++ b/packages/lsp17-contracts/contracts/ERCTokenCallbacks.sol @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.4; + +import { + ERC721Holder, + IERC721Receiver +} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol"; + +import { + ERC1155Holder, + ERC1155Receiver +} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol"; + +import { + IERC777Recipient +} from "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol"; + +import { + LSP17Extension +} from "@lukso/lsp17contractextension-contracts/contracts/LSP17Extension.sol"; + +/** + * @dev LSP17 Extension that can be attached to a LSP17Extendable contract + * to allow it to receive ERC721 tokens via `safeTransferFrom`. + */ +// solhint-disable-next-line no-empty-blocks +contract ERCTokenCallbacks is + ERC721Holder, + ERC1155Holder, + IERC777Recipient, + LSP17Extension +{ + function tokensReceived( + address operator, + address from, + address to, + uint256 amount, + bytes calldata userData, + bytes calldata operatorData + ) external override { + // solhint-disable-previous-line no-empty-blocks + } + + /** + * @notice Implements ERC165 interface support for ERC1155TokenReceiver, ERC721TokenReceiver and IERC165. + * @param interfaceId Id of the interface. + * @return if the interface is supported. + */ + function supportsInterface( + bytes4 interfaceId + ) + public + view + virtual + override(ERC1155Receiver, LSP17Extension) + returns (bool) + { + return + interfaceId == type(IERC721Receiver).interfaceId || + super.supportsInterface(interfaceId); + } +} diff --git a/packages/lsp17-contracts/tests/ERCTokenCallbacks.test.ts b/packages/lsp17-contracts/tests/ERCTokenCallbacks.test.ts new file mode 100644 index 000000000..252af5c5e --- /dev/null +++ b/packages/lsp17-contracts/tests/ERCTokenCallbacks.test.ts @@ -0,0 +1,31 @@ +import { expect } from 'chai'; +import { ethers } from 'hardhat'; +import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; +import { ERCTokenCallbacks, ERCTokenCallbacks__factory } from '../types'; +import { INTERFACE_ID_LSP17Extension } from '../constants.ts'; + +describe('testing `ERCTokenCallbacks`', () => { + let context: { + tokenCallbacks: ERCTokenCallbacks; + owner: SignerWithAddress; + }; + + before(async () => { + const [owner] = await ethers.getSigners(); + const tokenCallbacks = await new ERCTokenCallbacks__factory(owner).deploy(); + + context = { + tokenCallbacks, + owner, + }; + }); + + describe('testing `supportsInterface`', () => { + it('should return true for supported interface IDs', async () => { + expect(await context.tokenCallbacks.supportsInterface(INTERFACE_ID_LSP17Extension)).to.be + .true; // LSP17Extension interface ID + expect(await context.tokenCallbacks.supportsInterface('0x01ffc9a7')).to.be.true; // ERC721Holder interface ID + expect(await context.tokenCallbacks.supportsInterface('0x4e2312e0')).to.be.true; // ERC1155Holder interface ID + }); + }); +});