Skip to content

fix: omit balances without reliable decimals#8267

Merged
salimtb merged 9 commits intomainfrom
fix/assets-no-fallback-decimals-18
Mar 23, 2026
Merged

fix: omit balances without reliable decimals#8267
salimtb merged 9 commits intomainfrom
fix/assets-no-fallback-decimals-18

Conversation

@salimtb
Copy link
Copy Markdown
Contributor

@salimtb salimtb commented Mar 20, 2026

  • RpcDataSource: skip human-readable balance when decimals stay falsy after RPC
  • TokenDetector: skip detectedBalances when token list has no decimals
  • BalanceFetcher: native stays 18; ERC-20 without tokenInfos uses 1; explicit tokenInfo without decimals skips
  • Add unit tests for RpcDataSource, BalanceFetcher, and TokenDetector

Explanation

References

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them

Note

Medium Risk
Changes core balance/token-detection behavior by no longer defaulting ERC-20 decimals to 18, which can remove balances/metadata from responses until decimals resolve and may impact downstream consumers expecting entries to exist.

Overview
Stops the EVM RPC assets pipeline from guessing ERC-20 decimals: RpcDataSource, BalanceFetcher, and TokenDetector now omit human-readable balances (and related assetsInfo/detectedBalances entries) when decimals are unknown, rather than defaulting to 18 (native tokens remain 18).

BalanceFetcher now treats ERC-20 decimals as optional in TokenFetchInfo/AssetBalance and passes raw balances through when decimals aren’t provided; RpcDataSource adds #tokenFetchInfosForCustomErc20s and updates balance conversion logic to skip formatting without decimals and avoid emitting placeholder metadata. Test suites are updated/expanded to cover the new omission behavior and edge cases (missing/zero decimals).

Written by Cursor Bugbot for commit 419030b. This will update automatically on new commits. Configure here.

salimtb added 3 commits March 20, 2026 23:14
- RpcDataSource: skip human-readable balance when decimals stay falsy after RPC
- TokenDetector: skip detectedBalances when token list has no decimals
- BalanceFetcher: native stays 18; ERC-20 without tokenInfos uses 1; explicit tokenInfo without decimals skips
- Add unit tests for RpcDataSource, BalanceFetcher, and TokenDetector
@salimtb salimtb marked this pull request as ready for review March 21, 2026 01:04
@salimtb salimtb requested review from a team as code owners March 21, 2026 01:04
@salimtb
Copy link
Copy Markdown
Contributor Author

salimtb commented Mar 21, 2026

@metamaskbot publish-preview

@github-actions
Copy link
Copy Markdown
Contributor

Preview builds have been published. Learn how to use preview builds in other projects.

Expand for full list of packages and versions.
@metamask-previews/account-tree-controller@5.0.1-preview-9f983cce7
@metamask-previews/accounts-controller@37.0.0-preview-9f983cce7
@metamask-previews/address-book-controller@7.1.0-preview-9f983cce7
@metamask-previews/ai-controllers@0.4.0-preview-9f983cce7
@metamask-previews/analytics-controller@1.0.0-preview-9f983cce7
@metamask-previews/analytics-data-regulation-controller@0.0.0-preview-9f983cce7
@metamask-previews/announcement-controller@8.0.0-preview-9f983cce7
@metamask-previews/app-metadata-controller@2.0.0-preview-9f983cce7
@metamask-previews/approval-controller@9.0.0-preview-9f983cce7
@metamask-previews/assets-controller@3.0.0-preview-9f983cce7
@metamask-previews/assets-controllers@101.0.1-preview-9f983cce7
@metamask-previews/base-controller@9.0.0-preview-9f983cce7
@metamask-previews/base-data-service@0.0.0-preview-9f983cce7
@metamask-previews/bridge-controller@69.2.0-preview-9f983cce7
@metamask-previews/bridge-status-controller@70.0.0-preview-9f983cce7
@metamask-previews/build-utils@3.0.4-preview-9f983cce7
@metamask-previews/chain-agnostic-permission@1.4.0-preview-9f983cce7
@metamask-previews/claims-controller@0.4.3-preview-9f983cce7
@metamask-previews/client-controller@1.0.0-preview-9f983cce7
@metamask-previews/compliance-controller@1.0.1-preview-9f983cce7
@metamask-previews/composable-controller@12.0.0-preview-9f983cce7
@metamask-previews/config-registry-controller@0.1.1-preview-9f983cce7
@metamask-previews/connectivity-controller@0.1.0-preview-9f983cce7
@metamask-previews/controller-utils@11.19.0-preview-9f983cce7
@metamask-previews/core-backend@6.2.0-preview-9f983cce7
@metamask-previews/delegation-controller@2.0.2-preview-9f983cce7
@metamask-previews/earn-controller@11.1.2-preview-9f983cce7
@metamask-previews/eip-5792-middleware@3.0.1-preview-9f983cce7
@metamask-previews/eip-7702-internal-rpc-middleware@0.1.0-preview-9f983cce7
@metamask-previews/eip1193-permission-middleware@1.0.3-preview-9f983cce7
@metamask-previews/ens-controller@19.1.0-preview-9f983cce7
@metamask-previews/error-reporting-service@3.0.1-preview-9f983cce7
@metamask-previews/eth-block-tracker@15.0.1-preview-9f983cce7
@metamask-previews/eth-json-rpc-middleware@23.1.0-preview-9f983cce7
@metamask-previews/eth-json-rpc-provider@6.0.0-preview-9f983cce7
@metamask-previews/foundryup@1.0.1-preview-9f983cce7
@metamask-previews/gas-fee-controller@26.1.0-preview-9f983cce7
@metamask-previews/gator-permissions-controller@2.1.1-preview-9f983cce7
@metamask-previews/geolocation-controller@0.1.1-preview-9f983cce7
@metamask-previews/json-rpc-engine@10.2.3-preview-9f983cce7
@metamask-previews/json-rpc-middleware-stream@8.0.8-preview-9f983cce7
@metamask-previews/keyring-controller@25.1.0-preview-9f983cce7
@metamask-previews/logging-controller@8.0.0-preview-9f983cce7
@metamask-previews/message-manager@14.1.0-preview-9f983cce7
@metamask-previews/messenger@0.3.0-preview-9f983cce7
@metamask-previews/multichain-account-service@7.1.0-preview-9f983cce7
@metamask-previews/multichain-api-middleware@1.2.7-preview-9f983cce7
@metamask-previews/multichain-network-controller@3.0.5-preview-9f983cce7
@metamask-previews/multichain-transactions-controller@7.0.2-preview-9f983cce7
@metamask-previews/name-controller@9.1.0-preview-9f983cce7
@metamask-previews/network-controller@30.0.0-preview-9f983cce7
@metamask-previews/network-enablement-controller@5.0.0-preview-9f983cce7
@metamask-previews/notification-services-controller@23.0.0-preview-9f983cce7
@metamask-previews/permission-controller@12.2.1-preview-9f983cce7
@metamask-previews/permission-log-controller@5.0.0-preview-9f983cce7
@metamask-previews/perps-controller@1.3.0-preview-9f983cce7
@metamask-previews/phishing-controller@17.0.0-preview-9f983cce7
@metamask-previews/polling-controller@16.0.3-preview-9f983cce7
@metamask-previews/preferences-controller@23.0.0-preview-9f983cce7
@metamask-previews/profile-metrics-controller@3.1.1-preview-9f983cce7
@metamask-previews/profile-sync-controller@28.0.0-preview-9f983cce7
@metamask-previews/ramps-controller@12.0.1-preview-9f983cce7
@metamask-previews/rate-limit-controller@7.0.0-preview-9f983cce7
@metamask-previews/react-data-query@0.0.0-preview-9f983cce7
@metamask-previews/remote-feature-flag-controller@4.1.0-preview-9f983cce7
@metamask-previews/sample-controllers@4.0.3-preview-9f983cce7
@metamask-previews/seedless-onboarding-controller@9.0.0-preview-9f983cce7
@metamask-previews/selected-network-controller@26.0.3-preview-9f983cce7
@metamask-previews/shield-controller@5.0.2-preview-9f983cce7
@metamask-previews/signature-controller@39.1.0-preview-9f983cce7
@metamask-previews/storage-service@1.0.0-preview-9f983cce7
@metamask-previews/subscription-controller@6.0.2-preview-9f983cce7
@metamask-previews/transaction-controller@63.0.0-preview-9f983cce7
@metamask-previews/transaction-pay-controller@18.0.0-preview-9f983cce7
@metamask-previews/user-operation-controller@41.1.0-preview-9f983cce7

