Add anti-poisoning filters for token transfers and send view
Some checks failed
check / check (push) Has been cancelled
Some checks failed
check / check (push) Has been cancelled
Three layers of defense against address poisoning attacks: 1. Known symbol verification: tokens claiming a symbol from the hardcoded top-250 list (e.g. "ETH", "USDT") but from an unrecognized contract are identified as spoofs and always hidden. Their contract addresses are auto-added to the fraud blocklist. 2. Low-holder filtering: tokens with <1000 holders are hidden from both transaction history and the send token selector. Controlled by the "Hide tokens with fewer than 1,000 holders" setting. 3. Fraud contract blocklist: a persistent local list of detected fraud contract addresses. Transactions involving these contracts are hidden. Controlled by the "Hide transactions from detected fraud contracts" setting. Both settings default to on and can be disabled in Settings. Fetching and filtering are separated: fetchRecentTransactions returns raw data, filterTransactions is a pure function applying heuristics. Token holder counts are now passed through from the Blockscout API.
This commit is contained in:
@@ -8,9 +8,12 @@ const {
|
||||
formatAddressHtml,
|
||||
truncateMiddle,
|
||||
} = require("./helpers");
|
||||
const { state, currentAddress } = require("../../shared/state");
|
||||
const { state, currentAddress, saveState } = require("../../shared/state");
|
||||
const { formatUsd, getAddressValueUsd } = require("../../shared/prices");
|
||||
const { fetchRecentTransactions } = require("../../shared/transactions");
|
||||
const {
|
||||
fetchRecentTransactions,
|
||||
filterTransactions,
|
||||
} = require("../../shared/transactions");
|
||||
const { resolveEnsNames } = require("../../shared/ens");
|
||||
const { updateSendBalance, renderSendTokenSelect } = require("./send");
|
||||
const { log } = require("../../shared/log");
|
||||
@@ -84,7 +87,27 @@ let ensNameMap = new Map();
|
||||
|
||||
async function loadTransactions(address) {
|
||||
try {
|
||||
const txs = await fetchRecentTransactions(address, state.blockscoutUrl);
|
||||
const rawTxs = await fetchRecentTransactions(
|
||||
address,
|
||||
state.blockscoutUrl,
|
||||
);
|
||||
const result = filterTransactions(rawTxs, {
|
||||
hideLowHolderTokens: state.hideLowHolderTokens,
|
||||
hideFraudContracts: state.hideFraudContracts,
|
||||
fraudContracts: state.fraudContracts,
|
||||
});
|
||||
const txs = result.transactions;
|
||||
|
||||
// Persist any newly discovered fraud contracts
|
||||
if (result.newFraudContracts.length > 0) {
|
||||
for (const addr of result.newFraudContracts) {
|
||||
if (!state.fraudContracts.includes(addr)) {
|
||||
state.fraudContracts.push(addr);
|
||||
}
|
||||
}
|
||||
await saveState();
|
||||
}
|
||||
|
||||
loadedTxs = txs;
|
||||
|
||||
// Collect unique counterparty addresses for ENS resolution.
|
||||
|
||||
Reference in New Issue
Block a user