Skip to content

fix(tokens): split BTCB on BSC from WBTC entry (ACX-4980)#208

Open
droplet-rl wants to merge 1 commit into
masterfrom
ashwin/acx-4980-btcb-incorrect-decimals
Open

fix(tokens): split BTCB on BSC from WBTC entry (ACX-4980)#208
droplet-rl wants to merge 1 commit into
masterfrom
ashwin/acx-4980-btcb-incorrect-decimals

Conversation

@droplet-rl

Copy link
Copy Markdown

Summary

The BSC address listed under the WBTC entry in src/tokens.ts is 0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c, which is BTCB (Binance-Peg BTCB Token). BTCB on BSC has 18 decimals on-chain, but the WBTC entry declares decimals: 8. Any consumer that resolves this BSC address gets the wrong decimals and miscalculates amounts / price impact by ~10^10 — e.g. a USDC→BTCB swap was reporting a ~-9.8B swap impact.

This PR follows the existing USDC-BNB / USDT-BNB convention for BSC tokens with mismatched decimals:

  • Remove the BSC entry from WBTC.
  • Add a new WBTC-BNB entry with decimals: 18, l1TokenDecimals: 8, and both BSC + MAINNET addresses.
  • Add WBTC-BNB → WBTC to TOKEN_EQUIVALENCE_REMAPPING.

The misplaced address was originally introduced in #128 ("feat: add support for bnb") when BNB chain support was first added.

Test plan

  • yarn build succeeds, dist reflects the new entry.
  • yarn eslint and prettier --check src/tokens.ts pass.
  • Verify downstream consumers (relayer, indexer, quote-api) handle the new WBTC-BNB symbol via the equivalence remapping the same way they already handle USDC-BNB / USDT-BNB.
  • Confirm no in-flight code paths look up the BTCB address under the literal WBTC symbol — they should now resolve through WBTC-BNB.

Closes ACX-4980.

The BSC address listed under WBTC was BTCB (Binance-pegged BTC), which
has 18 decimals on BSC — not 8 like WBTC. Consumers resolving that
address picked up the WBTC entry's `decimals: 8` and miscalculated
amounts by ~10^10.

Mirror the existing `USDC-BNB` / `USDT-BNB` convention: drop the BSC
entry from WBTC and add a separate `WBTC-BNB` entry (decimals 18,
l1TokenDecimals 8) plus a `WBTC-BNB → WBTC` equivalence remapping.

Closes ACX-4980.
@linear

linear Bot commented Jun 16, 2026

Copy link
Copy Markdown

ACX-4980

@0xjorgen 0xjorgen self-requested a review June 23, 2026 10:04
Comment thread src/tokens.ts
decimals: 18,
addresses: {
[CHAIN_IDs.BSC]: "0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c",
[CHAIN_IDs.MAINNET]: "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@droplet-rl , why is mainnet included here?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mainnet address mirrors the existing USDC-BNB / USDT-BNB entries — each -BNB entry carries the canonical L1 (mainnet) token address alongside the BSC address.

It is the L1 reference that l1TokenDecimals: 8 and the new WBTC-BNB → WBTC equivalence remapping resolve against: the BSC BTCB token (18 decimals) maps back to canonical L1 WBTC (0x2260…C599, 8 decimals). Drop the mainnet address and there is no L1 token to remap to, so bridge/hub-pool routing that keys off the L1 token cannot resolve it.

The mainnet address being shared with the plain WBTC entry is intentional — it is exactly the "several mappings can share the same L1 token mapping" case the comment at the bottom of TOKEN_EQUIVALENCE_REMAPPING describes, which the remapping is there to handle (same as USDC/USDC-BNB, USDT/USDT-BNB).

@droplet-rl

Copy link
Copy Markdown
Author

Thanks for the review @0xjorgen. You had one inline question — why the WBTC-BNB entry includes a MAINNET address — which I've answered on the thread.

tl;dr: it mirrors the existing USDC-BNB / USDT-BNB convention. The mainnet (L1) address is the reference that l1TokenDecimals: 8 and the new WBTC-BNB → WBTC equivalence remapping resolve against, so the BSC BTCB token (18 decimals) maps back to canonical L1 WBTC (8 decimals). Sharing the mainnet address with the plain WBTC entry is intentional and is exactly the case the comment at the bottom of TOKEN_EQUIVALENCE_REMAPPING describes. No code change needed unless you'd prefer a different approach — happy to adjust.

@droplet-rl

Copy link
Copy Markdown
Author

🔎 View trace

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