Skip to content

fix: don't resolve swap-status assets by token ticker - #2367

Open
ChinmayGopal931 wants to merge 1 commit into
zodl-inc:mainfrom
ChinmayGopal931:fix/swap-status-asset-id-resolution
Open

fix: don't resolve swap-status assets by token ticker#2367
ChinmayGopal931 wants to merge 1 commit into
zodl-inc:mainfrom
ChinmayGopal931:fix/swap-status-asset-id-resolution

Conversation

@ChinmayGopal931

@ChinmayGopal931 ChinmayGopal931 commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

checkSwapStatus maps the asset ids in the status response back to the SwapAsset the app holds. When an id didn't match a catalog id exactly it fell back to reading the second colon-segment as a token ticker and matching on that. That segment is the chain, so the fallback could match a token on the wrong chain, and it accepted ids from any namespace because it never checked the prefix.

Replaced with an explicit map from the one id 1Click is known to route through back to the id the app requested, 1cs_v1:btc:native:coin to nep141:btc.omft.near. Anything else falls through to the existing AssetNotFoundException.

What the live API actually does

  • /v0/quote substitutes the routing asset in its echo: request nep141:btc.omft.near, get back 1cs_v1:btc:native:coin. Happens on both the origin and the destination side.
  • /v0/status echoes the ids the client sent, unchanged. Confirmed both ways: send nep141:btc.omft.near and status returns it verbatim; send 1cs_v1:btc:native:coin and status returns that.
  • The two endpoints serve the same signed quote, identical signature and timestamp, with different ids. The substitution is in /v0/quote's response, not in the stored quote.
  • Sweeping all 28 curated assets, BTC is the only one 1Click substitutes.

So on today's API this path always hits the exact match, and neither the old fallback nor the new map runs. The map is a guard for status starting to echo the routed id, which is the failure 930776d was written for.

Why only the echoed id is mapped

/v0/tokens lists both bitcoin ids as separate assets, BTC (nep141:btc.omft.near) and BTC(OMNI) (1cs_v1:btc:native:coin). getSupportedTokensForStatus runs against the uncurated list, so both are loaded.

Mapping catalog ids as well would give the two entries the same id and leave find picking by list position, which lands on the right one today only because BTC sits earlier in the catalog. checkSwapStatusDoesNotResolveARoutedIdToTheCatalogEntryCarryingIt covers that and fails if the mapping is applied to both sides.

Possible follow-up

SwapRepository.checkSwapStatus already knows the origin and destination from swapMetadata, and calls requireMatchingAsset against them one line after the data source returns. Resolving the assets from that metadata would drop this lookup entirely and stop the status path depending on how 1Click serializes ids. Left out here to keep the change small.

checkSwapStatus maps the asset ids in the status response back to the SwapAsset
the app holds. When an id did not match a catalog id exactly it fell back to
reading the second colon-segment as a token ticker and matching on that. That
segment is the chain, so the fallback could match a token on the wrong chain,
and it accepted ids from any namespace because it never checked the prefix.

Replace it with an explicit map from the one id 1Click is known to route
through back to the id the app requested, 1cs_v1:btc:native:coin to
nep141:btc.omft.near. Anything else falls through to AssetNotFoundException.

Checked against the live API: /v0/quote substitutes the routing asset in its
echo, on both the origin and destination side, but /v0/status echoes the ids
the client sent unchanged. Verified in both directions against the same signed
quote, which the two endpoints return with identical signature and timestamp
but different ids. Across the 28 curated assets BTC is the only substitution.
This path therefore always hits the exact match today; the map guards the case
930776d was written for.

Only the echoed id is mapped, never a catalog id. /v0/tokens lists both bitcoin
ids as separate assets, BTC and BTC(OMNI), and the status lookup runs against
the uncurated list, so mapping catalog ids too would give two entries the same
id and leave the lookup resolving by list position.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@ChinmayGopal931
ChinmayGopal931 force-pushed the fix/swap-status-asset-id-resolution branch from e78c2eb to cb4e508 Compare July 24, 2026 19:08
@ChinmayGopal931 ChinmayGopal931 changed the title fix: swap status can resolve a normalised asset ID to the wrong token fix: don't resolve swap-status assets by token ticker Jul 24, 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.

1 participant