Skip to content

docs: audit BigNumber 15-sig-digit issue in @metamask/assets-controller#8806

Draft
Prithpal-Sooriya wants to merge 6 commits into
mainfrom
cursor/audit-assets-controller-bignumber-precision-91f9
Draft

docs: audit BigNumber 15-sig-digit issue in @metamask/assets-controller#8806
Prithpal-Sooriya wants to merge 6 commits into
mainfrom
cursor/audit-assets-controller-bignumber-precision-91f9

Conversation

@Prithpal-Sooriya
Copy link
Copy Markdown
Contributor

@Prithpal-Sooriya Prithpal-Sooriya commented May 14, 2026

Explanation

A separate audit on metamask-extension flagged that bignumber.js rejects (or, depending on BigNumber.DEBUG, silently truncates) JS number primitives carrying more than 15 significant digits. The original report focused on CurrencyRateController.boundedPrecisionNumber in the old @metamask/assets-controllers package, which uses toFixed(9) (decimal places) rather than toPrecision(15) (significant digits) and therefore stores values like 40115252.21304121 and 1.0000000000000002 in state. Downstream code that wraps those values in new BigNumber(...) crashes (under DEBUG=true) or silently loses precision (otherwise).

This PR adds an audit report that answers the question "is the same class of bug present in the new @metamask/assets-controller package?" — short answer: yes, in three distinct call paths:

  1. PriceDataSource writes Price API numeric fields (price, usdPrice, marketCap, allTimeHigh, allTimeLow, circulatingSupply, totalVolume, pricePercentChange*) straight into assetsPrice state with no precision bound.
  2. Two in-package multipliedBy(jsNumber) sites (selectors/balance.ts line 471 and AssetsController.ts line 2368) feed those unbounded numbers back into BigNumber math; .multipliedBy(y) internally executes new BigNumber(y), so the same constructor branch is hit.
  3. formatExchangeRatesForBridge / formatStateForTransactionPay re-emit unbounded numbers (including usdPrice / nativeAssetUsdPrice, a classic float-division 17-sig-digit producer) into the legacy CurrencyRateController / TokenRatesController shape that @metamask/bridge-controller's selectors consume by directly wrapping the values in new BigNumber(...) — i.e., the exact crash reproducer described in the upstream report, just routed through this package's bridge-compat shim.

The audit also classifies every BigNumber / BigNumberJS site in this package (safe vs. at-risk) and recommends two layered fixes:

  • Smallest non-breaking fix: boundedPrecisionNumber using toPrecision(15) (significant digits, not toFixed(9) decimal places) applied at the API → state boundary in PriceDataSource, and inside formatExchangeRatesForBridge for conversionRate, usdConversionRate, and the derived priceInNative = usdPrice / nativeAssetUsdPrice.
  • Structurally cleanest fix: also switch AssetPrice.* numeric fields to string (mirroring FungibleAssetBalance.amount). The audit explains why this is a viable internal change but does not remove the need to bound numbers at the bridge-compat shim layer (the legacy shapes this package emits to are owned by the older @metamask/assets-controllers package and typed as number, and the bridge selector wraps those exact number fields in new BigNumber(...)).

This PR is documentation only — no source/behaviour change yet. It's intended as the analysis artefact for the team that owns the controller before any code fix lands.

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
Open in Web Open in Cursor 

cursoragent and others added 6 commits May 14, 2026 07:55
Co-authored-by: Prithpal Sooriya <prithpal.sooriya@gmail.com>
…ounded numbers

Co-authored-by: Prithpal Sooriya <prithpal.sooriya@gmail.com>
Co-authored-by: Prithpal Sooriya <prithpal.sooriya@gmail.com>
…ults

Co-authored-by: Prithpal Sooriya <prithpal.sooriya@gmail.com>
…sion + toFixed

Co-authored-by: Prithpal Sooriya <prithpal.sooriya@gmail.com>
…tent 'e' edge

Co-authored-by: Prithpal Sooriya <prithpal.sooriya@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants