fix: batch NFT ownership checks via Multicall3#8281
Conversation
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
| return acc; | ||
| }, | ||
| [], | ||
| ); |
There was a problem hiding this comment.
Undefined standard silently skips NFT ownership checks
Medium Severity
The filter to exclude NFTs with unrecognized standards (hasExplicitNonStandard) incorrectly treats undefined the same as an explicitly unrecognized standard like "UNKNOWN". NftMetadata.standard can be undefined at runtime (e.g., NFTs from the API when kind is falsy, or older persisted state), even though TypeScript types it as string | null. Since undefined !== null is true and normalizeNftStandard(undefined) returns null, these NFTs are silently excluded from ownership checks — they'll never be marked as no-longer-owned. The guard nft.standard !== null needs to also account for undefined (e.g., nft.standard != null using loose equality).


Explanation
AssetsContractControllermessenger calls (getERC721OwnerOf,getERC1155BalanceOf) with a newgetNftOwnershipForMultipleNftsutility that batches ERC-721ownerOfand ERC-1155balanceOfcalls through Multicall3'saggregate3, falling back to individual RPC calls on unsupported chains or when multicall fails.checkAndUpdateSingleNftOwnershipStatusin favor ofcheckAndUpdateAllNftsOwnershipStatus, which now batches all NFTs in a single pass.standardparameter toisNftOwnerso callers that already know the token standard skip redundant subcalls.Breaking Changes
checkAndUpdateSingleNftOwnershipStatusremoved — usecheckAndUpdateAllNftsOwnershipStatusinstead.AllowedActionsnarrowed —AssetsContractController:getERC721OwnerOfandAssetsContractController:getERC1155BalanceOfare no longer required byNftController's messenger. Consumers constructing the messenger must remove these from their allowed actions list.References
https://consensyssoftware.atlassian.net/browse/ASSETS-2959
Checklist
Note
Medium Risk
Changes NFT ownership verification paths (
watchNft,isNftOwner, and ownership-status refresh) to use a new batching utility and different RPC/provider plumbing, which could affect correctness on edge-case contracts and unsupported chains despite fallbacks and added tests.Overview
NftControllernow batches ERC-721ownerOfand ERC-1155balanceOfownership checks via Multicall3 (with per-call fallback to individual RPC calls), reducing RPC request volume and adding an optionalstandardhint to skip redundant subcalls.This removes the
AssetsContractController:getERC721OwnerOf/getERC1155BalanceOfmessenger dependencies (and deletescheckAndUpdateSingleNftOwnershipStatus), updatingcheckAndUpdateAllNftsOwnershipStatusand tests to rely on the newgetNftOwnershipForMultipleNftshelper, including handling for explicitly unknown-standard NFTs that would otherwise break multicall batches.Written by Cursor Bugbot for commit 10d305c. This will update automatically on new commits. Configure here.