# [M-2] Inefficient User Memorabilia Enumeration leads to Denial of Service Risk
## Description
- Normally, view functions should be **efficient** and not risk **out-of-gas** errors.
- The `getUserMemorabiliaDetailed` function loops over **all collections** and **all items** in each collection, which can cause **out-of-gas** errors if there are many items or collections.
```javascript
function getUserMemorabiliaDetailed(address user)
external
view
returns (uint256[] memory tokenIds, uint256[] memory collectionIds, uint256[] memory itemIds)
{
uint256 count = 0;
for (uint256 cId = 1; cId < nextCollectionId; cId++) {
for (uint256 iId = 1; iId < collections[cId].currentItemId; iId++) {
uint256 tokenId = encodeTokenId(cId, iId);
if (balanceOf(user, tokenId) > 0) {
count++;
}
}
}
...
for (uint256 cId = 1; cId < nextCollectionId; cId++) {
for (uint256 iId = 1; iId < collections[cId].currentItemId; iId++) {
uint256 tokenId = encodeTokenId(cId, iId);
if (balanceOf(user, tokenId) > 0) {
tokenIds[index] = tokenId;
collectionIds[index] = cId;
itemIds[index] = iId;
index++;
}
}
}
...
}
```
## Risk
### Likelihood
* This will occur when the number of **collections or items per collection grows large**.
* Any user with a **large number of memorabilia tokens** may be unable to call this function due to gas limits.
### Impact
* Users may be **unable to retrieve** their memorabilia details on-chain.
* **Off-chain services** relying on this function may fail or **be unable to serve users**.
---
## Proof of Concept
- Deploy the contract with **1000 collections**, each containing **1000 items**.
- Calling `getUserMemorabiliaDetailed` will **revert due to out-of-gas**.
---
## Recommended Mitigation
Track user-owned memorabilia via a mapping or emit events and recommend **off-chain indexing** for efficient enumeration.
```diff
- for (uint256 cId = 1; cId < nextCollectionId; cId++) {
- for (uint256 iId = 1; iId < collections[cId].currentItemId; iId++) {
- uint256 tokenId = encodeTokenId(cId, iId);
- if (balanceOf(user, tokenId) > 0) {
- count++;
- }
- }
- }
+ // Option 1: Maintain a mapping from user to owned memorabilia token IDs on mint/burn
+ // Option 2: Recommend off-chain indexing using events for enumeration
```
---