Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/assets-controllers/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Add optional `rwaData` support when adding tokens in `TokensController` ([#7804](https://github.com/MetaMask/core/pull/7804)).

## [99.2.0]

### Added
Expand Down
12 changes: 10 additions & 2 deletions packages/assets-controllers/src/TokensController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import { ERC1155Standard } from './Standards/NftStandards/ERC1155/ERC1155Standar
import {
fetchTokenMetadata,
TOKEN_METADATA_NO_SUPPORT_ERROR,
TokenRwaData,
} from './token-service';
import type {
TokenListStateChange,
Expand Down Expand Up @@ -288,6 +289,9 @@ export class TokensController extends BaseController<
if (cachedToken && cachedToken.name && !token.name) {
token.name = cachedToken.name; // Update the token name
}
if (cachedToken?.rwaData) {
token.rwaData = cachedToken.rwaData; // Update the token RWA data
}
Copy link

Choose a reason for hiding this comment

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

Cache unconditionally overwrites user-provided rwaData unlike name

Medium Severity

The cache propagation logic for rwaData unconditionally overwrites existing token data when cachedToken.rwaData exists, unlike the name handling which only updates when !token.name. This means user-provided rwaData (set via watchAsset or addToken) will be lost when the TokenListController:stateChange event fires with cached data. The condition if (cachedToken?.rwaData) is missing the !token.rwaData check that would preserve user-provided values.

Fix in Cursor Fix in Web

Copy link

Choose a reason for hiding this comment

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

Stale rwaData persists when cache no longer has it

Low Severity

The rwaData propagation logic only updates tokens when the cache has rwaData, but never clears it when the cache no longer has rwaData. If a token loses its RWA status in the API (cache updates without rwaData), the token retains stale rwaData. Since the code always overwrites rwaData when present (unlike name which checks !token.name), the intent appears to be keeping rwaData synchronized with the cache, but the clearing case is missing. This could display outdated RWA information (market hours, pause times) for tokens that are no longer RWA.

Fix in Cursor Fix in Web

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is on purpose

}
}
}
Expand Down Expand Up @@ -416,6 +420,7 @@ export class TokensController extends BaseController<
* @param options.image - Image of the token.
* @param options.interactingAddress - The address of the account to add a token to.
* @param options.networkClientId - Network Client ID.
* @param options.rwaData - Optional RWA data for the token.
* @returns Current token list.
*/
async addToken({
Expand All @@ -426,6 +431,7 @@ export class TokensController extends BaseController<
image,
interactingAddress,
networkClientId,
rwaData,
}: {
address: string;
symbol: string;
Expand All @@ -434,6 +440,7 @@ export class TokensController extends BaseController<
image?: string;
interactingAddress?: string;
networkClientId: NetworkClientId;
rwaData?: TokenRwaData;
}): Promise<Token[]> {
const releaseLock = await this.#mutex.acquire();
const { allTokens, allIgnoredTokens, allDetectedTokens } = this.state;
Expand Down Expand Up @@ -473,7 +480,7 @@ export class TokensController extends BaseController<
isERC721,
aggregators: formatAggregatorNames(tokenMetadata?.aggregators ?? []),
name,
...(tokenMetadata?.rwaData && { rwaData: tokenMetadata.rwaData }),
...(rwaData !== undefined && { rwaData }),
};
const previousIndex = newTokens.findIndex(
(token) => token.address.toLowerCase() === address.toLowerCase(),
Expand Down Expand Up @@ -986,7 +993,7 @@ export class TokensController extends BaseController<

await this.#requestApproval(suggestedAssetMeta);

const { address, symbol, decimals, name, image } = asset;
const { address, symbol, decimals, name, image, rwaData } = asset;
await this.addToken({
address,
symbol,
Expand All @@ -995,6 +1002,7 @@ export class TokensController extends BaseController<
image,
interactingAddress: suggestedAssetMeta.interactingAddress,
networkClientId,
rwaData,
});
}

Expand Down
Loading