Project

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

Missing Capacity Check in Tier Upgrade Function

Summary

The upgradeTier function in the MembershipFactory contract allows users to upgrade their tier membership without verifying if there's available space in the target tier. While it checks if a higher tier exists, it fails to validate if that tier has reached its capacity, potentially leading to tier overflow issues.

Vulnerability Details

In the upgradeTier function, there is a check to ensure the target tier exists, but unlike the joinDAO function, it doesn't verify if the target tier has available capacity:

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.");
// Missing check for tier capacity
IMembershipERC1155(daoMembershipAddress).burn(_msgSender(), fromTierIndex, 2);
IMembershipERC1155(daoMembershipAddress).mint(_msgSender(), fromTierIndex - 1, 1);
emit UserJoinedDAO(_msgSender(), daoMembershipAddress, fromTierIndex - 1);
}

For comparison, the joinDAO function properly implements this check:

function joinDAO(address daoMembershipAddress, uint256 tierIndex) external {
@> require(daos[daoMembershipAddress].tiers[tierIndex].amount >
daos[daoMembershipAddress].tiers[tierIndex].minted, "Tier full.");
// ... rest of the function
}

Impact

The lack of capacity checking in upgradeTier can lead to several issues:

  1. Tiers can exceed their intended maximum capacity

  2. DAO governance power could be incorrectly distributed

  3. Violation of the DAO's membership structure and rules

Tools Used

  • Manual code review

Exploit Scenario

  1. A DAO is created with the following tier structure:

    • Tier 5: Capacity of 100 members

    • Tier 4: Capacity of 50 members (higher tier with more privileges)

  2. Initial state:

    • Tier 5 has 50 members

    • Tier 4 is at capacity (50 members)

  3. Attack path:

    - User gets 2 tokens in Tier 5
    - User calls upgradeTier to move to Tier 4
    - Transaction succeeds despite Tier 4 being full
    - Tier 4 now exceeds its intended capacity
  4. Result:

    • Tier 4 now has 51 members, exceeding its maximum capacity of 50

    • This breaks the tier structure design and the DAO's tokenomics

Recommended Mitigation

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.");
+ uint256 targetTierIndex = fromTierIndex - 1;
+ require(
+ daos[daoMembershipAddress].tiers[targetTierIndex].amount >
+ daos[daoMembershipAddress].tiers[targetTierIndex].minted,
+ "Target tier is full"
+ );
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 about 1 year ago
Submission Judgement Published
Invalidated
Reason: Known issue

Support

FAQs

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

Give us feedback!