From c2818b5675a3e818f238352e7ad638251656518c Mon Sep 17 00:00:00 2001 From: Andy Haynes Date: Tue, 1 Aug 2023 16:59:22 -0700 Subject: [PATCH 1/4] feat: support wildcards in ft blacklist --- .../frontend/src/hooks/useTokenBlacklist.js | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/packages/frontend/src/hooks/useTokenBlacklist.js b/packages/frontend/src/hooks/useTokenBlacklist.js index 259bc7dd4d..7f66e8e8d3 100644 --- a/packages/frontend/src/hooks/useTokenBlacklist.js +++ b/packages/frontend/src/hooks/useTokenBlacklist.js @@ -1,5 +1,26 @@ import { useMemo } from 'react'; +/** + * Determine whether a fungible token contract should be included given a token blacklist + * @param token {string} token contract name under consideration + * @param blacklist {string[]} list of blacklisted tokens; either the full name or a leading wildcard ('*') + * @returns {boolean} + */ +export function isTokenIncluded(tokenContract, blacklist) { + for (let blacklistedToken of blacklist) { + if (tokenContract === blacklistedToken) { + return false; + } + + // e.g. *.mallory.near would exclude a.mallory.near and b.mallory.near + if (blacklistedToken.startsWith('*') && tokenContract.endsWith(blacklistedToken.slice(1))) { + return false; + } + } + + return true; +} + export function useTokenBlacklist({ tokens }) { // TODO: make list dynamic, fetch from db const blacklistedTokens = [ @@ -12,7 +33,7 @@ export function useTokenBlacklist({ tokens }) { return tokens; } - return tokens.filter((token) => !blacklistedTokens.includes(token.contractName)); + return tokens.filter((token) => isTokenIncluded(token.contractName, blacklistedTokens)); }, [tokens]); return { blacklistedTokens, allowedTokens }; From 0ca552e42c94b9250a854faf682c7b1ea3687cd6 Mon Sep 17 00:00:00 2001 From: Andy Haynes Date: Tue, 1 Aug 2023 17:00:21 -0700 Subject: [PATCH 2/4] test: exclusion/wildcard logic --- .../frontend/test/token_blacklist.test.js | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 packages/frontend/test/token_blacklist.test.js diff --git a/packages/frontend/test/token_blacklist.test.js b/packages/frontend/test/token_blacklist.test.js new file mode 100644 index 0000000000..83c66ec2b5 --- /dev/null +++ b/packages/frontend/test/token_blacklist.test.js @@ -0,0 +1,22 @@ +const { isTokenIncluded } = require('../src/hooks/useTokenBlacklist'); + +describe('Fungible Token Blacklist', () => { + test('non-blacklisted tokens are included', () => { + expect(isTokenIncluded('test.near', ['not.near'])).toBe(true); + }); + + test('explicitly blacklisted tokens are excluded', () => { + expect(isTokenIncluded('test.near', ['test.near'])).toBe(false); + }); + + test('wildcard-prefixed blacklisted tokens are excluded', () => { + expect(isTokenIncluded('mal.test.near', ['*.test.near'])).toBe(false); + expect(isTokenIncluded('mal.test.near', ['xyz.near', '*.test.near'])).toBe(false); + }); + + test('non-matching tokens are included despite wildcard-prefixed blacklisted tokens', () => { + expect(isTokenIncluded('test.near', ['*.test.near'])).toBe(true); + expect(isTokenIncluded('xyz.near', ['*.test.near'])).toBe(true); + expect(isTokenIncluded('xyz.near', ['*.test.near', 'abc.near'])).toBe(true); + }); +}); From 3e6a8410f0ac39ac4b151ecf20d3f8bdeba9c63d Mon Sep 17 00:00:00 2001 From: Andy Haynes Date: Tue, 1 Aug 2023 17:00:51 -0700 Subject: [PATCH 3/4] feat: block source of spam tokens --- packages/frontend/src/hooks/useTokenBlacklist.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend/src/hooks/useTokenBlacklist.js b/packages/frontend/src/hooks/useTokenBlacklist.js index 7f66e8e8d3..2a1afc5f3a 100644 --- a/packages/frontend/src/hooks/useTokenBlacklist.js +++ b/packages/frontend/src/hooks/useTokenBlacklist.js @@ -25,7 +25,7 @@ export function useTokenBlacklist({ tokens }) { // TODO: make list dynamic, fetch from db const blacklistedTokens = [ 'kusama-airdrop.near', - 'youwon400neartoclaimyourgainwwwlotte.laboratory.jumpfinance.near', + '*.laboratory.jumpfinance.near', ]; const allowedTokens = useMemo(() => { From 5f6ffa0d552b96becf0a89b7119961743a0711cf Mon Sep 17 00:00:00 2001 From: Andy Haynes Date: Tue, 1 Aug 2023 17:02:36 -0700 Subject: [PATCH 4/4] docs: update name --- packages/frontend/src/hooks/useTokenBlacklist.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend/src/hooks/useTokenBlacklist.js b/packages/frontend/src/hooks/useTokenBlacklist.js index 2a1afc5f3a..2c3115bb10 100644 --- a/packages/frontend/src/hooks/useTokenBlacklist.js +++ b/packages/frontend/src/hooks/useTokenBlacklist.js @@ -2,7 +2,7 @@ import { useMemo } from 'react'; /** * Determine whether a fungible token contract should be included given a token blacklist - * @param token {string} token contract name under consideration + * @param tokenContract {string} token contract name under consideration * @param blacklist {string[]} list of blacklisted tokens; either the full name or a leading wildcard ('*') * @returns {boolean} */