The balance list gave a tracked token a zero row while "Show tracked tokens with zero balance" was on, even when the spoof rule refuses the token. balanceLinesForAddress() now asks isSpoofedSymbol() before it adds that row. AddToken and SettingsAddToken now refuse such a token after the contract lookup, with a flash message that says why. The bundled-list buttons on SettingsAddToken need no check, because the rule never refuses a bundled token. The README and docs/README.md now say that the balance list drops such a token whatever the settings. Model: opus-5-5
93 lines
2.9 KiB
JavaScript
93 lines
2.9 KiB
JavaScript
// A token that the spoof rule refuses never shows in the balance list, even
|
|
// tracked at zero balance with "Show tracked tokens with zero balance" on, and
|
|
// the two add-token screens refuse to track one
|
|
// (https://git.eeqj.de/sneak/AutistMask/issues/705). Driven through the real
|
|
// popup over a stored profile.
|
|
|
|
const {
|
|
bootPopup,
|
|
cleanupPopup,
|
|
unversionedValidProfile,
|
|
TOKEN_ADDRESS,
|
|
} = require("./support/popupBoot");
|
|
|
|
// Claims the symbol of the bundled USDT from another contract.
|
|
const FAKE_USDT = {
|
|
address: TOKEN_ADDRESS,
|
|
symbol: "USDT",
|
|
decimals: 6,
|
|
name: "Tether USD",
|
|
};
|
|
// A symbol the bundled list does not have, so the spoof rule passes it.
|
|
const TEST_TOKEN = {
|
|
address: "0xBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
|
|
symbol: "TST",
|
|
decimals: 18,
|
|
name: "Test Token",
|
|
};
|
|
const REFUSED_FLASH =
|
|
"This is a fake token impersonating a known symbol, so it was not added.";
|
|
|
|
afterEach(() => {
|
|
cleanupPopup();
|
|
});
|
|
|
|
test("a fake token tracked at zero balance is not listed while zero balances are shown", async () => {
|
|
const boot = await bootPopup(
|
|
unversionedValidProfile({
|
|
currentView: "address",
|
|
selectedWallet: 0,
|
|
selectedAddress: 0,
|
|
trackedTokens: [FAKE_USDT, TEST_TOKEN],
|
|
showZeroBalanceTokens: true,
|
|
}),
|
|
);
|
|
const rows = boot.node("address-balances").innerHTML;
|
|
expect(rows).toContain(`data-token="${TEST_TOKEN.address.toLowerCase()}"`);
|
|
expect(rows).not.toContain(
|
|
`data-token="${FAKE_USDT.address.toLowerCase()}"`,
|
|
);
|
|
});
|
|
|
|
// Each screen is opened from AddressDetail by the buttons named, in order.
|
|
describe.each([
|
|
[
|
|
"AddToken",
|
|
["btn-add-token"],
|
|
"add-token",
|
|
"add-token-address",
|
|
"btn-add-token-confirm",
|
|
],
|
|
[
|
|
"SettingsAddToken",
|
|
["btn-settings", "btn-settings-add-token"],
|
|
"settings-addtoken",
|
|
"settings-addtoken-address",
|
|
"btn-settings-addtoken-manual",
|
|
],
|
|
])("%s", (_, opening, view, field, button) => {
|
|
test("refuses a fake token by contract address", async () => {
|
|
const boot = await bootPopup(
|
|
unversionedValidProfile({
|
|
currentView: "address",
|
|
selectedWallet: 0,
|
|
selectedAddress: 0,
|
|
}),
|
|
);
|
|
for (const id of opening) await boot.click(id);
|
|
expect(boot.visibleViews()).toEqual([view]);
|
|
const { lookupTokenInfo } = require("../src/shared/balances");
|
|
lookupTokenInfo.mockResolvedValueOnce({
|
|
symbol: FAKE_USDT.symbol,
|
|
decimals: FAKE_USDT.decimals,
|
|
name: FAKE_USDT.name,
|
|
});
|
|
boot.node(field).value = FAKE_USDT.address;
|
|
|
|
await boot.click(button);
|
|
expect(boot.text("flash-msg")).toBe(REFUSED_FLASH);
|
|
expect(boot.visibleViews()).toEqual([view]);
|
|
expect(boot.storage.read("autistmask").trackedTokens).toEqual([]);
|
|
});
|
|
});
|