[utils] `toWei` accepts fractional wei and returns wrong values

Open Beginner friendly
#10,209 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
88/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
typescript
Domain
blockchain

Research direction

Start with packages/utils/src/unitsConversion.ts and compare the behavior with the original pull request linked in the issue. Add regression coverage for fractional wei values such as 0.5, 1.5, and 0.9, then run the relevant utils tests and confirm fractional wei is rejected while whole wei remains unchanged.

Written by the indexing model from the issue text.

Description

Carried over from https://github.com/MetaMask/utils/pull/303, which was open when @metamask/utils moved into core.

toWei silently accepts fractional wei and returns the wrong number. Confirmed against main today:

import { toWei } from '@metamask/utils';

toWei('0.5', 'wei'); // 5n
toWei('1.5', 'wei'); // 6n
toWei('0.9', 'wei'); // 9n
toWei('1', 'wei');   // 1n

Wei is the base unit, so anything with a fractional part should be rejected rather than scaled.

The cause is in packages/utils/src/unitsConversion.ts:

const unitLengths = Object.fromEntries(
  Object.entries(unitMap).map(([key, value]) => [key, value.length - 1 || 1]),
) as Record<EthereumUnit, number>;

Wei's raw value is '1', so value.length - 1 is 0, which is the correct precision for the base unit. The || 1 fallback then turns that 0 into 1, so the fraction gets treated as one decimal place of a larger unit.

The original PR has the fix plus tests.

Dominant language
TypeScript
Stars
413
Forks
308
Avg merge
1d 4h
Merged PRs (30d)
253

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from MetaMask/core

All issues in MetaMask/core

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.