Skip to content

fix(bsc): port transfer validation from base class into verifyTssTransaction - #9403

Draft
bitgo-ai-agent-dev[bot] wants to merge 3 commits into
masterfrom
wci-1169-bsc-remove-weak-verifytsstransaction
Draft

fix(bsc): port transfer validation from base class into verifyTssTransaction#9403
bitgo-ai-agent-dev[bot] wants to merge 3 commits into
masterfrom
wci-1169-bsc-remove-weak-verifytsstransaction

Conversation

@bitgo-ai-agent-dev

@bitgo-ai-agent-dev bitgo-ai-agent-dev Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

What

  • Replace the unconditional-return-true stub verifyTssTransaction in Bsc (modules/sdk-coin-bsc/src/bsc.ts) and BscToken (modules/sdk-coin-bsc/src/bscToken.ts) with the same 'transfer' calldata validation AbstractEthLikeNewCoins already performs:
    • Native BNB (data === '0x'): verifies destination address and amount match the declared recipient
    • BEP-20 transfer() (0xa9059cbb): decodes ABI calldata, verifies recipient address and token amount, including the WalletConnect recipients[0].data fallback
  • The shallow presence guards (missing txParams, missing params, hop+batch conflict) are retained, plus the missing txPrebuild.consolidateId check from the base class
  • Add four regression tests: native BNB matching/mismatched, BEP-20 matching/mismatched

Why

  • The original stub was introduced in commit 3d294365bd (COIN-3222, May 2025) as a temporary bypass because getTransactionBuilder().from(txHex).build() was crashing for BSC at the time. It was never reverted, leaving BSC without any txHex-level validation for over a year.
  • A compromised BitGo server could construct txParams that pass the shallow checks regardless of the actual txHex contents — there was no comparison between what was being signed and what the user intended.
  • The COIN-3222 decoding issue is confirmed resolved; this brings BSC to parity with ETH/Polygon/etc. on the 'transfer' path.
  • Finding: Trail of Bits audit TOB-BITGOEDMPC-3, tracked as WCI-1102WCI-1169.

Test plan

  • yarn run unit-test --scope @bitgo/sdk-coin-bsc — all existing tests pass, 4 new verifyTssTransaction tests pass
  • Native BNB with matching recipient → passes
  • Native BNB with mismatched recipient → throws TxIntentMismatchRecipientError
  • BEP-20 token transfer with matching calldata recipient → passes
  • BEP-20 token transfer with mismatched calldata recipient → throws TxIntentMismatchRecipientError

Ticket: WCI-1169

Remove the stub verifyTssTransaction overrides from Bsc and BscToken
that unconditionally returned true after only shallow presence checks.
Both classes now inherit AbstractEthLikeNewCoins.verifyTssTransaction,
which decodes txHex and validates native-BNB and BEP-20 transfers
against the declared recipients.

The original override was added in commit 3d29436 (COIN-3222,
May 2025) to unblock a txHex-decoding crash in the transaction
builder. That issue is no longer present, so the bypass can be
removed.

Add regression tests confirming:
- Native BNB TSS transfer with matching recipient passes
- Native BNB TSS transfer with mismatched recipient throws
- BEP-20 TSS token transfer with matching calldata recipient passes
- BEP-20 TSS token transfer with mismatched calldata recipient throws

Ticket: WCI-1169
Session-Id: 4ade7ff7-085e-476d-b280-f4d3dd01c105
Task-Id: 9e3fa483-2a00-47db-aa04-c64b6f003a77
@linear-code

linear-code Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

WCI-1169

@ralph-bitgo
ralph-bitgo Bot force-pushed the wci-1169-bsc-remove-weak-verifytsstransaction branch from a180e39 to b505c8b Compare August 3, 2026 10:24
@bitgo-ai-agent-dev
bitgo-ai-agent-dev Bot force-pushed the wci-1169-bsc-remove-weak-verifytsstransaction branch from b505c8b to b968966 Compare August 3, 2026 10:24
…saction

Replace the unconditional-return-true stub in Bsc and BscToken with the
same 'transfer' calldata validation that AbstractEthLikeNewCoins already
performs:
- native BNB (data === '0x'): verifies destination address and amount
  match the declared recipient
- BEP-20 transfer() (0xa9059cbb): decodes ABI calldata, verifies
  recipient address and token amount, including the WalletConnect
  recipients[0].data fallback

The original stub was introduced in commit 3d29436 (COIN-3222,
May 2025) to unblock a txHex-decoding crash in the transaction
builder. That issue is resolved; this brings BSC to parity with ETH
and other AbstractEthLikeNewCoins coins without removing the override.

The shallow presence guards (missing txParams, missing params,
hop+batch conflict) are retained from the original override, with the
addition of the missing txPrebuild.consolidateId check that the base
class also performs.

Add regression tests confirming:
- Native BNB TSS transfer with matching recipient passes
- Native BNB TSS transfer with mismatched recipient throws
- BEP-20 TSS token transfer with matching calldata recipient passes
- BEP-20 TSS token transfer with mismatched calldata recipient throws

Ticket: WCI-1169
Session-Id: 4ade7ff7-085e-476d-b280-f4d3dd01c105
Task-Id: 9e3fa483-2a00-47db-aa04-c64b6f003a77
@ralph-bitgo
ralph-bitgo Bot force-pushed the wci-1169-bsc-remove-weak-verifytsstransaction branch from 2e6ca82 to 98afd5e Compare August 3, 2026 11:11
@bitgo-ai-agent-dev bitgo-ai-agent-dev Bot changed the title fix(bsc): remove weak verifyTssTransaction override, inherit base class fix(bsc): port transfer validation from base class into verifyTssTransaction Aug 3, 2026
Replace the ethereumjs-util addHexPrefix import (not in sdk-coin-bsc
deps) with an inline helper. ethereumjs-util is a transitive dep of
abstract-eth, not a direct dep of sdk-coin-bsc, so relying on it was
fragile.

Add two tests for the WalletConnect recipients[0].data flow in
verifyTssTransaction:
- BEP-20 with matching recipients[0].data passes
- BEP-20 with tampered txHex calldata but correct recipients[0].data
  throws (tampered-recipient rejection)

Ticket: WCI-1169
Session-Id: 4ade7ff7-085e-476d-b280-f4d3dd01c105
Task-Id: 9e3fa483-2a00-47db-aa04-c64b6f003a77
@bitgo-ai-agent-dev
bitgo-ai-agent-dev Bot force-pushed the wci-1169-bsc-remove-weak-verifytsstransaction branch from 652bec2 to 6c6f12a Compare August 3, 2026 11:14
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