pragma solidity 0.8.22;
import {MembershipFactory} from "../contracts/dao/MembershipFactory.sol";
import {CurrencyManager} from "../contracts/dao/CurrencyManager.sol";
import {DAOType, DAOConfig, DAOInputConfig, TierConfig} from "../contracts/dao/libraries/MembershipDAOStructs.sol";
import {MembershipERC1155} from "../contracts/dao/tokens/MembershipERC1155.sol";
import {Test} from "lib/forge-std/src/Test.sol";
import {ERC20Mock} from "./ERC20Mock.sol";
import {console2} from "lib/forge-std/src/console2.sol";
contract Base is Test {
string baseURI = "0x";
address owpWallet = makeAddr("owpWallet");
address owner = makeAddr("owner");
address alice = makeAddr("alice");
address bob = makeAddr("bob");
address charlie = makeAddr("charlie");
MembershipERC1155 membershiImplementation;
MembershipFactory membershipFactory;
CurrencyManager currencyManager;
ERC20Mock currency;
event UserJoinedDAO(address indexed user, address indexed membershipNftAddress, uint256 tierIndex);
function setUp() public {
vm.startPrank(owner);
membershiImplementation = new MembershipERC1155();
currencyManager = new CurrencyManager();
currency = new ERC20Mock("Currency", "CUR", 100e18);
membershipFactory =
new MembershipFactory(address(currencyManager), owpWallet, baseURI, address(membershiImplementation));
currencyManager.addCurrency(address(currency));
currency.mint(alice, 100e18);
currency.mint(bob, 100e18);
currency.mint(charlie, 100e18);
vm.stopPrank();
}
function test_POC_userWhoCallUpgradeTier_wouldStillCountTowardOriginalTierMember() public {
vm.startPrank(alice);
DAOInputConfig memory daoConfig = DAOInputConfig("DAO", DAOType.SPONSORED, address(currency), 1000, 7);
TierConfig[] memory tiersConfig = new TierConfig[]();
tiersConfig[0] = TierConfig(2, 64000, 70, 0);
tiersConfig[1] = TierConfig(2, 32000, 60, 0);
tiersConfig[2] = TierConfig(2, 16000, 50, 0);
tiersConfig[3] = TierConfig(2, 8000, 40, 0);
tiersConfig[4] = TierConfig(2, 4000, 30, 0);
tiersConfig[5] = TierConfig(2, 2000, 20, 0);
tiersConfig[6] = TierConfig(2, 1000, 10, 0);
address daoAddress = membershipFactory.createNewDAOMembership(daoConfig, tiersConfig);
vm.stopPrank();
vm.startPrank(bob);
uint256 tierIndex = 5;
currency.approve(address(membershipFactory), 100e18);
membershipFactory.joinDAO(daoAddress, tierIndex);
membershipFactory.joinDAO(daoAddress, tierIndex);
membershipFactory.upgradeTier(daoAddress, tierIndex);
TierConfig[] memory tiers = membershipFactory.tiers(daoAddress);
assertEq(tiers[tierIndex].minted, 2);
vm.stopPrank();
vm.startPrank(alice);
tierIndex = 5;
currency.approve(address(membershipFactory), 100e18);
vm.expectRevert();
membershipFactory.joinDAO(daoAddress, tierIndex);
}
}
the original tier where user upgraded would be exhausted even though the original user is already upgraded. this would cause the DAO cannot have more member other than the originally minted user.
Potentially would cause the protocol lose their opportunity to gain new user and fees.
add logic to reduce the minted amount of the original tier, also update the next tier amount of minted:
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);
}