Skip to content

Commit

Permalink
[detectTokens] Apply and refactor fixes for detected tokens being add…
Browse files Browse the repository at this point in the history
…ed to wrong network, and detection using `chainId` keyed states

- See MetaMask/metamask-extension#22814
- See #3914
  • Loading branch information
MajorLift committed Feb 20, 2024
1 parent 53525f8 commit c5768ea
Showing 1 changed file with 32 additions and 32 deletions.
64 changes: 32 additions & 32 deletions packages/assets-controllers/src/TokenDetectionController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@ import type {
ControllerStateChangeEvent,
} from '@metamask/base-controller';
import contractMap from '@metamask/contract-metadata';
import {
ChainId,
safelyExecute,
toChecksumHexAddress,
} from '@metamask/controller-utils';
import { ChainId, safelyExecute } from '@metamask/controller-utils';
import type {
KeyringControllerGetStateAction,
KeyringControllerLockEvent,
Expand Down Expand Up @@ -48,13 +44,23 @@ import type {
const DEFAULT_INTERVAL = 180000;

/**
* Finds a case insensitive match in an array of strings
* @param source - An array of strings to search.
* @param target - The target string to search for.
* @returns The first match that is found.
* Compare 2 given strings and return boolean
* eg: "foo" and "FOO" => true
* eg: "foo" and "bar" => false
* eg: "foo" and 123 => false
*
* @param value1 - first string to compare
* @param value2 - first string to compare
* @returns true if 2 strings are identical when they are lowercase
*/
function findCaseInsensitiveMatch(source: string[], target: string) {
return source.find((e: string) => e.toLowerCase() === target.toLowerCase());
export function isEqualCaseInsensitive(
value1: string,
value2: string,
): boolean {
if (typeof value1 !== 'string' || typeof value2 !== 'string') {
return false;
}
return value1.toLowerCase() === value2.toLowerCase();
}

type LegacyToken = Omit<
Expand Down Expand Up @@ -490,35 +496,29 @@ export class TokenDetectionController extends StaticIntervalPollingController<
);
const tokenList =
tokensChainsCache[chainIdAgainstWhichToDetect]?.data ?? {};

const tokenListUsed = isTokenDetectionInactiveInMainnet
? STATIC_MAINNET_TOKEN_LIST
: tokenList;

const { allTokens, allDetectedTokens, allIgnoredTokens } =
this.messagingSystem.call('TokensController:getState');
const tokens =
allTokens[chainIdAgainstWhichToDetect]?.[addressAgainstWhichToDetect] ??
[];
const detectedTokens =
allDetectedTokens[chainIdAgainstWhichToDetect]?.[
addressAgainstWhichToDetect
] ?? [];
const ignoredTokens =
allIgnoredTokens[chainIdAgainstWhichToDetect]?.[
addressAgainstWhichToDetect
] ?? [];

const [tokensAddresses, detectedTokensAddresses, ignoredTokensAddreses] = [
allTokens,
allDetectedTokens,
allIgnoredTokens,
].map((tokens) =>
(
tokens[chainIdAgainstWhichToDetect]?.[addressAgainstWhichToDetect] ?? []
).map((value) => (typeof value === 'string' ? value : value.address)),
);
const tokensToDetect: string[] = [];
for (const tokenAddress of Object.keys(tokenListUsed)) {
for (const tokenAddress of Object.keys(tokenList)) {
if (
!findCaseInsensitiveMatch(
tokens.map(({ address }) => address),
tokenAddress,
) &&
!findCaseInsensitiveMatch(
detectedTokens.map(({ address }) => address),
tokenAddress,
[tokensAddresses, detectedTokensAddresses, ignoredTokensAddreses].every(
(addresses) =>
!addresses.find((address) =>
isEqualCaseInsensitive(address, tokenAddress),
),
)
) {
tokensToDetect.push(tokenAddress);
Expand Down

0 comments on commit c5768ea

Please sign in to comment.