Skip to content

fix: verify classic tokens by code and issuer, not issuer alone - #1024

Closed
JakeUrban wants to merge 1 commit into
mainfrom
fix/verified-asset-code-issuer-match
Closed

JakeUrban wants to merge 1 commit into
mainfrom
fix/verified-asset-code-issuer-match

Conversation

@JakeUrban

Copy link
Copy Markdown
Contributor

What

The "Verified" check for classic tokens now uses the token code and the issuer together. Before this change, it used only the issuer.

  • New file src/helpers/verifiedTokenIds.ts with two functions:
    • buildVerifiedTokenIds makes the set of IDs from the verified token lists: the contract ID of each entry, and the CODE:issuer pair of each entry.
    • isTokenInVerifiedIds returns true if the token's issuer is a listed contract ID, or if the token's CODE:issuer pair is in the set.
  • splitVerifiedTokens (Add Token search and Swap search) uses these functions.
  • computeTrendingIntersection (Swap popular tokens) uses these functions.
  • Code comparison is case-sensitive. USDE and USDe are different tokens. The address comparison is still case-insensitive, as before.
  • Contract tokens still match by contract ID. The native token is still verified.

Why

When you search for "usde", both USDE and USDe from the issuer GDJ5BNU5NN6NQ54D7OX6NQTUYNBZ42CAT33QGM5BIQ2QIYADAC5ICH47 show as verified. The Soroswap list contains USDE, SUSDE and ENA from this issuer. It does not contain USDe. USDe showed as verified only because its issuer is on the list.

With the old rule, any token code from an issuer on a list shows as verified. For example, a listed issuer can issue a new token with the code USDC, and the app shows it as verified. The extension has the same problem and gets the same fix in stellar/freighter#3041.

Known limitations

A verified token list entry must have a code for its classic token to match. An entry with an issuer and no code does not verify any token now. Entries in the current lists all have a code.

Screenshots / video

No screenshots. Expected result for the search "usde":

Before After
Verified: USDE, USDe Verified: USDE. USDe moves to the unverified section.

Checklist

PR structure

  • This PR does not mix refactoring changes with feature changes (break it down into smaller PRs if not).
  • This PR has reasonably narrow scope (break it down into smaller PRs if not).
  • This PR includes relevant before and after screenshots/videos highlighting these changes.
  • I took the time to review my own PR.

Testing

  • These changes have been tested and confirmed to work as intended on Android.
  • These changes have been tested and confirmed to work as intended on iOS.
  • These changes have been tested and confirmed to work as intended on small iOS screens.
  • These changes have been tested and confirmed to work as intended on small Android screens.
  • I have tried to break these changes while extensively testing them.
  • This PR adds tests for the new functionality or fixes.

Release

  • This is not a breaking change.
  • This PR updates existing JSDocs when applicable.
  • This PR adds JSDocs to new functionalities.
  • I've checked with the product team if we should add metrics to these changes.
  • I've shared relevant before and after screenshots/videos highlighting these changes with the design team and they've approved the changes.

Tests: new and updated tests in splitVerifiedTokens.test.ts and computeTrendingIntersection.test.ts. The full Jest suite passes. ESLint, Prettier and tsc --noEmit pass. The change was not tested on a device.


Generated by Claude Code

An asset was shown as verified when any asset list entry shared its
issuer, without checking the asset code. So every code an issuer
minted was verified when the list named only one of them (for example
USDe from the issuer of the listed USDE).

Classic assets now match a list entry only when both code and issuer
match. Contract tokens still match by contract ID.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014B2zysccigTczhF1iiZNuu
@JakeUrban JakeUrban closed this Oct 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants