Project

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

Tier Minted Value Not Validated During DAO Membership Upgrade

Summary

The upgradeTier function in MembershipFactory contract does not validate whether the source tier's minted value is sufficient for burning tokens. While this does not lead to a security vulnerability due to ERC1155's built-in balance checks, it highlights a potential inconsistency in tier accounting validation.

Vulnerability Details

The upgradeTier function in MembershipFactory contract processes tier upgrades by burning tokens from a source tier without validating the tier's minted value:

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

Before burning tokens, it would be more consistent to verify tiers[fromTierIndex].minted >= 2 even though:

  1. The ERC1155's burn operation provides inherent safety:

// From MembershipERC1155
function burn_(address from, uint256 tokenId, uint256 amount) internal {
totalSupply -= amount * 2 ** (6 - tokenId);
_burn(from, tokenId, amount); // Will revert if balance insufficient
}
  1. The operation will safely revert if the user's balance is insufficient, making this an issue of validation consistency rather than security.

This represents a pattern inconsistency when compared with the diligent validation in joinDAO:

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.");
// ... rest of the function
}

Impact

The lack of explicit tier minted value validation has minimal practical impact:

  1. No Security Risk:

  • ERC1155's built-in balance checks prevent any unauthorized token burns

  • The operation will safely revert if a user attempts to burn more tokens than they own

  • No possibility of token theft or unauthorized operations

  1. Code Pattern Inconsistency:

  • Different validation approaches between joinDAO and upgradeTier functions

  • Could make future maintenance and auditing more challenging

  • May cause confusion about validation responsibilities between factory and token contracts

  1. Developer Experience:

  • Error messages are less specific (ERC1155 balance errors vs. clear tier validation messages)

  • Makes debugging slightly more difficult as errors come from token contract rather than business logic layer

The impact is purely organizational and relates to code quality rather than security or functionality.

Recommendations

For consistency with other validation patterns, consider adding tier minted value validation:

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].minted >= 2, "Insufficient minted tokens in source tier");
IMembershipERC1155(daoMembershipAddress).burn(_msgSender(), fromTierIndex, 2);
IMembershipERC1155(daoMembershipAddress).mint(_msgSender(), fromTierIndex - 1, 1);
emit UserJoinedDAO(_msgSender(), daoMembershipAddress, fromTierIndex - 1);
}

This change would:

  1. Maintain consistent validation patterns across the codebase

  2. Provide clearer error messages at the business logic layer

  3. Make validation responsibility explicit in the factory contract

Updates

Lead Judging Commences

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

Support

FAQs

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