Project

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

DAO creator can create DAO with tier prices to bypass platform fees and receive all membership fees

Description

A DAO creator can set up a DAO with tier prices that enable them to avoid platform fees and collect all membership fees.

In MembershipFactory.createNewDAOMembership, a user can establish a DAO with various tier prices below 5.

When a user calls MembershipFactory.joinDAO to join the DAO, precision loss occurs during the calculation of platformFees, resulting in all membership fees being transferred to the membership contract.

/// @notice Allows a user to join a DAO by purchasing a membership NFT at a specific tier
/// @param daoMembershipAddress The address of the DAO membership NFT
/// @param tierIndex The index of the tier to join
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; // precision loss happens here
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);
emit UserJoinedDAO(_msgSender(), daoMembershipAddress, tierIndex);
}

POC

  1. Alice sets up a new DAO with the daoMembershipAddress A

    a. She invokes MembershipFactory.createNewDAOMembership and provides an array of TierConfig with TierConfig.price values of 1, 2, 3, and 4 for the respective tiers from lowest to highest

    b. The DAOConfig.currency used is USDC

  2. Bob joins tier 1 of the DAO with daoMembershipAddress A

  3. The platformFees are calculated as (20 * 4) / 100 = 0, leading to precision loss

  4. As a result, no platformFees are transferred to the one world wallet address

  5. The membership address receives all the membership fees

Impact

Loss of funds for one world protocol. DAO can bypass membership fees

Code Snippet

https://github.com/Cyfrin/2024-11-one-world/blob/1e872c7ab393c380010a507398d4b4caca1ae32b/contracts/dao/MembershipFactory.sol#L144

Recommendation

There area few ways to mitigate the issue that can be considered

  • Include check to ensure platformFees are not zero

  • Scaling up values

  • Introduce a minimum price

Updates

Lead Judging Commences

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

Appeal created

x0sauce Submitter
9 months ago
0xbrivan2 Lead Judge
9 months ago
0xbrivan2 Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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