fix(assets-controller): implement spam asset cleanup functionality - #9973
fix(assets-controller): implement spam asset cleanup functionality#9973Prithpal-Sooriya wants to merge 26 commits into
Conversation
Adds spam cleanup for users. This is because our external sources can fail and add in spam: - API filters can loosen, and add in spam tokens. - WS has no filtering right now, so airdrops are added to the wallet. This safeguards ourselves by adding additional cleanup on startup/unlock. We need a longer term discussion & decision with Assets team to highlight this cleanup issue and building a trustless system.
|
@metamaskbot publish-preview |
|
Preview builds have been published. Learn how to use preview builds in other projects. Expand for full list of packages and versions. |
…)/add-asset-cleanup-process-on-unlock Co-authored-by: Cursor <cursoragent@cursor.com> # Conflicts: # packages/assets-controller/CHANGELOG.md
|
@metamaskbot publish-preview |
|
@cursor /babysit fix CI |
- Add unit tests for cleanSpamAssets covering candidate filtering, spam removal, API failures, and occurrence floor fallback - Add AssetsController integration tests for unlock-triggered cleanup - Fix import order in healAssetsInfoMetadata.ts for lint:misc:check Co-authored-by: Prithpal Sooriya <prithpal.sooriya@gmail.com>
|
Preview builds have been published. Learn how to use preview builds in other projects. Expand for full list of packages and versions. |
Co-authored-by: Prithpal Sooriya <prithpal.sooriya@gmail.com>
- Unit test via healAssetsInfoMetadata.test.ts - More ingrained integration test via AssetsController.spam-cleanup.test.ts Also created some test mocks and utils via __fixtures__
There were small changes made to mocks... meh not a big deal.
Co-authored-by: Prithpal Sooriya <prithpal.sooriya@gmail.com>
… cleanup The previous implementation of #runSpamCleanup would replace the assetsInfo and assetsBalance state wholesale with a snapshot taken before awaiting the Token API. This caused any legitimate updates to those state slices that occurred concurrently to be dropped. This commit updates the logic to compute the set of removed spam assets and delete only those specific assets from the current state, preserving any concurrent additions or modifications. Co-authored-by: Cursor <cursoragent@cursor.com>
…ock' of github.com:MetaMask/core into fix(assets-controller)/add-asset-cleanup-process-on-unlock
- Re-apply selective spam deletion in #runSpamCleanup so concurrent state updates during the Token API await are not overwritten - Bump eslint suppression count for AssetsController stateChange usage - Fix formatting in spam-cleanup test file Co-authored-by: Prithpal Sooriya <prithpal.sooriya@gmail.com>
…date Mutate the Immer draft in place with type assertions instead of spreading assetsInfo/assetsBalance, matching the pattern used in handleAssetsUpdate. Co-authored-by: Prithpal Sooriya <prithpal.sooriya@gmail.com>
This was an edge-case caught from E2E tests on clients.
…ock' of github.com:MetaMask/core into fix(assets-controller)/add-asset-cleanup-process-on-unlock
Trigger spam cleanup when UI, keyring, and account-tree preconditions are first satisfied, not only on unlock. Update spam-cleanup tests to activate the full lifecycle and relax assertions affected by concurrent tracking. Co-authored-by: Prithpal Sooriya <prithpal.sooriya@gmail.com>
…ock' of github.com:MetaMask/core into fix(assets-controller)/add-asset-cleanup-process-on-unlock
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit c2d9d46. Configure here.
|
@metamaskbot publish-preview |
|
Preview builds have been published. Learn how to use preview builds in other projects. Expand for full list of packages and versions. |
|
@cursor fix linting only thx |
|
Fixed the Formatted 3 files:
No logic changes — formatting only. CI should pass lint on the next run. |
Co-authored-by: Prithpal Sooriya <prithpal.sooriya@gmail.com>
…ock' of github.com:MetaMask/core into fix(assets-controller)/add-asset-cleanup-process-on-unlock
|
@metamaskbot publish-preview |
|
Preview builds have been published. Learn how to use preview builds in other projects. Expand for full list of packages and versions. |



Explanation
Adds spam cleanup for users. This is additional filtering to ensure we are protected if any external system adds in spam (WS, API, Migration).
This is because our external sources can fail and add in spam:
This safeguards ourselves by adding additional cleanup on startup/unlock. We need a longer term discussion & decision with Assets team to highlight this cleanup issue and building a trustless system.
Builds:
Code Walkthrough:
https://www.loom.com/share/7c60194c8be44a6c8d1e7ee8dc559ae7
References
https://consensyssoftware.atlassian.net/browse/ASSETS-3905
Checklist
Note
Medium Risk
Unlock-time logic mutates persisted
assetsInfoand balances from Token API heuristics, so misclassification could hide legitimate ERC-20s until the flag is disabled or lists update.Overview
AssetsController now runs a spam-token sweep when the wallet unlocks, before normal asset tracking resumes. The flow calls
cleanSpamAssets, which queries MetaMask’s Token/Tokens APIs for suggested occurrence floors and per-token occurrence counts, then drops sweepable ERC-20s that sit below the chain floor fromassetsInfoandassetsBalancewhile leaving natives, non-EVM assets, default-tracked tokens (e.g. mUSD), andcustomAssetsalone.The behavior is off by default unless remote flags set
assetsUnifyState.useUnlockCleanuptotrue, and it also requires basic functionality and an unlocked keyring. Failures are logged or reported viacaptureExceptionwithout blocking unlock; state is left unchanged if the API fails.The PR adds
isUnlockCleanupEnabled, wires#runSpamCleanupinto theKeyringController:unlocksubscription, documents the fix in the changelog, and addsnock-based HTTP tests (unit, controller E2E, and integration against captured real API responses), plus expanded mock messenger helpers for these scenarios.Reviewed by Cursor Bugbot for commit db4b816. Bugbot is set up for automated code reviews on this repo. Configure here.