getUserMemorabiliaDetailed performs a nested loop over every collection (1..nextCollectionId) and every item ever minted in each (1..currentItemId), calling balanceOf for each. The cost grows with all historical state, not with the user's holdings, so any on-chain consumer will eventually exceed the block gas limit and revert, even for a user who owns nothing. The loop also wastes 99 iterations on the reserved gap between pass IDs (1-3) and the first memorabilia collection ID (100).
The same double loop is repeated a second time to populate the arrays (:284-294), doubling the cost. Collections start at nextCollectionId = 100 (:20), so cId = 1..99 are empty but still iterated.
Likelihood: Low. It does not affect the core protocol, only eth_call/on-chain integrators; an off-chain caller can raise the gas cap. It only becomes a hard failure on-chain after enough items are minted.
Impact: On-chain consumers (airdrops, marketplace listings, indexers that call on-chain) revert as the collection catalogue grows, degrading composability. No user funds are locked.
The test mints one item into each of N = 150 collections and measures the gas of getUserMemorabiliaDetailed for a wallet that owns nothing. The measured cost is ~938,645 gas at 150 items, rising roughly linearly; at ~5,000 minted items a single on-chain call exceeds a 30M block gas limit. This demonstrates the loop is bounded by total state rather than by the user's balance.
Track owned token IDs per user (e.g., an enumerable set or tokenId => owner index updated on mint/transfer) and return those directly, so cost scales with the user's holdings. At minimum, start the collection loop at the first real collection ID (100) to remove the wasted range.
The contest is live. Earn rewards by submitting a finding.
Submissions are being reviewed by our AI judge. Results will be available in a few minutes.
View all submissionsThe contest is complete and the rewards are being distributed.