Project

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

DAO Platform Fee Bypass Through Zero-Price Tiers

Summary

MembershipFactory contract allows DAO creators to bypass platform fees by setting zero prices for tiers while collecting payments off-chain, undermining the platform's revenue model.

Vulnerability Details

The joinDAO function calculates platform fees as a percentage of the tier price without enforcing minimum pricing:

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.");
uint256 tierPrice = daos[daoMembershipAddress].tiers[tierIndex].price;
uint256 platformFees = (20 * tierPrice) / 100; // Platform gets 0 if price = 0
daos[daoMembershipAddress].tiers[tierIndex].minted += 1;
IERC20(daos[daoMembershipAddress].currency).transferFrom(_msgSender(), owpWallet, platformFees);
IERC20(daos[daoMembershipAddress].currency).transferFrom(_msgSender(), daoMembershipAddress, tierPrice - platformFees);
IMembershipERC1155(daoMembershipAddress).mint(_msgSender(), tierIndex, 1);
}

Key issues:

  1. No minimum price requirement for tiers

  2. Platform fees are purely percentage-based on the tier price

  3. DAO creators can set price to 0 and collect actual payments off-chain

  4. No mechanism to detect or prevent off-chain fee collection

Impact

  • Complete bypass of platform's 20% fee structure

  • Revenue loss for the protocol

  • Unfair advantage for DAOs willing to circumvent fees

  • Platform resources used without compensation

Tools Used

  • Manual code review

Recommendations

Add minimum price requirement for paid tiers:

uint256 public constant MINIMUM_PAID_TIER_PRICE = 1e18; // 1 token minimum
function createNewDAOMembership(DAOInputConfig calldata daoConfig, TierConfig[] calldata tierConfigs) external {
// ... existing checks ...
require(tierConfigs[0].price >= MINIMUM_PAID_TIER_PRICE, "Premium tier price too low");
// ... rest of function ...
}
Updates

Lead Judging Commences

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

Support

FAQs

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