Project

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

Tier removal in `MembershipFactory::updateDAOMembership` breaks token tracking and profit distribution

Summary

MembershipFactory::updateDAOMembership allows removing tiers without checking for existing tokens, leading to lost token tracking and broken profit distribution calculations.

Vulnerability Details

During the tier removal process in MembershipFactory::updateDAOMembership, there's no validation of existing tokens in tiers being removed. Minted tokens remain in ERC1155 contract, and DAO configuration loses track of them after removal.

Profit distribution calculation uses tier-based weighting (2^(6-tier)), and the removed tiers' tokens still contribute to total supply, leading to incorrect weight calculations.

Impact

Token tracking becomes inconsistent, leading to:

  • Minted tokens in removed tiers still exist in ERC1155 contract, but DAO configuration loses track of them

  • Total supply calculations become incorrect

  • Profit distribution weights become inaccurate

Proof of Concept

Let's assume the following scenario:

  • DAO has 3 tiers: 0, 1, 2

    • 50 tokens minted for tier 0

    • 30 tokens minted for tier 1

    • 20 tokens minted for tier 2

  • Admin removes tier 2

  • 20 tokens from tier 2 are left behind in the ERC1155 contract, accounted for in total supply and profit distribution is now wrong

    • Total supply is off by 20 * 2^(6-2) = 320 weight units

MembershipFactory.sol#L114-L118

function updateDAOMembership(string calldata ensName, TierConfig[] memory tierConfigs)
external onlyRole(EXTERNAL_CALLER) returns (address) {
// existing code...
// Preserve minted values and adjust the length of dao.tiers
for (uint256 i = 0; i < tierConfigs.length; i++) {
if (i < dao.tiers.length) {
@> tierConfigs[i].minted = dao.tiers[i].minted;
}
}
// existing code...
}

Tools Used

Manual Review

Recommended Mitigation Steps

Add a check to ensure no tokens are left behind in removed tiers:

function updateDAOMembership(string calldata ensName, TierConfig[] memory tierConfigs)
external
onlyRole(EXTERNAL_CALLER)
returns (address)
{
// existing code...
+ // Check no tokens exist in tiers being removed
+ for (uint256 i = tierConfigs.length; i < dao.tiers.length; i++) {
+ require(dao.tiers[i].minted == 0, "Cannot remove tier with existing tokens");
+ if (i < dao.tiers.length) {
+ tierConfigs[i].minted = dao.tiers[i].minted;
+ }
}
// existing code...
}
Updates

Lead Judging Commences

0xbrivan2 Lead Judge
12 months ago
0xbrivan2 Lead Judge 12 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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