Project

One World
NFTDeFi
15,000 USDC
View results
Submission Details
Severity: medium
Invalid

The `minted` value is prone to errors when a burn occurs

Summary

When a DAO NFT is minted using MembershipFactory::joinDAO(), the corresponding tier minted value is incremented.

This variable is used to account for the number of NFTs minted in a particular tier.

Each tier has a limited number of NFTs that can be minted which is stored in a tier amount.

When attempting to MembershipFactory::joinDAO() the function ensures this limit is not reached.

https://github.com/Cyfrin/2024-11-one-world/blob/main/contracts/dao/MembershipFactory.sol#L145

function joinDAO(address daoMembershipAddress, uint256 tierIndex) external {
require(daos[daoMembershipAddress].noOfTiers > tierIndex, "Invalid tier.");
@> require(daos[daoMembershipAddress].tiers[tierIndex].amount > daos[daoMembershipAddress].tiers[tierIndex].minted, "Tier full.");
uint256 tierPrice = daos[daoMembershipAddress].tiers[tierIndex].price;
uint256 platformFees = (20 * tierPrice) / 100;
@> daos[daoMembershipAddress].tiers[tierIndex].minted += 1;
IERC20(daos[daoMembershipAddress].currency).transferFrom(_msgSender(), owpWallet, platformFees);
IERC20(daos[daoMembershipAddress].currency).transferFrom(_msgSender(), daoMembershipAddress, tierPrice - platformFees);
IMembershipERC1155(daoMembershipAddress).mint(_msgSender(), tierIndex, 1);
emit UserJoinedDAO(_msgSender(), daoMembershipAddress, tierIndex);
}

The lifecycle of a DAO implies some NFTs to be burnt specifically when upgradeTier() is used on a sponsored DAO.

This can also occur by executing an arbitrary MembershipERC1155::burn() through MembershipFactory::executeExternalCall() or other set of calls from privileged addresses which is however not likely.

However when this occurs, the minted value is not decreased. This happens in upgradeTier() where 2 NFTs of a tier are burnt (meaning the tier's minted should be reduced by 2) and 1 NFT of a better tier is minted (meaning the tier's minted should be increased by 1).

https://github.com/Cyfrin/2024-11-one-world/blob/main/contracts/dao/MembershipFactory.sol#L155-L161

function upgradeTier(address daoMembershipAddress, uint256 fromTierIndex) external {
require(daos[daoMembershipAddress].daoType == DAOType.SPONSORED, "Upgrade not allowed.");
require(daos[daoMembershipAddress].noOfTiers >= fromTierIndex + 1, "No higher tier available.");
@> IMembershipERC1155(daoMembershipAddress).burn(_msgSender(), fromTierIndex, 2);
@> IMembershipERC1155(daoMembershipAddress).mint(_msgSender(), fromTierIndex - 1, 1);
emit UserJoinedDAO(_msgSender(), daoMembershipAddress, fromTierIndex - 1);
}

This can be problematic because the minted value is not maintained correctly.

Impact

  1. Limits the actual number of NFTs that can be held due to minted not being decreased. This results in amount being exceeded by minted at a faster pace than intended

  2. The tier's minted value can be flawed and inconsistent with the circulating supply

Recommandation

Systematically update the minted value when a tier NFT is minted/burnt

Updates

Lead Judging Commences

0xbrivan2 Lead Judge 12 months ago
Submission Judgement Published
Invalidated
Reason: Out of scope

Appeal created

greed Submitter
12 months ago
0xbrivan2 Lead Judge
11 months ago
greed Submitter
11 months ago
0xbrivan2 Lead Judge 11 months ago
Submission Judgement Published
Invalidated
Reason: Out of scope

Support

FAQs

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