fix: a shared ticker no longer hides one of its two real tokens (closes #276)
All checks were successful
check / check (push) Successful in 33s

Seven bundled tokens were filtered as spoofs at their own address, so a user
holding FRAX, TON, REUSD, EURE, MSUSD, MUSD or JPYC could not see or spend the
one the wallet happened not to pick.

The known-symbol table is derived from the bundled token list, first-wins in
market-cap order, so a symbol that appears twice silently condemned its second
contract. Both are real tokens from the same fetch and neither is stale --
three pairs are one issuer's old and new contract, four are unrelated issuers
sharing a ticker. Picking a winner would have been guessing, and dropping the
ambiguous symbols would have ended spoof filtering for those tickers entirely.

The table now maps a symbol to the set of addresses that legitimately bear it.
A contract outside the set is still a spoof, so the check is not weakened: a
third contract bearing any of the seven shared tickers is refused, and that is
tested. The filter decides what is fake, not what is worth holding, so a legacy
contract stays in the set -- it still holds real balances.

A test walks the whole bundled list asserting no token is filtered at its own
address, which is the guard whose absence let this ship.
This commit was merged in pull request #277.
This commit is contained in:
2026-08-12 13:31:55 +02:00
parent d5595c0151
commit c755a5e944
5 changed files with 180 additions and 14 deletions

View File

@@ -207,8 +207,8 @@ describe("token list assumptions the fixtures rely on", () => {
});
test("USDC and WETH map to their genuine lowercased contracts", () => {
expect(KNOWN_SYMBOLS.get("USDC")).toBe(USDC_CONTRACT);
expect(KNOWN_SYMBOLS.get("WETH")).toBe(WETH_CONTRACT);
expect([...KNOWN_SYMBOLS.get("USDC")]).toEqual([USDC_CONTRACT]);
expect([...KNOWN_SYMBOLS.get("WETH")]).toEqual([WETH_CONTRACT]);
});
test("the spam fixture symbol is not in the known token list", () => {