Skip to content

fix: reject duplicate contract address and NFT index keys in CoinMap#8926

Open
nvjsr wants to merge 1 commit into
masterfrom
CGD-715
Open

fix: reject duplicate contract address and NFT index keys in CoinMap#8926
nvjsr wants to merge 1 commit into
masterfrom
CGD-715

Conversation

@nvjsr
Copy link
Copy Markdown
Contributor

@nvjsr nvjsr commented Jun 3, 2026

Description

Fixes CGD-715 / BTGO-13: CoinMap.addCoin() enforced uniqueness for coin name, id, and alias, but silently overwrote entries in the contract-address and NFT-collection secondary indexes when two tokens shared the same lookup key. A later-registered token could shadow an existing one for coins.get(family:networkType:contractAddress) lookups, leading to wrong token metadata (e.g. decimals) during transaction construction.

Changes:

Throw DuplicateContractAddressDefinitionError / DuplicateNftCollectionIdDefinitionError on index collision (same pattern as name/id checks).
Include network.type in index keys (family:mainnet|testnet:address) so mainnet and testnet tokens on the same chain family no longer share one slot.
Assign unique placeholder contract addresses for eth:ctkn and eth:cusdt (both previously used 0x000…000).
Add unit tests for duplicate contract/NFT keys and update address/NFT lookup tests for the new key format.
Motivation: Sigma Prime audit finding — secondary indexes must not allow silent overwrite.

Issue Number
CGD-715 (BTGO-13)

Type of change
Bug fix (non-breaking change which fixes an issue)
New feature (non-breaking change which adds functionality)
Breaking change (fix or feature that would cause existing functionality to not work as expected)

This change requires a documentation update
Breaking change: Contract-address and NFT-collection lookups via CoinMap.get() must use the new composite key format, e.g. eth:mainnet:0x… instead of eth:0x…. Coin lookup by name is unchanged.

@linear-code
Copy link
Copy Markdown

linear-code Bot commented Jun 3, 2026

CGD-715

… CoinMap

CoinMap.addCoin() now throws on collision for contract-address and
NFT-collection indexes instead of silently overwriting the existing entry.
Index keys include network type (family:networkType:address) so mainnet
and testnet tokens on the same family no longer share one slot.
Use distinct placeholder addresses for eth:ctkn and eth:cusdt until
mainnet contracts are defined.
CGD-715

TICKET: CGD-715
@nvjsr nvjsr marked this pull request as ready for review June 3, 2026 08:56
@nvjsr nvjsr requested a review from a team as a code owner June 3, 2026 08:56
const contractAddressKey = CoinMap.contractAddressKey(coin);
const existingByContractAddress = this._coinByContractAddress.get(contractAddressKey);
if (existingByContractAddress) {
throw new DuplicateContractAddressDefinitionError(contractAddressKey, existingByContractAddress.name);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

when does this run ?

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