From f503760ace6f259deec3d0e466850cdab8436b53 Mon Sep 17 00:00:00 2001 From: Max Klenk Date: Fri, 25 Sep 2026 23:08:57 +0200 Subject: [PATCH] fix(coins): correct EIP-55 checksum of USDT0 on Rootstock --- .changeset/fix-usdt0-rootstock-checksum.md | 5 ++++ src/coins/coins.ts | 2 +- src/coins/coins.unit.spec.ts | 33 ++++++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 .changeset/fix-usdt0-rootstock-checksum.md create mode 100644 src/coins/coins.unit.spec.ts diff --git a/.changeset/fix-usdt0-rootstock-checksum.md b/.changeset/fix-usdt0-rootstock-checksum.md new file mode 100644 index 0000000..41cbf21 --- /dev/null +++ b/.changeset/fix-usdt0-rootstock-checksum.md @@ -0,0 +1,5 @@ +--- +"@lifi/data-types": patch +--- + +Fix the EIP-55 checksum of the USDT0 address on Rootstock, which was mis-cased and rejected by address lookups that compare verbatim. diff --git a/src/coins/coins.ts b/src/coins/coins.ts index 506c941..60c6fc9 100644 --- a/src/coins/coins.ts +++ b/src/coins/coins.ts @@ -3017,7 +3017,7 @@ export const basicCoins: BasicCoin[] = [ decimals: 6, }, [ChainId.RSK]: { - address: '0x779dED0C9e1022225F8e0630b35A9B54Be713736', + address: '0x779Ded0c9e1022225f8E0630b35a9b54bE713736', decimals: 6, }, [ChainId.ARB]: { diff --git a/src/coins/coins.unit.spec.ts b/src/coins/coins.unit.spec.ts new file mode 100644 index 0000000..c48bc0f --- /dev/null +++ b/src/coins/coins.unit.spec.ts @@ -0,0 +1,33 @@ +import type { StaticToken } from '@lifi/types' +import { isAddress } from 'viem' +import { describe, expect, it } from 'vitest' +import { supportedEVMChains } from '../chains/supportedChains.evm.js' +import { defaultCoins, wrappedTokens } from './coins.js' + +const evmChainIds = new Set(supportedEVMChains.map((chain) => chain.id)) + +const evmTokens: StaticToken[] = [ + ...defaultCoins.flatMap((coin) => Object.values(coin.chains)), + ...Object.values(wrappedTokens), +].filter((token) => evmChainIds.has(token.chainId)) + +describe('validate EVM token addresses', () => { + it('has tokens to check', () => { + expect(evmTokens.length).toBeGreaterThan(0) + }) + + // A mixed-case address carries its own EIP-55 checksum, so a typo in the + // casing makes it invalid. Services that compare addresses verbatim then + // fail to resolve the token instead of silently normalising it. All-lowercase + // addresses carry no checksum and stay valid. + it('are valid EIP-55 addresses', () => { + const invalid = evmTokens + .filter((token) => !isAddress(token.address, { strict: true })) + .map( + (token) => + `${token.coinKey} on chain ${token.chainId}: ${token.address}` + ) + + expect(invalid).toEqual([]) + }) +})