Commit d148dd7
authored
fix: batch NFT ownership checks via Multicall3 (#8281)
## Explanation
- Replace individual `AssetsContractController` messenger calls
(`getERC721OwnerOf`, `getERC1155BalanceOf`) with a new
`getNftOwnershipForMultipleNfts` utility that batches ERC-721 `ownerOf`
and ERC-1155 `balanceOf` calls through Multicall3's `aggregate3`,
falling back to individual RPC calls on unsupported chains or when
multicall fails.
- Remove `checkAndUpdateSingleNftOwnershipStatus` in favor of
`checkAndUpdateAllNftsOwnershipStatus`, which now batches all NFTs in a
single pass.
- Add an optional `standard` parameter to `isNftOwner` so callers that
already know the token standard skip redundant subcalls.
- `checkAndUpdateAllNftsOwnershipStatus` now removes NFTs confirmed as
unowned from state rather than retaining them with `isCurrentlyOwned:
false`. The "Previously Owned" NFT feature this flag powered is no
longer supported.
**Breaking Changes**
- **`checkAndUpdateSingleNftOwnershipStatus` removed** — use
`checkAndUpdateAllNftsOwnershipStatus` instead.
- **`AllowedActions` narrowed** —
`AssetsContractController:getERC721OwnerOf` and
`AssetsContractController:getERC1155BalanceOf` are no longer required by
`NftController`'s messenger. Consumers constructing the messenger must
remove these from their allowed actions list.
<!--
Thanks for your contribution! Take a moment to answer these questions so
that reviewers have the information they need to properly understand
your changes:
* What is the current state of things and why does it need to change?
* What is the solution your changes offer and how does it work?
* Are there any changes whose purpose might not obvious to those
unfamiliar with the domain?
* If your primary goal was to update one package but you found you had
to update another one along the way, why did you do so?
* If you had to upgrade a dependency, why did you do so?
-->
## References
Ticket: https://consensyssoftware.atlassian.net/browse/ASSETS-2959
PR on Mobile: MetaMask/metamask-mobile#28655
PR on Extension:
<!--
Are there any issues that this pull request is tied to?
Are there other links that reviewers should consult to understand these
changes better?
Are there client or consumer pull requests to adopt any breaking
changes?
For example:
* Fixes #12345
* Related to #67890
-->
## 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](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md)
- [ ] I've introduced [breaking
changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md)
in this PR and have prepared draft pull requests for clients and
consumer packages to resolve them
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Medium risk due to breaking API surface (`AllowedActions` narrowed,
`checkAndUpdateSingleNftOwnershipStatus` removed) and changed state
semantics (unowned NFTs are deleted), plus new multicall batching logic
that could affect ownership determination across networks.
>
> **Overview**
> **NFT ownership checks are refactored to batch on-chain calls via
Multicall3.** `NftController.isNftOwner` and
`checkAndUpdateAllNftsOwnershipStatus` now use the new
`getNftOwnershipForMultipleNfts` helper to aggregate ERC-721 `ownerOf` /
ERC-1155 `balanceOf` calls (with fallback to individual calls when
multicall/chain support is unavailable), and callers can pass an
optional `standard` to skip unnecessary subcalls.
>
> **Breaking behavior changes:**
`AssetsContractController:getERC721OwnerOf` and
`AssetsContractController:getERC1155BalanceOf` are removed from
`NftController` `AllowedActions`,
`checkAndUpdateSingleNftOwnershipStatus` is removed, and ownership
refresh now **removes NFTs confirmed as unowned** from state instead of
setting `isCurrentlyOwned: false`. Tests and changelog are updated
accordingly, and `multicall` gains comprehensive coverage for the new
NFT ownership batching utility.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
f782f90. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->1 parent 93b8bc4 commit d148dd7
5 files changed
Lines changed: 894 additions & 443 deletions
File tree
- packages/assets-controllers
- src
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
12 | 19 | | |
13 | 20 | | |
14 | 21 | | |
| |||
0 commit comments