fix(swap): flag symbol-squatter tokens impersonating native coins#354
Merged
Conversation
…ding
A token that self-declares a major chain's ticker/name (e.g. an Ethereum
ERC-20 whose symbol is "SOLANA") was rendered in the swap asset cards with
the native coin's logo + symbol, because the UI trusts the token's
self-declared symbol and the server-supplied icon. That lets scam/squatter
tokens impersonate real assets and confuses which asset a user is swapping.
- shared/symbolSquatter.ts: detect a non-native CAIP (parseCaip.isToken) that
wears a major chain identity AND is not the catalogued/known asset for that
CAIP (so legit L1-as-ERC20s like MATIC are not flagged). Fails open while the
asset catalog is still loading.
- shared/assetLookup.ts: isAssetMapReady() + isKnownAsset() catalog helpers.
- SwapDialog AssetSelector: on a squatter, drop the borrowed server icon (falls
back to CAIP/letter), red ring, and a clear 'not the native coin' warning.
- GreenCountUp: wrap prefix/suffix in whiteSpace:pre — inline-flex was
collapsing the leading space, gluing amount to symbol ('...291.85SOLANA').
Detection covered by shared/symbolSquatter.test.ts.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A token that self-declares a major chain's ticker/name — e.g. an Ethereum ERC-20 whose symbol is
SOLANA(real case:eip155:1/erc20:0x3d8063…, nameBarbieCrashBandicootRFK88) — rendered in the swap asset cards with the native coin's logo + symbol. The UI trusts the token's self-declaredsymboland the server-suppliedicon, so a squatter inherits real-asset branding and it becomes unclear which asset you're actually swapping.Fix
The CAIP namespace is the source of truth: the genuine native asset is always a
/slip44:CAIP, never a token.shared/symbolSquatter.ts—isSymbolSquatter(caip, symbol): true when a non-native CAIP (parseCaip().isToken) wears a major chain identity and is not the catalogued/known asset for that CAIP. The catalog check means legit L1s that live as ERC-20s (e.g. MATIC) are not flagged. Fails open while the asset catalog is still loading.shared/assetLookup.ts—isAssetMapReady()+isKnownAsset()helpers.SwapDialogAssetSelector(both PAY and RECEIVE cards) — on a squatter: drop the borrowed server icon (falls back to CAIP/letter bubble, so it can no longer show the native logo), red ring, and a clear "not the native coin — verify the contract" warning.GreenCountUp— wrap prefix/suffix inwhiteSpace:pre;inline-flexwas collapsing the leading space and gluing the amount to the symbol (…291.85SOLANA).Tests / verification
shared/symbolSquatter.test.tscovers the detection (scam ERC-20 → flagged; native slip44 → not; catalogued MATIC ERC-20 → not; loading → fails open). Passes.make vault).Notes: detection uses a curated set of commonly-squatted major-chain identities (marked
ponytail:for extension). Applied to the main swap asset cards; extending the same flag to the picker rows is a natural follow-up.