Summary
The MemberShipFactory::upgradeTier function doesn't update the number of tiers minted on the tiers at the both sides of the upgrade.
Vulnerability Details
The MemberShipFactory::upgradeTier function allows users to upgrade their tier from one to another. This action changes the number of tiers minted on tiers at the both sides of upgrade, since there is a burn on one and a mint on the other. However the MemberShipFactory::upgradeTier function doesn't update none of the tiers number of minted tokens.
File: contracts/dao/MembershipFactory.sol#L155-L161
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);
emit UserJoinedDAO(_msgSender(), daoMembershipAddress, fromTierIndex - 1);
}
Impact
There will be a discrepancy between daos[daoMembershipAddress].tiers[fromTierIndex - 1].minted and daos[daoMembershipAddress].tiers[fromTierIndex - 1].minted and the real number of minted tiers. The protocol can behave unexpectedly because of this.
Tools Used
Manual review.
Recommendations
Update the number of minted tokens of each tiers involved.
File: contracts/dao/MembershipFactory.sol#L155-L161
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);
++ daos[daoMembershipAddress].tiers[fromTierIndex].minted -= 2;
IMembershipERC1155(daoMembershipAddress).mint(_msgSender(), fromTierIndex - 1, 1);
++ daos[daoMembershipAddress].tiers[fromTierIndex - 1].minted += 1;
emit UserJoinedDAO(_msgSender(), daoMembershipAddress, fromTierIndex - 1);
}