Summary
The MembershipFactory
contract does not properly track the total number of members that have joined the DAO across all tiers.
Vulnerability Details
The current implementation of the MembershipFactory
contract does not have any mechanism to track the total number of members that have joined the DAO.
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;
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);
}
https://github.com/Cyfrin/2024-11-one-world/blob/1e872c7ab393c380010a507398d4b4caca1ae32b/contracts/dao/MembershipFactory.sol#L137C5-L150C6
The contract only stores the maxMembers
value, which represents the intended capacity limit, but there is no corresponding variable that keeps track of the actual number of members in the joinDAO function.
struct DAOConfig {
uint256 maxMembers;
}
Impact
Without a way to keep track of the total number of members, the DAO can easily exceed its configured maxMembers
limit, even though the individual tier capacities have not been reached.
Tools Used
Manual review
Recommendations
The MembershipFactory
contract should maintain a dedicated variable to track the total number of members that have joined the DAO. This can be done by adding a new field to the DAOConfig
struct and updating it accordingly in the joinDAO
function:
struct DAOConfig {
uint256 maxMembers;
uint256 totalMembers;
}
function joinDAO(address daoMembershipAddress, uint256 tierIndex) external {
dao.tiers[tierIndex].minted += 1;
dao.totalMembers += 1;
require(dao.totalMembers <= dao.maxMembers, "DAO member limit reached");
}