Beatland Festival

First Flight #44
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Severity: medium
Valid

Off‑By‑One in `redeemMemorabilia()` leads to Supply Underflow

Off‑By‑One in redeemMemorabilia() leads to Supply Underflow

Description

  • The redeemMemorabilia function allows users to redeem memorabilia NFTs from a collection, incrementing currentItemId after each redemption.

  • The function checks collection.currentItemId < collection.maxSupply, but since currentItemId starts at 1, the last item (when currentItemId == maxSupply) can never be redeemed.

function redeemMemorabilia(uint256 collectionId) external {
MemorabiliaCollection storage collection = collections[collectionId];
require(collection.priceInBeat > 0, "Collection does not exist");
require(collection.isActive, "Collection not active");
@> require(collection.currentItemId < collection.maxSupply, "Collection sold out");
// ... mint logic ...
uint256 itemId = collection.currentItemId++;
// ...
}

Risk

Likelihood:

  • This will occur every time a collection is created and users attempt to redeem the last available item.

  • The last item in every collection will be unredeemable.

Impact:

  • Users will be unable to redeem the full advertised supply of memorabilia.

  • The actual supply will always be one less than intended, leading to user confusion and potential loss of value.

Proof of Concept

  1. Create a collection with maxSupply = 10

  2. Redeem 9 items (currentItemId goes from 1 to 10)

  3. Attempt to redeem the 10th item: require fails, even though maxSupply is 10

// maxSupply = 10
for (uint i = 0; i < 10; i++) {
festivalPass.redeemMemorabilia(collectionId);
} // The 10th call reverts

Recommended Mitigation

- require(collection.currentItemId < collection.maxSupply, "Collection sold out");
+ require(collection.currentItemId <= collection.maxSupply, "Collection sold out");

Use <= instead of < to make sure this does not occur.

Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 month ago
Submission Judgement Published
Validated
Assigned finding tags:

Off by one error in redeemMemorabilia

Support

FAQs

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