Beatland Festival

First Flight #44
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Impact: medium
Likelihood: medium
Invalid

Unbounded Loops in getUserMemorabiliaDetailed Can Lead to Out-of-Gas Errors.

Unbounded Loops in getUserMemorabiliaDetailed Can Lead to Out-of-Gas Errors

Description

  • In FestivalPass::``getUserMemorabiliaDetailed, anyone can call this fucntion for a specific address/user to get the all the memorabilia tokens owner by user with their specific details.

  • The issue is that this function uses 4 unbounded loopwith no restiction over the loop iterations which may cause OUT OF GAS

  • The 4 loops are bounded by nextCollectionIdand currentItemIdfor a specific collection, so as these two value continue to increase, the out of gas will be reached.


function getUserMemorabiliaDetailed(address user) external view returns (
uint256[] memory tokenIds,
uint256[] memory collectionIds,
uint256[] memory itemIds
) {
// First, count how many memorabilia they own
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++;
}
}
}
// Then populate arrays
tokenIds = new uint256[](count);
collectionIds = new uint256[](count);
itemIds = new uint256[](count);
uint256 index = 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) {
tokenIds[index] = tokenId;
collectionIds[index] = cId;
itemIds[index] = iId;
index++;
}
}
}

Risk

Likelihood:

  • As the time goes and more collection are addeed to increase the collectionId and more redeems are done to increase the currantItemId, the out-of-gas state will be reached.

  • The risk increase as more collection are created and items are redeemed.

Impact:

  • Broken Functionality: Due to unbounded loops, neither the user nor any other address can successfully call getUserMemorabiliaDetailed to retrieve data for a specific user once the data size exceeds a certain threshold.

  • Gas Griefing Risk: The function may consume all provided gas and revert, leading to out-of-gas errors. This exposes users to gas griefing, where repeated attempts to access their data result in wasted gas and failed transactions.

Proof of Concept

  1. FestivalPass contract is deployed and organizer is set

  2. organizer start to create memorabnilia collection with specific maxSupply

  3. Users start to attend, get beatToken, and redeem them for an item in specific memorabilia collection.

  4. Afther sometime, the bounds of the loop in getMemorabiliaDetailedwill grow to a point when calling the function will cause out-of-gas error.

Recommended Mitigation

  • Implement the function without having unbounded loops.

Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 month ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.