Skip to content

Commit d8c6406

Browse files
Merge pull request #8961 from BitGo/revert-8926-CGD-715
Revert "fix: reject duplicate contract address and NFT index keys in CoinMap"
2 parents edc3d2e + 41613eb commit d8c6406

4 files changed

Lines changed: 13 additions & 119 deletions

File tree

modules/statics/src/coins/erc7984Tokens.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,15 @@ export const erc7984Tokens = [
2424
'eth:ctkn',
2525
'Confidential Test Token',
2626
6,
27-
'0x0000000000000000000000000000000000000001', // TODO: update with mainnet contract address
27+
'0x0000000000000000000000000000000000000000', // TODO: update with mainnet contract address
2828
UnderlyingAsset['eth:ctkn']
2929
),
3030
erc7984(
3131
'f47ac10b-58cc-4372-a567-0e02b2c3d480',
3232
'eth:cusdt',
3333
'Confidential USDT',
3434
6,
35-
'0x0000000000000000000000000000000000000002', // TODO: update with mainnet contract address
35+
'0x0000000000000000000000000000000000000000', // TODO: update with mainnet contract address
3636
UnderlyingAsset['eth:cusdt']
3737
),
3838

modules/statics/src/errors.ts

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,6 @@ export class DuplicateCoinIdDefinitionError extends BitGoStaticsError {
3333
}
3434
}
3535

