Project

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

Due to missing check members amount could exceed tier capacity

Summary

There are two ways users could become members to the desired tier:

  1. Via purchasing tier via joinDAO for desired tier

  2. By upgrading from lower tier to higher via upgradeTier

The joinDAO already have protective methods to not allow tier capacity to be exceeded:

require(daos[daoMembershipAddress].noOfTiers > tierIndex, "Invalid tier.");
require(daos[daoMembershipAddress].tiers[tierIndex].amount > daos[daoMembershipAddress].tiers[tierIndex].minted, "Tier full.");

Vulnerability Details

The issue arise in upgradeTier that looks like this:

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);
}

The upgradeTier does not check if the desired tier reached its capacity or not.
This missing check will lead to tier capacity limit to be exceeded.

PoC:
Lets say member of tier 5 wants to upgrade to tier 4. Tier 4 is already reached its capacity (capacity will be 100 for the sake of example) before the upgrade happened.
Now after passing the checks the function burn 2 tokens from the tier 5 and mint 1 token for tier 4.
But because it never checks if the tier 4 reached its capacity it will mint token anyway.
So now the total would be 101/100 which will exceed tier limit.

Impact

Tier limit capacity will be exceeded

Tools Used

Manual Review

Recommendations

Change the design of upgradeTier to correctly check and update availability of tiers like this:

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.");
+ require(daos[daoMembershipAddress].tiers[fromTierIndex - 1].amount > daos[daoMembershipAddress].tiers[fromTierIndex - 1].minted, "Tier full.");
+ daos[daoMembershipAddress].tiers[fromTierIndex].minted -= 2;
+ daos[daoMembershipAddress].tiers[fromTierIndex - 1].minted += 1;
IMembershipERC1155(daoMembershipAddress).burn(_msgSender(), fromTierIndex, 2);
IMembershipERC1155(daoMembershipAddress).mint(_msgSender(), fromTierIndex - 1, 1);
emit UserJoinedDAO(_msgSender(), daoMembershipAddress, fromTierIndex - 1);
}
Updates

Lead Judging Commences

0xbrivan2 Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Known issue

Support

FAQs

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