From ca45aa6da6101f15fe9ef4c485e5d61a64f66f84 Mon Sep 17 00:00:00 2001 From: ricecodekhmer <151774852+ricecodekhmer@users.noreply.github.com> Date: Tue, 9 Apr 2024 01:50:10 +0100 Subject: [PATCH] fix(bridge-ui): fix ERC721 and ERC1155 detection in NFT bridge (#16680) --- .../src/libs/token/detectContractType.test.ts | 23 ++++--------------- .../src/libs/token/detectContractType.ts | 20 ++++++++-------- 2 files changed, 14 insertions(+), 29 deletions(-) diff --git a/packages/bridge-ui/src/libs/token/detectContractType.test.ts b/packages/bridge-ui/src/libs/token/detectContractType.test.ts index 7655a7d6c4..46d50e000c 100644 --- a/packages/bridge-ui/src/libs/token/detectContractType.test.ts +++ b/packages/bridge-ui/src/libs/token/detectContractType.test.ts @@ -13,20 +13,7 @@ describe('detectContractType', () => { // Given const contractAddress = zeroAddress; const chainId = 1; - vi.mocked(readContract).mockImplementationOnce(() => Promise.resolve()); - - // When - const result = await detectContractType(contractAddress, chainId); - - // Then - expect(result).toBe(TokenType.ERC721); - }); - - it('should return ERC721 for a valid ERC721 contract with invalid Token ID', async () => { - // Given - const contractAddress = zeroAddress; - const chainId = 1; - vi.mocked(readContract).mockImplementationOnce(() => Promise.reject(new Error('ERC721: invalid token ID'))); + vi.mocked(readContract).mockImplementationOnce(() => Promise.resolve(true)); // When const result = await detectContractType(contractAddress, chainId); @@ -40,8 +27,8 @@ describe('detectContractType', () => { const contractAddress = zeroAddress; const chainId = 1; vi.mocked(readContract) - .mockImplementationOnce(() => Promise.reject()) - .mockImplementationOnce(() => Promise.resolve()); + .mockImplementationOnce(() => Promise.reject(false)) + .mockImplementationOnce(() => Promise.resolve(true)); // When const result = await detectContractType(contractAddress, chainId); @@ -55,8 +42,8 @@ describe('detectContractType', () => { const contractAddress = zeroAddress; const chainId = 1; vi.mocked(readContract) - .mockImplementationOnce(() => Promise.reject()) - .mockImplementationOnce(() => Promise.reject()) + .mockImplementationOnce(() => Promise.reject(new Error())) + .mockImplementationOnce(() => Promise.reject(new Error())) .mockImplementationOnce(() => Promise.resolve()); // When diff --git a/packages/bridge-ui/src/libs/token/detectContractType.ts b/packages/bridge-ui/src/libs/token/detectContractType.ts index 99c96962e4..9a4cf06b86 100644 --- a/packages/bridge-ui/src/libs/token/detectContractType.ts +++ b/packages/bridge-ui/src/libs/token/detectContractType.ts @@ -13,31 +13,28 @@ const log = getLogger('detectContractType'); async function isERC721(address: Address, chainId: number): Promise { try { - await readContract(config, { + return await readContract(config, { address, abi: erc721Abi, - functionName: 'ownerOf', - args: [0n], + functionName: 'supportsInterface', + args: ['0x80ac58cd'], // Identifier for ERC-721 chainId, }); - return true; - } catch (err) { - // we expect this error to be thrown if the token is a ERC721 and the tokenId is invalid - return (err as Error)?.message?.includes('ERC721: invalid token ID') ?? false; + } catch { + return false; } } // return err instanceof ContractFunctionExecutionError && // err.cause.message.includes('ERC721: invalid token ID'); async function isERC1155(address: Address, chainId: number): Promise { try { - await readContract(config, { + return await readContract(config, { address, abi: erc1155Abi, - functionName: 'isApprovedForAll', - args: ['0x0000000000000000000000000000000000000000', '0x0000000000000000000000000000000000000000'], + functionName: 'supportsInterface', + args: ['0xd9b67a26'], // Identifier for ERC-1155 chainId, }); - return true; } catch { return false; } @@ -52,6 +49,7 @@ async function isERC20(address: Address, chainId: number): Promise { args: ['0x0000000000000000000000000000000000000000'], chainId, }); + return true; } catch { return false;