-
-
Notifications
You must be signed in to change notification settings - Fork 199
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: handle multicall revert in TokenBalancesController
#5083
Conversation
!error || | ||
typeof error !== 'object' || | ||
!('code' in error) || | ||
error.code !== 'CALL_EXCEPTION' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like a complicated condition. Could you elaborate a bit on your code comment on line 404 to better explain what these conditions represent?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trying to only retry if the call reverted, and not retry on other kinds of errors that could occur. I don't know exactly what I expect those errors to be, but could be like a dead rpc connection or something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approved, but could you elaborate a bit on your if
condition before merging plz?
## **Description** Fixes an issue where erc20 token balances were incorrectly showing 0. On the repro we have, we noticed a token in state with address `0x0000000000000000000000000000000000000000` on mainnet, which is not a valid erc20 token. This caused the multicall to revert, preventing other balances from updating. There's a fix in the controller here: MetaMask/core#5083 which will fall back to parallel `balanceOf` calls if the multicall reverts. And we're also doing a migration here to remove zero address tokens on mainnet. [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/29361?quickstart=1) ## **Related issues** ## **Manual testing steps** The current version of the wallet should not allow importing an invalid erc20 address through any mechanism, so not easy to reproduce naturally. The migration can be tested by checking out an older version like `git checkout v12.9.0 `, upgrading to this branch, verifying the migration ran in background logs, and that your tokens remain. ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I’ve included tests if applicable - [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **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.
Fixes an issue where erc20 token balances were incorrectly showing 0. On the repro we have, we noticed a token in state with address `0x0000000000000000000000000000000000000000` on mainnet, which is not a valid erc20 token. This caused the multicall to revert, preventing other balances from updating. There's a fix in the controller here: MetaMask/core#5083 which will fall back to parallel `balanceOf` calls if the multicall reverts. And we're also doing a migration here to remove zero address tokens on mainnet. [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/29361?quickstart=1) The current version of the wallet should not allow importing an invalid erc20 address through any mechanism, so not easy to reproduce naturally. The migration can be tested by checking out an older version like `git checkout v12.9.0 `, upgrading to this branch, verifying the migration ran in background logs, and that your tokens remain. <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> <!-- [screenshots/recordings] --> <!-- [screenshots/recordings] --> - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I’ve included tests if applicable - [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. - [ ] 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.
Explanation
When fetching erc20 token balances via the multicall3 contract, there's a case where the call can revert. Even though we pass
requireSuccess=false
totryAggregate
, this does not catch all errors. Specifically, trying to execute code on a target address that is not a smart contract.There were some cases where users had tokens added with address
0x0000000000000000000000000000000000000000
which caused such a revert, preventing balances fetches from other tokens.In addition to migrating out of state tokens we can detect as invalid, the fix here is to fallback to parallel
balanceOf
calls if the multicall request reverts.References
Changelog
@metamask/assets-controllers
TokenBalancesController
was fixed to fetch erc20 token balances even if there's an invalid token in state whose address does not point to a smart contract.Checklist