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);
}