Project

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

Lack of Validation for Tier Price Allows Incorrect Token Transfer Amounts in joinDAO

https://github.com/Cyfrin/2024-11-one-world/blob/main/contracts/dao/MembershipFactory.sol#L140

Summary - The joinDAO function relies on the tier.price value for calculating the membership cost. However, the lack of additional validation on tier.price could allow an attacker to manipulate or bypass payment, potentially joining a DAO at a lower price or without a complete payment.

Vulnerability Details- The joinDAO function fetches tier.price directly from the TierConfig struct but does not validate that tier.price aligns with the intended DAO membership cost set by administrators. If tier.price is set to zero or manipulated, users could theoretically join a DAO without paying the correct fee.

Impact- If the attacker can influence tier.price to be zero or an unintended value (either through an insecure DAO configuration or by calling an unprotected setter function), they could bypass or minimize the payment.

Tools Used -manual review

Recommendations-

we must validate tier.price in joinDAO to ensure it matches a minimum acceptable amount.

contract MembershipFactory is AccessControl, NativeMetaTransaction, ReentrancyGuard {
mapping(address => mapping(address => bool)) private hasJoined;
uint256 public constant MINIMUM_TIER_PRICE = 0.01 ether; // Define a minimum price
function joinDAO(address daoMembershipAddress, uint256 tierIndex) external nonReentrant {
require(!hasJoined[msg.sender][daoMembershipAddress], "Already joined this DAO");
DAOConfig storage dao = daos[daoMembershipAddress];
require(dao.noOfTiers > tierIndex, "Invalid tier");
TierConfig storage tier = dao.tiers[tierIndex];
require(tier.amount > tier.minted, "Tier full");
// Check that tier price meets a minimum threshold
require(tier.price >= MINIMUM_TIER_PRICE, "Tier price too low");
uint256 tierPrice = tier.price;
uint256 platformFees = (20 * tierPrice) / 100;
tier.minted += 1;
hasJoined[msg.sender][daoMembershipAddress] = true;
// Safe token transfers
SafeERC20.safeTransferFrom(IERC20(dao.currency), _msgSender(), owpWallet, platformFees);
SafeERC20.safeTransferFrom(IERC20(dao.currency), _msgSender(), daoMembershipAddress, tierPrice - platformFees);
IMembershipERC1155(daoMembershipAddress).mint(_msgSender(), tierIndex, 1);
emit UserJoinedDAO(_msgSender(), daoMembershipAddress, tierIndex);
}
}
Updates

Lead Judging Commences

0xbrivan2 Lead Judge 11 months ago
Submission Judgement Published
Invalidated
Reason: Too generic

Support

FAQs

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