Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: toBignumber conversion error with high balance #12010

Merged
merged 12 commits into from
Oct 28, 2024

Conversation

siibars
Copy link
Contributor

@siibars siibars commented Oct 24, 2024

Description

There is a bignumber conversion attempt which is failing, this change fixes this.

Related issues

Fixes: STAKE-848

Manual testing steps

  1. connect with an account with a high ETH balance
  2. enable the native staking feature flag
  3. click stake to get to the StakeinputView

Screenshots/Recordings

Before

image

View: Root
Error: [number-to-bn] while converting number "3.487400189415765903484e+21" to BN.js instance, error: invalid number value. Value must be an integer, hex string, BN or BigNumber instance. Note, decimals are not supported.

After

This issue doesn't happen.

Pre-merge author checklist

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

@siibars siibars requested a review from a team as a code owner October 24, 2024 17:12
Copy link
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

Matt561
Matt561 previously approved these changes Oct 24, 2024
@siibars siibars added team-stake Run Smoke E2E Triggers smoke e2e on Bitrise labels Oct 24, 2024
Copy link
Contributor

github-actions bot commented Oct 24, 2024

https://bitrise.io/ Bitrise

✅✅✅ pr_smoke_e2e_pipeline passed on Bitrise! ✅✅✅

Commit hash: fc7623c
Build link: https://app.bitrise.io/app/be69d4368ee7e86d/pipelines/40b358b8-44bc-4313-bf09-f955ae877fa7

Note

  • You can kick off another pr_smoke_e2e_pipeline on Bitrise by removing and re-applying the Run Smoke E2E label on the pull request

@legobeat
Copy link
Contributor

legobeat commented Oct 24, 2024

Do you have a link (or would you be able to describe in PR description) the issue this fixes?

Considering if this is related at all to solving it:

Also, is there any possible way to add a regression test for this bugfix?

@Matt561 Matt561 self-requested a review October 24, 2024 17:59
amitabh94
amitabh94 previously approved these changes Oct 25, 2024
@siibars siibars requested a review from legobeat October 25, 2024 13:33
@siibars siibars added the Priority - Medium Task with medium priority label Oct 25, 2024
Copy link
Contributor

@Daniel-Cross Daniel-Cross left a comment

Choose a reason for hiding this comment

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

Check whether the useMemo is actually needed. This kind of hook allocates system memory to watch the dependancies.

Daniel-Cross
Daniel-Cross previously approved these changes Oct 25, 2024
Copy link
Contributor

@Daniel-Cross Daniel-Cross left a comment

Choose a reason for hiding this comment

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

Looks good, once the tests are passing. Thanks

@legobeat
Copy link
Contributor

legobeat commented Oct 25, 2024

Do you have a link (or would you be able to describe in PR description) the issue this fixes?

Considering if this is related at all to solving it:

@siibars Thanks for updating, much clearer! 👍

Looks like it is indeed related. bn.js v4 does accept numbers with scientific notation as input to the constructor while v5 throws an error. It seems likely that this was once working correctly when implemented towards bn.js@4 and then at some point it started failing as the library version used in that particular place got substituted with v5. Unfortunately, the way BN is imported from legacy ethereumjs-util makes these discrepancies currently not get caught in type checks.

> new (require('bnjs4'))('1.23e30')
BN { negative: 0, words: [ 824430 ], length: 1, red: null }

> new (require('bnjs5'))('1.23e30')
Uncaught Error: Invalid character
    at assert (/home/user/dev/mm/.worktrees/metamask-mobile/deps-ethereumjs-6/node_modules/bnjs5/lib/bn.js:6:21)
    at parseBase (/home/user/dev/mm/.worktrees/metamask-mobile/deps-ethereumjs-6/node_modules/bnjs5/lib/bn.js:274:7)
    at BN._parseBase (/home/user/dev/mm/.worktrees/metamask-mobile/deps-ethereumjs-6/node_modules/bnjs5/lib/bn.js:298:14)
    at BN.init [as _init] (/home/user/dev/mm/.worktrees/metamask-mobile/deps-ethereumjs-6/node_modules/bnjs5/lib/bn.js:105:14)
    at new BN (/home/user/dev/mm/.worktrees/metamask-mobile/deps-ethereumjs-6/node_modules/bnjs5/lib/bn.js:39:12)

