Files
AutistMask/src/shared/symbolSpoof.js
clawbot 1f41a07df2
All checks were successful
check / check (push) Successful in 30s
fix: filter a fake ETH token from the balance list too (closes #235)
2026-08-12 11:10:38 +02:00

44 lines
1.9 KiB
JavaScript

// The known-symbol spoof rule, in one place.
//
// A token that borrows a known symbol from a contract that is not the one
// that symbol belongs to is a spoof, and the wallet hides it. Three surfaces
// ask that question — the transaction history, the Send token selector and
// the balance list — and they must answer it identically: a token the history
// calls fake while the balance list lists it as a holding is worse than
// either verdict alone, because the balance list is where the user forms
// their belief about what they own (issue #235).
//
// KNOWN_SYMBOLS maps a symbol to the lowercased contract address that may
// bear it, or to null. Null means the symbol belongs to the native asset,
// which has no contract at all, so no contract may bear it and every one
// that does is a spoof. "ETH" is the only such entry today; the rule is
// written so that a second one needs no change here or at any call site.
const { KNOWN_SYMBOLS } = require("./tokenList");
// Ethereum addresses are case-insensitive: EIP-55 mixed case is a checksum
// over the address, not part of its identity.
function normalizeAddress(addr) {
return (addr || "").toLowerCase();
}
// True when a token bearing `symbol` from contract `contractAddress` is
// impersonating a known symbol.
//
// An empty contract address is the native asset, which is never a spoof:
// this is what keeps the user's real ETH out of the rule, and it holds for
// any symbol that becomes null-mapped later, not just for ETH.
function isSpoofedSymbol(symbol, contractAddress) {
const contract = normalizeAddress(contractAddress);
if (!contract) return false;
const sym = (symbol || "").toUpperCase();
if (!KNOWN_SYMBOLS.has(sym)) return false;
const legit = KNOWN_SYMBOLS.get(sym);
if (legit === null) return true;
return contract !== normalizeAddress(legit);
}
module.exports = {
isSpoofedSymbol,
};