Github link
https://github.com/Cyfrin/2024-11-one-world/blob/1e872c7ab393c380010a507398d4b4caca1ae32b/contracts/dao/MembershipFactory.sol#L155
Summary
minted number of the tier is not updated in the MembershipFactory::upgradeTier function and this could affect users' joining process to tiers.
The minted count of the tier is not updated during the MembershipFactory::upgradeTier function call, potentially disrupting tier minted count tracking and user progression.
Vulnerability Details
Users can join existing DAO by utilizing the MembershipFactory::jointDAO.
File: MembershipFactory.sol
140: function joinDAO(address daoMembershipAddress, uint256 tierIndex) external {
141: require(daos[daoMembershipAddress].noOfTiers > tierIndex, "Invalid tier.");
142: require(daos[daoMembershipAddress].tiers[tierIndex].amount > daos[daoMembershipAddress].tiers[tierIndex].minted, "Tier full.");
143: uint256 tierPrice = daos[daoMembershipAddress].tiers[tierIndex].price;
144: uint256 platformFees = (20 * tierPrice) / 100;
145: daos[daoMembershipAddress].tiers[tierIndex].minted += 1;
146: IERC20(daos[daoMembershipAddress].currency).transferFrom(_msgSender(), owpWallet, platformFees);
147: IERC20(daos[daoMembershipAddress].currency).transferFrom(_msgSender(), daoMembershipAddress, tierPrice - platformFees);
148: IMembershipERC1155(daoMembershipAddress).mint(_msgSender(), tierIndex, 1);
149: emit UserJoinedDAO(_msgSender(), daoMembershipAddress, tierIndex);
150: }
During the joining process the minted count of the tier that the user is trying to join, is increased by 1 at L145. And the minted count will be used to limit the number of joiners to be less or equal to the amount of the tier at L142.
And users can upgrade the tier within a sponsored DAO by utilizing the MembershipFactory::upgradeTier function.
File: MembershipFactory.sol
155: function upgradeTier(address daoMembershipAddress, uint256 fromTierIndex) external {
156: require(daos[daoMembershipAddress].daoType == DAOType.SPONSORED, "Upgrade not allowed.");
157: require(daos[daoMembershipAddress].noOfTiers >= fromTierIndex + 1, "No higher tier available.");
158: IMembershipERC1155(daoMembershipAddress).burn(_msgSender(), fromTierIndex, 2);
159: IMembershipERC1155(daoMembershipAddress).mint(_msgSender(), fromTierIndex - 1, 1);
160: emit UserJoinedDAO(_msgSender(), daoMembershipAddress, fromTierIndex - 1);
161: }
Users can get the upper tier NFT by burning 2 lower tier NFTs. However the counts of the minted are not updated during this process for both tiers.
Impact
This results in incorrect tracking of the minted count of tiers and could affect the joining process of users. It can prevent users from joining the tiers or allows more users to join the specific tier than it should be.
Tools Used
Manual Review
Recommendations
It is recommended to update the number of minted as follows:
File: MembershipFactory.sol
function upgradeTier(address daoMembershipAddress, uint256 fromTierIndex) external {
require(daos[daoMembershipAddress].daoType == DAOType.SPONSORED, "Upgrade not allowed.");
require(daos[daoMembershipAddress].noOfTiers >= fromTierIndex + 1, "No higher tier available.");
IMembershipERC1155(daoMembershipAddress).burn(_msgSender(), fromTierIndex, 2);
IMembershipERC1155(daoMembershipAddress).mint(_msgSender(), fromTierIndex - 1, 1);
+ daos[daoMembershipAddress].tiers[fromTierIndex].minted -= 2;
+ daos[daoMembershipAddress].tiers[fromTierIndex - 1].minted += 1;
emit UserJoinedDAO(_msgSender(), daoMembershipAddress, fromTierIndex - 1);
}