From 501d50b68eb6538e4049e3178195b3286cda861f Mon Sep 17 00:00:00 2001 From: agent Date: Tue, 23 Jun 2026 21:29:35 +0000 Subject: [PATCH] fix(statics): route Polygon ERC-20 send-many via ERC-20 batcher Adds CoinFeature.ERC20_BULK_TRANSACTION to POLYGON_TOKEN_FEATURES, POLYGON_TOKEN_FEATURES_EXCLUDE_SINGAPORE, and POLYGON_TOKEN_FEATURES_WITH_FRANKFURT. Mirrors what is already wired up for BSC and the polygon coin-level features. Without this flag, send-many requests for Polygon ERC-20 tokens (e.g. polygon:usdt) on mainnet fell through to the native batcher path, which encoded the call as sendMultiSigToken(batchContract, totalAmount) instead of batchTransferFrom([recipients], [amounts]). The total token amount was transferred to the batch contract as a single recipient, leaving funds stuck at the batcher contract and forcing customers to fall back to one transfer per recipient. Adds a coverage test asserting every polygon: / tpolygon: token exposes ERC20_BULK_TRANSACTION. Ticket: COINS-435 Session-Id: af73ff16-aaf1-4203-9eeb-2abe86d9474e Task-Id: 2cb7c5db-bf77-49d6-9356-e06df65e43fc --- modules/statics/src/coinFeatures.ts | 8 +++++++- modules/statics/test/unit/coins.ts | 10 ++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/modules/statics/src/coinFeatures.ts b/modules/statics/src/coinFeatures.ts index b5c9fe0e84..b09ac434e8 100644 --- a/modules/statics/src/coinFeatures.ts +++ b/modules/statics/src/coinFeatures.ts @@ -167,6 +167,7 @@ export const POLYGON_TOKEN_FEATURES_WITH_FRANKFURT = [ ...ACCOUNT_COIN_DEFAULT_FEATURES, CoinFeature.CUSTODY_BITGO_FRANKFURT, CoinFeature.BULK_TRANSACTION, + CoinFeature.ERC20_BULK_TRANSACTION, ]; export const CSPR_FEATURES = [ ...ACCOUNT_COIN_DEFAULT_FEATURES, @@ -262,10 +263,15 @@ export const POLYGON_FEATURES = [ CoinFeature.ERC20_BULK_TRANSACTION, ]; -export const POLYGON_TOKEN_FEATURES = [...ACCOUNT_COIN_DEFAULT_FEATURES, CoinFeature.BULK_TRANSACTION]; +export const POLYGON_TOKEN_FEATURES = [ + ...ACCOUNT_COIN_DEFAULT_FEATURES, + CoinFeature.BULK_TRANSACTION, + CoinFeature.ERC20_BULK_TRANSACTION, +]; export const POLYGON_TOKEN_FEATURES_EXCLUDE_SINGAPORE = [ ...ACCOUNT_COIN_DEFAULT_FEATURES_EXCLUDE_SINGAPORE, CoinFeature.BULK_TRANSACTION, + CoinFeature.ERC20_BULK_TRANSACTION, ]; export const EVM_ERC20_TOKEN_FEATURES_EXCLUDE_SINGAPORE = [ ...ACCOUNT_COIN_DEFAULT_FEATURES_EXCLUDE_SINGAPORE, diff --git a/modules/statics/test/unit/coins.ts b/modules/statics/test/unit/coins.ts index 644323c0a0..02ec4797bf 100644 --- a/modules/statics/test/unit/coins.ts +++ b/modules/statics/test/unit/coins.ts @@ -1232,6 +1232,16 @@ describe('ERC20 Bulk Transaction Feature', () => { coin.features.includes(CoinFeature.ERC20_BULK_TRANSACTION).should.eql(true); }); }); + + it('Polygon ERC-20 tokens should have ERC20_BULK_TRANSACTION feature', () => { + coins.forEach((coin) => { + if (coin.name.startsWith('polygon:') || coin.name.startsWith('tpolygon:')) { + coin.features + .includes(CoinFeature.ERC20_BULK_TRANSACTION) + .should.eql(true, `expected ${coin.name} to include ERC20_BULK_TRANSACTION`); + } + }); + }); }); describe('Custody Bulk Withdrawal Features', () => {