Comment thread packages/assets-controller/src/data-sources/RpcDataSource.ts
Comment thread packages/assets-controller/src/data-sources/RpcDataSource.ts
Comment thread packages/assets-controller/src/data-sources/RpcDataSource.ts Outdated
@salimtb salimtb changed the title fix(assets-controller): omit balances without reliable decimals fix: omit balances without reliable decimals Mar 23, 2026
Comment thread packages/assets-controller/src/data-sources/RpcDataSource.ts Outdated
Comment thread packages/assets-controllers/src/TokenDetectionController.ts Outdated
Comment thread packages/assets-controllers/src/TokenDetectionController.ts Outdated
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

@salimtb
Copy link
Copy Markdown
Contributor Author

salimtb commented Mar 23, 2026

@metamaskbot publish-preview

@github-actions
Copy link
Copy Markdown
Contributor

Preview builds have been published. Learn how to use preview builds in other projects.

Expand for full list of packages and versions.
@metamask-previews/account-tree-controller@5.0.1-preview-419030b03
@metamask-previews/accounts-controller@37.0.0-preview-419030b03
@metamask-previews/address-book-controller@7.1.0-preview-419030b03
@metamask-previews/ai-controllers@0.4.0-preview-419030b03
@metamask-previews/analytics-controller@1.0.0-preview-419030b03
@metamask-previews/analytics-data-regulation-controller@0.0.0-preview-419030b03
@metamask-previews/announcement-controller@8.0.0-preview-419030b03
@metamask-previews/app-metadata-controller@2.0.0-preview-419030b03
@metamask-previews/approval-controller@9.0.0-preview-419030b03
@metamask-previews/assets-controller@3.0.0-preview-419030b03
@metamask-previews/assets-controllers@101.0.1-preview-419030b03
@metamask-previews/base-controller@9.0.0-preview-419030b03
@metamask-previews/base-data-service@0.0.0-preview-419030b03
@metamask-previews/bridge-controller@69.2.0-preview-419030b03
@metamask-previews/bridge-status-controller@70.0.0-preview-419030b03
@metamask-previews/build-utils@3.0.4-preview-419030b03
@metamask-previews/chain-agnostic-permission@1.4.0-preview-419030b03
@metamask-previews/claims-controller@0.4.3-preview-419030b03
@metamask-previews/client-controller@1.0.0-preview-419030b03
@metamask-previews/compliance-controller@1.0.1-preview-419030b03
@metamask-previews/composable-controller@12.0.0-preview-419030b03
@metamask-previews/config-registry-controller@0.1.1-preview-419030b03
@metamask-previews/connectivity-controller@0.1.0-preview-419030b03
@metamask-previews/controller-utils@11.19.0-preview-419030b03
@metamask-previews/core-backend@6.2.0-preview-419030b03
@metamask-previews/delegation-controller@2.0.2-preview-419030b03
@metamask-previews/earn-controller@11.1.2-preview-419030b03
@metamask-previews/eip-5792-middleware@3.0.1-preview-419030b03
@metamask-previews/eip-7702-internal-rpc-middleware@0.1.0-preview-419030b03
@metamask-previews/eip1193-permission-middleware@1.0.3-preview-419030b03
@metamask-previews/ens-controller@19.1.0-preview-419030b03
@metamask-previews/error-reporting-service@3.0.1-preview-419030b03
@metamask-previews/eth-block-tracker@15.0.1-preview-419030b03
@metamask-previews/eth-json-rpc-middleware@23.1.0-preview-419030b03
@metamask-previews/eth-json-rpc-provider@6.0.0-preview-419030b03
@metamask-previews/foundryup@1.0.1-preview-419030b03
@metamask-previews/gas-fee-controller@26.1.0-preview-419030b03
@metamask-previews/gator-permissions-controller@2.1.1-preview-419030b03
@metamask-previews/geolocation-controller@0.1.1-preview-419030b03
@metamask-previews/json-rpc-engine@10.2.3-preview-419030b03
@metamask-previews/json-rpc-middleware-stream@8.0.8-preview-419030b03
@metamask-previews/keyring-controller@25.1.0-preview-419030b03
@metamask-previews/logging-controller@8.0.0-preview-419030b03
@metamask-previews/message-manager@14.1.0-preview-419030b03
@metamask-previews/messenger@0.3.0-preview-419030b03
@metamask-previews/multichain-account-service@7.1.0-preview-419030b03
@metamask-previews/multichain-api-middleware@1.2.7-preview-419030b03
@metamask-previews/multichain-network-controller@3.0.5-preview-419030b03
@metamask-previews/multichain-transactions-controller@7.0.2-preview-419030b03
@metamask-previews/name-controller@9.1.0-preview-419030b03
@metamask-previews/network-controller@30.0.0-preview-419030b03
@metamask-previews/network-enablement-controller@5.0.0-preview-419030b03
@metamask-previews/notification-services-controller@23.0.0-preview-419030b03
@metamask-previews/permission-controller@12.2.1-preview-419030b03
@metamask-previews/permission-log-controller@5.0.0-preview-419030b03
@metamask-previews/perps-controller@1.3.0-preview-419030b03
@metamask-previews/phishing-controller@17.0.0-preview-419030b03
@metamask-previews/polling-controller@16.0.3-preview-419030b03
@metamask-previews/preferences-controller@23.0.0-preview-419030b03
@metamask-previews/profile-metrics-controller@3.1.1-preview-419030b03
@metamask-previews/profile-sync-controller@28.0.0-preview-419030b03
@metamask-previews/ramps-controller@12.0.1-preview-419030b03
@metamask-previews/rate-limit-controller@7.0.0-preview-419030b03
@metamask-previews/react-data-query@0.0.0-preview-419030b03
@metamask-previews/remote-feature-flag-controller@4.1.0-preview-419030b03
@metamask-previews/sample-controllers@4.0.3-preview-419030b03
@metamask-previews/seedless-onboarding-controller@9.0.0-preview-419030b03
@metamask-previews/selected-network-controller@26.0.3-preview-419030b03
@metamask-previews/shield-controller@5.0.2-preview-419030b03
@metamask-previews/signature-controller@39.1.0-preview-419030b03
@metamask-previews/storage-service@1.0.0-preview-419030b03
@metamask-previews/subscription-controller@6.0.2-preview-419030b03
@metamask-previews/transaction-controller@63.0.0-preview-419030b03
@metamask-previews/transaction-pay-controller@18.0.0-preview-419030b03
@metamask-previews/user-operation-controller@41.1.0-preview-419030b03

/** Token decimals used for formatting */
decimals: number;
/** Token decimals used for formatting; omitted when unknown (raw `balance` only; resolved downstream). */
decimals?: number;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

in theory the token api should always return decimals , in case it's not we fallback to rpc calls

const rawAmount = new BigNumberJS(rawBalance);
const divisor = new BigNumberJS(10).pow(decimals);
return rawAmount.dividedBy(divisor).toString();
return rawAmount.dividedBy(divisor).toFixed();
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

we use default rounding on toFixed , but this can be changed

};
}
// Unknown ERC-20: omit from assetsInfo until decimals are known.
// #handleBalanceUpdate resolves decimals via RPC or omits the balance.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

we just skip in case of non decimals

@salimtb salimtb requested a review from bergarces March 23, 2026 13:21
@salimtb salimtb added this pull request to the merge queue Mar 23, 2026
Merged via the queue into main with commit d3cfc50 Mar 23, 2026
326 checks passed
@salimtb salimtb deleted the fix/assets-no-fallback-decimals-18 branch March 23, 2026 13:39
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