diff --git a/README.md b/README.md
index dd58982..9b9733f 100644
--- a/README.md
+++ b/README.md
@@ -1020,7 +1020,7 @@ on the approval screen, the amount on the wait, success and error screens, the
transaction history and the transaction detail screen, and the refusal of a fee
above 1 ETH. A chain id that names no network reads `ETH`. Wherever this
document shows ETH as the label of a native balance, value or fee, in a "Native
-ETH transfer" type line, in the contract-recipient warning or in that refusal,
+ETH transfer" type line, in the two recipient warnings or in that refusal,
Sepolia shows `SepoliaETH`. The swap lines keep `ETH`, the router's own name for
the native currency, and the ETH/USD price line, shown on mainnet only, keeps
its fixed wording.
@@ -1730,8 +1730,10 @@ view would leave a wallet one click from deletion.
reserved either way
- Warnings: inline warnings from the local checks (scam address, self-send)
plus four reserved warning boxes made visible by the async checks —
- recipient with no transaction history, recipient is a contract, burn
- address, and an Etherscan phishing/scam label
+ recipient that has never sent a transaction and holds no ETH, recipient is
+ a contract, burn address, and an Etherscan phishing/scam label. An address
+ that has received ETH but never sent a transaction still holds that ETH,
+ so it gets no warning
- Errors (insufficient balance), plus three reserved error boxes — the
amount plus the fee exceeds the balance (ETH transfers), not enough ETH to
pay the fee for the transfer (ERC-20 transfers), and the fee could not be
diff --git a/src/popup/index.html b/src/popup/index.html
index a433783..3441682 100644
--- a/src/popup/index.html
+++ b/src/popup/index.html
@@ -634,17 +634,12 @@
-
-
- WARNING: The recipient address has ZERO transaction
- history. This may indicate a fresh or unused address.
- Double-check the address before sending.
-
-
-
+
+
{
+ throw new Error("tests must not perform network requests");
+});
+
+const RECIPIENT = "0x" + "b".repeat(40);
+
+// The warning types getFullWarnings() returns for RECIPIENT when the node
+// reports it as a regular address with `txCount` sent transactions and a
+// balance of `balance` wei.
+async function warningTypes(txCount, balance) {
+ const provider = {
+ getCode: async () => "0x",
+ getTransactionCount: async () => txCount,
+ getBalance: async () => balance,
+ };
+ const warnings = await getFullWarnings(RECIPIENT, provider);
+ return warnings.map((w) => w.type);
+}
+
+test("a recipient that has received 0.5 ETH and never sent a transaction gets no warning", async () => {
+ expect(await warningTypes(0, 500000000000000000n)).toEqual([]);
+});
+
+test("a recipient that has never sent a transaction and holds no ETH gets the warning", async () => {
+ expect(await warningTypes(0, 0n)).toEqual(["new-address"]);
+});
diff --git a/tests/nativeCurrency.test.js b/tests/nativeCurrency.test.js
index 8bd8bb7..a311312 100644
--- a/tests/nativeCurrency.test.js
+++ b/tests/nativeCurrency.test.js
@@ -267,6 +267,13 @@ describe.each([
);
});
+ test("the warning for a recipient that has never sent a transaction", async () => {
+ await confirmSend("0.1");
+ expect(text("confirm-recipient-warning")).toContain(
+ "has never sent a transaction and holds no " + symbol + ".",
+ );
+ });
+
// A token reports whatever symbol it likes. One reporting the label the
// wallet shows its native token under, on this network or any other, is
// a fake, exactly as one reporting `ETH` always was.
diff --git a/tests/rpcErrorLog.test.js b/tests/rpcErrorLog.test.js
index f06284a..3831698 100644
--- a/tests/rpcErrorLog.test.js
+++ b/tests/rpcErrorLog.test.js
@@ -74,7 +74,7 @@ test("ethers puts the URL in the error message, not in the short message", async
test("the recipient checks before a send", async () => {
await getFullWarnings(ADDRESS, getProvider(RPC_URL, "mainnet"));
expectFailureLoggedWithoutKey("contract check failed");
- expectFailureLoggedWithoutKey("tx count check failed");
+ expectFailureLoggedWithoutKey("tx count or balance check failed");
});
test("the ENS reverse lookup", async () => {