36-
export class DuplicateContractAddressDefinitionError extends BitGoStaticsError {
37-
public constructor(contractAddressKey: string, existingCoinName: string) {
38-
super(`token with contract address '${contractAddressKey}' is already defined as '${existingCoinName}'`);
39-
Object.setPrototypeOf(this, DuplicateContractAddressDefinitionError.prototype);
40-
}
41-
}
42-
43-
export class DuplicateNftCollectionIdDefinitionError extends BitGoStaticsError {
44-
public constructor(nftCollectionKey: string, existingCoinName: string) {
45-
super(`token with NFT collection id '${nftCollectionKey}' is already defined as '${existingCoinName}'`);
46-
Object.setPrototypeOf(this, DuplicateNftCollectionIdDefinitionError.prototype);
47-
}
48-
}
49-
5036
export class DisallowedCoinFeatureError extends BitGoStaticsError {
5137
public constructor(coinName: string, feature: CoinFeature) {
5238
super(`coin feature '${feature}' is disallowed for coin ${coinName}.`);

modules/statics/src/map.ts

Lines changed: 7 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
11
import { BaseCoin } from './base';
2-
import {
3-
DuplicateCoinDefinitionError,
4-
CoinNotDefinedError,
5-
DuplicateCoinIdDefinitionError,
6-
DuplicateContractAddressDefinitionError,
7-
DuplicateNftCollectionIdDefinitionError,
8-
} from './errors';
2+
import { DuplicateCoinDefinitionError, CoinNotDefinedError, DuplicateCoinIdDefinitionError } from './errors';
93
import { ContractAddressDefinedToken, NFTCollectionIdDefinedToken } from './account';
104
import { EthereumNetwork } from './networks';
115

@@ -14,10 +8,10 @@ export class CoinMap {
148
private readonly _coinByIds = new Map<string, Readonly<BaseCoin>>();
159
// Holds key equivalences used during an asset name migration
1610
private readonly _coinByAliases = new Map<string, Readonly<BaseCoin>>();
17-
// map of coin by address -> the key is the family:networkType:contractAddress
11+
// map of coin by address -> the key is the family:contractAddress
1812
// the family is the where the coin is e.g l1 chains like eth, bsc etc. or l2 like arbeth, celo etc.
1913
private readonly _coinByContractAddress = new Map<string, Readonly<BaseCoin>>();
20-
// map of coin by NFT collection ID -> the key is the (t)family:networkType:nftCollectionID
14+
// map of coin by NFT collection ID -> the key is the (t)family:nftCollectionID
2115
private readonly _coinByNftCollectionID = new Map<string, Readonly<BaseCoin>>();
2216
// Lazily initialized cache for chainId to coin name mapping (derived from network definitions)
2317
private _coinByChainId: Map<number, string> | null = null;
@@ -26,14 +20,6 @@ export class CoinMap {
2620
// Do not instantiate
2721
}
2822

29-
private static contractAddressKey(coin: ContractAddressDefinedToken): string {
30-
return `${coin.family}:${coin.network.type}:${coin.contractAddress}`;
31-
}
32-
33-
private static nftCollectionIdKey(coin: NFTCollectionIdDefinedToken): string {
34-
return `${coin.prefix}${coin.family}:${coin.network.type}:${coin.nftCollectionId}`;
35-
}
36-
3723
static fromCoins(coins: Readonly<BaseCoin>[]): CoinMap {
3824
const coinMap = new CoinMap();
3925
coins.forEach((coin) => {
@@ -61,19 +47,9 @@ export class CoinMap {
6147

6248
if (coin.isToken) {
6349
if (coin instanceof ContractAddressDefinedToken) {
64-
const contractAddressKey = CoinMap.contractAddressKey(coin);
65-
const existingByContractAddress = this._coinByContractAddress.get(contractAddressKey);
66-
if (existingByContractAddress) {
67-
throw new DuplicateContractAddressDefinitionError(contractAddressKey, existingByContractAddress.name);
68-
}
69-
this._coinByContractAddress.set(contractAddressKey, coin);
50+
this._coinByContractAddress.set(`${coin.family}:${coin.contractAddress}`, coin);
7051
} else if (coin instanceof NFTCollectionIdDefinedToken) {
71-
const nftCollectionKey = CoinMap.nftCollectionIdKey(coin);
72-
const existingByNftCollectionId = this._coinByNftCollectionID.get(nftCollectionKey);
73-
if (existingByNftCollectionId) {
74-
throw new DuplicateNftCollectionIdDefinitionError(nftCollectionKey, existingByNftCollectionId.name);
75-
}
76-
this._coinByNftCollectionID.set(nftCollectionKey, coin);
52+
this._coinByNftCollectionID.set(`${coin.prefix}${coin.family}:${coin.nftCollectionId}`, coin);
7753
}
7854
}
7955
}
@@ -93,9 +69,9 @@ export class CoinMap {
9369
}
9470
if (oldCoin.isToken) {
9571
if (oldCoin instanceof ContractAddressDefinedToken) {
96-
this._coinByContractAddress.delete(CoinMap.contractAddressKey(oldCoin));
72+
this._coinByContractAddress.delete(`${oldCoin.family}:${oldCoin.contractAddress}`);
9773
} else if (oldCoin instanceof NFTCollectionIdDefinedToken) {
98-
this._coinByNftCollectionID.delete(CoinMap.nftCollectionIdKey(oldCoin));
74+
this._coinByNftCollectionID.delete(`${oldCoin.prefix}${oldCoin.family}:${oldCoin.nftCollectionId}`);
9975
}
10076
}
10177
}

modules/statics/test/unit/coins.ts

Lines changed: 4 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ import {
4141
trimmedDynamicBaseChainConfig,
4242
} from './resources/amsTokenConfig';
4343
import { EthLikeErc20Token } from '../../../sdk-coin-evm/src';
44-
import { ProgramID, taptNFTCollection, terc20 } from '../../src/account';
44+
import { ProgramID } from '../../src/account';
4545
import { allCoinsAndTokens } from '../../src/allCoinsAndTokens';
4646

4747
interface DuplicateCoinObject {
@@ -753,70 +753,6 @@ describe('CoinMap', function () {
753753
(() => CoinMap.fromCoins([btc, btc2])).should.throw(`coin with id '${btc.id}' is already defined`);
754754
});
755755

756-
it('should fail to map tokens with duplicated contract address for the same family', () => {
757-
const template = coins.get('tusdc');
758-
const contractAddress = (template as Erc20Coin).contractAddress;
759-
const tokenA = terc20(
760-
'11111111-1111-4111-8111-111111111111',
761-
'token-a',
762-
'Token A',
763-
6,
764-
contractAddress,
765-
template.asset,
766-
template.features,
767-
template.prefix,
768-
template.suffix,
769-
template.network
770-
);
771-
const tokenB = terc20(
772-
'22222222-2222-4222-8222-222222222222',
773-
'token-b',
774-
'Token B',
775-
18,
776-
contractAddress,
777-
template.asset,
778-
template.features,
779-
template.prefix,
780-
template.suffix,
781-
template.network
782-
);
783-
const contractAddressKey = `${tokenA.family}:${tokenA.network.type}:${contractAddress}`;
784-
(() => CoinMap.fromCoins([tokenA, tokenB])).should.throw(
785-
`token with contract address '${contractAddressKey}' is already defined as 'token-a'`
786-
);
787-
});
788-
789-
it('should fail to map tokens with duplicated NFT collection id for the same family', () => {
790-
const template = coins.get('tapt:nftcollection1');
791-
const nftCollectionId = '0xbbc561fbfa5d105efd8dfb06ae3e7e5be46331165b99d518f094c701e40603b5';
792-
const tokenA = taptNFTCollection(
793-
'11111111-1111-4111-8111-111111111111',
794-
'tapt:nftcollection-a',
795-
'NFT Collection A',
796-
nftCollectionId,
797-
template.asset,
798-
template.features,
799-
template.prefix,
800-
template.suffix,
801-
template.network
802-
);
803-
const tokenB = taptNFTCollection(
804-
'22222222-2222-4222-8222-222222222222',
805-
'tapt:nftcollection-b',
806-
'NFT Collection B',
807-
nftCollectionId,
808-
template.asset,
809-
template.features,
810-
template.prefix,
811-
template.suffix,
812-
template.network
813-
);
814-
const nftCollectionKey = `${tokenA.prefix}${tokenA.family}:${tokenA.network.type}:${nftCollectionId}`;
815-
(() => CoinMap.fromCoins([tokenA, tokenB])).should.throw(
816-
`token with NFT collection id '${nftCollectionKey}' is already defined as 'tapt:nftcollection-a'`
817-
);
818-
});
819-
820756
it('should have iterator', function () {
821757
[...coins].length.should.be.greaterThan(100);
822758
});
@@ -847,10 +783,10 @@ describe('CoinMap', function () {
847783

848784
it('should get coin by address', () => {
849785
const weth = coins.get('weth');
850-
const wethByAddress = coins.get(`${weth.family}:${weth.network.type}:${(weth as Erc20Coin).contractAddress}`);
786+
const wethByAddress = coins.get(`${weth.family}:${(weth as Erc20Coin).contractAddress}`);
851787
wethByAddress.should.deepEqual(weth);
852788
const tweth = coins.get('tweth');
853-
const twethByAddress = coins.get(`${tweth.family}:${tweth.network.type}:${(tweth as Erc20Coin).contractAddress}`);
789+
const twethByAddress = coins.get(`${tweth.family}:${(tweth as Erc20Coin).contractAddress}`);
854790
twethByAddress.should.deepEqual(tweth);
855791
});
856792

@@ -859,11 +795,7 @@ describe('CoinMap', function () {
859795
});
860796

861797
it('should find coin by NFT collection ID', () => {
862-
const nftCollectionStatics = coins.get(
863-
`tapt:${
864-
coins.get('tapt:nftcollection1').network.type
865-
}:0xbbc561fbfa5d105efd8dfb06ae3e7e5be46331165b99d518f094c701e40603b5`
866-
);
798+
const nftCollectionStatics = coins.get('tapt:0xbbc561fbfa5d105efd8dfb06ae3e7e5be46331165b99d518f094c701e40603b5');
867799
nftCollectionStatics.name.should.eql('tapt:nftcollection1');
868800
});
869801

0 commit comments

Comments
 (0)