First steps in sorting out this larger mess:

@legobeat
Copy link
Contributor

legobeat commented Oct 25, 2024

@siibars I am trying to track down exactly where the stakedBalanceWei (assets) string gets constructed - do you have a reference handy? Is it just being piped unmodified from a server-side API?

https://github.com/MetaMask/metamask-mobile/actions/runs/11526358054/job/32090342121?pr=12010#step:5:31

FAIL app/components/UI/Stake/hooks/useBalance.test.tsx
  ● useBalance › returns balance and fiat values based on account and pooled stake data

    expect(received).toBe(expected) // Object.is equality

    Expected: "5791332670714232000"
    Received: "05791332670714232000"

      76 |     expect(result.current.balanceFiat).toBe('$39506172511.60'); // Fiat balance
      77 |     expect(result.current.balanceFiatNumber).toBe(39506172511.6); // Fiat number balance
    > 78 |     expect(result.current.stakedBalanceWei).toBe('5791332670714232000'); // No staked assets
         |                                             ^
      79 |     expect(result.current.formattedStakedBalanceETH).toBe('5.79133 ETH'); // Formatted ETH balance
      80 |     expect(result.current.stakedBalanceFiatNumber).toBe(18532.26454); // Staked balance in fiat number
      81 |     expect(result.current.formattedStakedBalanceFiat).toBe('$18532.26'); //

      at Object.toBe (app/components/UI/Stake/hooks/useBalance.test.tsx:78:45)
      at asyncGeneratorStep (node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17)
      at _next (node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9)
      at node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:7
      at Object.<anonymous> (node_modules/@babel/runtime/helpers/asyncToGenerator.js:14:12)

@amitabh94
Copy link
Contributor

@siibars I am trying to track down exactly where the stakedBalanceWei (assets) string gets constructed - do you have a reference handy? Is it just being piped unmodified from a server-side API?

https://github.com/MetaMask/metamask-mobile/actions/runs/11526358054/job/32090342121?pr=12010#step:5:31

FAIL app/components/UI/Stake/hooks/useBalance.test.tsx
  ● useBalance › returns balance and fiat values based on account and pooled stake data

    expect(received).toBe(expected) // Object.is equality

    Expected: "5791332670714232000"
    Received: "05791332670714232000"

      76 |     expect(result.current.balanceFiat).toBe('$39506172511.60'); // Fiat balance
      77 |     expect(result.current.balanceFiatNumber).toBe(39506172511.6); // Fiat number balance
    > 78 |     expect(result.current.stakedBalanceWei).toBe('5791332670714232000'); // No staked assets
         |                                             ^
      79 |     expect(result.current.formattedStakedBalanceETH).toBe('5.79133 ETH'); // Formatted ETH balance
      80 |     expect(result.current.stakedBalanceFiatNumber).toBe(18532.26454); // Staked balance in fiat number
      81 |     expect(result.current.formattedStakedBalanceFiat).toBe('$18532.26'); //

      at Object.toBe (app/components/UI/Stake/hooks/useBalance.test.tsx:78:45)
      at asyncGeneratorStep (node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17)
      at _next (node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9)
      at node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:7
      at Object.<anonymous> (node_modules/@babel/runtime/helpers/asyncToGenerator.js:14:12)

We get this as wei string from the server side API.
https://github.com/consensys-vertical-apps/va-mmcx-staking-api/blob/81718575f23d03763d8abb991a2379cf54d25041/src/metaMaskPooledStaking/metaMaskPooledStaking.controller.ts#L77

@amitabh94
Copy link
Contributor

using new BN(assets) instead of hexToBn(assets) fixes the issue.

@siibars
Copy link
Contributor Author

siibars commented Oct 28, 2024

hi @legobeat
to give you more details on where stakedBalanceWei comes from :
a. in the mobile it's populated here with 'pooledStakeData' which comes from an api server call,
b. this call is implemented in the stake-sdk here
c. The api server implementation makes call to a smart contract method 'getShares' here retrieve an share amount (uint256) and then converts it to a @ethersproject/bignumber to then converts it to a 'bignumber.js' (v9) here,
d. Finally it multiplies it here with conversion rate to get an asset amount
e. Finally Finally this server api implementation return d as a string here using BN.toString 😮

