Project

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

M-2: In the joinDAO function, the `amount` (maximum member count) for each Tier is not properly implemented, resulting in actual `platformFees` revenue being less than expected `platformFees` revenue

Description

struct TierConfig {
uint256 amount;
uint256 price;
uint256 power;
uint256 minted;
}
  1. In the struct TierConfig, amount: represents the maximum number of members that can be in each tier, and minted: is used to track the number of members that have already been minted in each tier.

  2. In the joinDAO function, due to an incorrect condition check (require(daos[daoMembershipAddress].tiers[tierIndex].amount > daos[daoMembershipAddress].tiers[tierIndex].minted, "Tier full.");), this results in the inability to reach the maximum amount (maximum number of members) in each Tier, as minted will always be less than amount.

  3. That is, if amount is set to 10 and the maximum value of minted can only be 9, this clearly violates the design of the protocol and will lead to actual platformFees being lower than the expected platformFees.

Impact 1

The maximum number of members that can be in each tier (amount) is less than the number of members already minted in each tier (minted), which will result in a loss of owpWallet earnings, as the number of members cannot reach the preset maximum, leading to actual platformFees being lower than the expected platformFees.

POC:

  1. The DAO Creator sets tier.Price: 100, tier.amount: 10.

  2. When a user joins the DAO, 20% of the tier.Price will be taken as platformFees and transferred to the owpWallet.

  3. Since tier.amount = 10, the expected owpWallet platformFees are 100 * 20% * 10 = 200.

  4. However, due to an incorrect condition check, the actual owpWallet platformFees are only 100 * 20% * 9 = 180.

  5. Therefore, the expected actual platformFees are 20less than actual.

Impact 2

During the ongoing audit, I discovered a new impact.

Due to the check require(daos[daoMembershipAddress].tiers[tierIndex].amount > daos[daoMembershipAddress].tiers[tierIndex].minted, "Tier full.");, which means: amount < minted. If the amount value is even, then the minted value must be odd. This results in a situation where users attempting to upgrade their Tier through the upgradeTier function will always have one lower-level (Tier 7) NFT that cannot be upgraded to a higher level (Tier 6).

POC:

Let's walk through a scenario to illustrate the issue:

  1. Assume the DAO Creator sets Tier 7's amount = 10

  2. An affected user (Bob) purchases all NFTs available in Tier 7. Due to the condition amount < minted, the minted value becomes 9.

  3. When Bob wants to upgrade all his Tier 7 NFTs to Tier 6, he needs to use the upgradeTier function, which requires burning 2 Tier 7 NFTs to obtain 1 Tier 6 NFT.

  4. Since minted = 9, Bob can only successfully upgrade to get 4 Tier 6 NFTs, leaving one Tier 7 NFT that cannot be upgraded!

  5. This means that whenever the amount value is even, any user attempting to upgrade their Tier through the upgradeTier function in the DAO will always have one lower-level (Tier 7) NFT that cannot be upgraded to a higher level (Tier 6).

Recommendations

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.");
+ 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;
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);
}
Updates

Lead Judging Commences

0xbrivan2 Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
0xbrivan2 Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Appeal created

0x996 Submitter
about 1 year ago
0x996 Submitter
about 1 year ago
0xbrivan2 Lead Judge
about 1 year ago
0xbrivan2 Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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

Give us feedback!