I think this hextobn util here make sense but Indeed the BN import should probably be aligned and this file should also be written in ts for more type safety at build time.

@amitabh94 I am curious about d. and e. working as expected with account with a high share amount / conversion rate with a lot of decimals, do we have tests for such cases ?

cheers

@siibars siibars added Run Smoke E2E Triggers smoke e2e on Bitrise and removed Run Smoke E2E Triggers smoke e2e on Bitrise labels Oct 28, 2024
Copy link
Contributor

github-actions bot commented Oct 28, 2024

https://bitrise.io/ Bitrise

✅✅✅ pr_smoke_e2e_pipeline passed on Bitrise! ✅✅✅

Commit hash: e74f458
Build link: https://app.bitrise.io/app/be69d4368ee7e86d/pipelines/ae02fb19-c3c0-4056-b404-8691299cde94

Note

  • You can kick off another pr_smoke_e2e_pipeline on Bitrise by removing and re-applying the Run Smoke E2E label on the pull request

@siibars siibars added Run Smoke E2E Triggers smoke e2e on Bitrise and removed Run Smoke E2E Triggers smoke e2e on Bitrise labels Oct 28, 2024
Copy link
Contributor

github-actions bot commented Oct 28, 2024

https://bitrise.io/ Bitrise

✅✅✅ pr_smoke_e2e_pipeline passed on Bitrise! ✅✅✅

Commit hash: 6060b7d
Build link: https://app.bitrise.io/app/be69d4368ee7e86d/pipelines/f6eb14ec-5783-4abe-ae44-cd100edc850d

Note

  • You can kick off another pr_smoke_e2e_pipeline on Bitrise by removing and re-applying the Run Smoke E2E label on the pull request

Copy link

sonarcloud bot commented Oct 28, 2024

@amitabh94
Copy link
Contributor

hi @legobeat to give you more details on where stakedBalanceWei comes from : a. in the mobile it's populated here with 'pooledStakeData' which comes from an api server call, b. this call is implemented in the stake-sdk here c. The api server implementation makes call to a smart contract method 'getShares' here retrieve an share amount (uint256) and then converts it to a @ethersproject/bignumber to then converts it to a 'bignumber.js' (v9) here, d. Finally it multiplies it here with conversion rate to get an asset amount e. Finally Finally this server api implementation return d as a string here using BN.toString 😮

I think this hextobn util here make sense but Indeed the BN import should probably be aligned and this file should also be written in ts for more type safety at build time.

@amitabh94 I am curious about d. and e. working as expected with account with a high share amount / conversion rate with a lot of decimals, do we have tests for such cases ?

cheers

We will have to check whether if we have specific test cases for decimals but what I know is that we use bignumber.js in Staking api which is used to deal with big numbers with decimal places.

@siibars siibars added this pull request to the merge queue Oct 28, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Oct 28, 2024
@siibars siibars added this pull request to the merge queue Oct 28, 2024
github-merge-queue bot pushed a commit that referenced this pull request Oct 28, 2024
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**
There is a bignumber conversion attempt which is failing, this change
fixes this.

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

## **Related issues**

Fixes: STAKE-848

## **Manual testing steps**

1. connect with an account with a high ETH balance 
2. enable the native staking feature flag
3. click stake to get to the StakeinputView
 

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

![image](https://github.com/user-attachments/assets/bd071444-a6b6-49ca-ae31-4339ebcc68e6)

View: Root
Error: [number-to-bn] while converting number
"3.487400189415765903484e+21" to BN.js instance, error: invalid number
value. Value must be an integer, hex string, BN or BigNumber instance.
Note, decimals are not supported.

### **After**

This issue doesn't happen. 

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [x] I’ve followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [x] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [x] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

---------

Co-authored-by: legobeat <[email protected]>
Merged via the queue into main with commit e96777a Oct 28, 2024
43 checks passed
@siibars siibars deleted the fix/bignumber-conversion-error branch October 28, 2024 15:22
@github-actions github-actions bot locked and limited conversation to collaborators Oct 28, 2024
@metamaskbot metamaskbot added the release-7.35.0 Issue or pull request that will be included in release 7.35.0 label Oct 28, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Priority - Medium Task with medium priority release-7.35.0 Issue or pull request that will be included in release 7.35.0 Run Smoke E2E Triggers smoke e2e on Bitrise team-stake
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

6 participants