## Summary
`MembershipFactory.createNewDAOMembership()` : no checks on the tiers prices of the sponsored DAO's, which will be exploited by buyers by upgarding their higher-indexed tiers NFTs (lower weight) with lower-indexed tiers (higher weight) with less price, example:
if the price of a sponsored DAO tier-0 is 5000 USDC and the price of tier-1 is 2000; then any member can buy 2 \* tiers-1 NFTs with 4000 USDC, and upgrade their membership with 1 tier-0 NFT which has a price of 5000USDC, while the user only pays a price of 4000USDC.
## Vulnerability Details
- One world protocol has a feacture of enabling **sponsored** DAO members to upgarde their tier membership from higher index tiers that have low weight to a lower index tiers that have a higher weight, for example:
tier-0 has double weight of tier-1 , so if a user wants to upgrade his membership from tier-1 to tier-0; he must have 2 tier-1 NFTs to be burnt to get a membership in tier-0, while their weight will not be affected as 2 NFTs will be burnt from the user's tier-1, to get one NFT of tier-0, and this will leave the `totalSupply` in balance:
```javascript
function upgradeTier(
address daoMembershipAddress,
uint256 fromTierIndex
) external {
//...
IMembershipERC1155(daoMembershipAddress).burn(
_msgSender(),
fromTierIndex,
2
);
IMembershipERC1155(daoMembershipAddress).mint(
_msgSender(),
fromTierIndex - 1,
1
);
//...
}
```
where:
```javascript
function burn(
address from,
uint256 tokenId,
uint256 amount
) external onlyRole(OWP_FACTORY_ROLE) {
burn_(from, tokenId, amount);
}
function burn_(address from, uint256 tokenId, uint256 amount) internal {
totalSupply -= amount * 2 ** (6 - tokenId); // Update total supply with weight
_burn(from, tokenId, amount);
}
```
```javascript
function mint(
address to,
uint256 tokenId,
uint256 amount
) external override onlyRole(OWP_FACTORY_ROLE) {
totalSupply += amount * 2 ** (6 - tokenId); // Update total supply with weight
_mint(to, tokenId, amount, "");
}
```
- The issue is that the tier prices are not being validated when creating the sponsored DAO tiers (via `MmebershipFactory.createNewDAOMembership()`), so if the price of each lower tier is not twice of its subsequent upper tier (i.e: tier-0 is 2\*tier-1 price); then this will allow users to buy higher tiers and upgarde it to lower tiers if the price of the lower tier is less than the higher ones\*2,
for example:
if the price of a sponsored DAO tier-0 is 5000 USDC and the price of tier-1 is 2000; then any member can buy 2 \* tiers-1 NFTs with 4000 USDC, and upgrade their membership with 1 tier-0 NFT which has a price of 5000USDC, while the user only pays a price of 4000USDC.
## Impact
Knowing that with each membership sale (via `MmbershipFactory.joinDAO()`), 20% of the membership price is sent to the project wallet, and the remaining 80% is sent to the `MembershipERC1155` contract to be distributed to the membership holders:
```javascript
//...
function joinDAO(address daoMembershipAddress, uint256 tierIndex) external {
uint256 tierPrice = daos[daoMembershipAddress].tiers[tierIndex].price;
uint256 platformFees = (20 * tierPrice) / 100;
IERC20(daos[daoMembershipAddress].currency).transferFrom(
_msgSender(),
owpWallet,
platformFees
);
IERC20(daos[daoMembershipAddress].currency).transferFrom(
_msgSender(),
daoMembershipAddress,
tierPrice - platformFees
);
//...
}
```
then not checking the prices of tiers will create an imbalance in the profit distribution to the membership holders.
## Proof of Concept
[MembershipFactory.joinDAO()](https://github.com/Cyfrin/2024-11-one-world/blob/1e872c7ab393c380010a507398d4b4caca1ae32b/contracts/dao/MembershipFactory.sol#L140C5-L140C81)
```javascript
function joinDAO(address daoMembershipAddress, uint256 tierIndex) external {
//...
}
```
## Tools Used
Manual Review.
## Recommendations
Update the `MembershipFactory.joinDAO()` to check for the tier prices, where every tier[i] should have the price of 2\*tier[i+1], as the following example:
tier[0].price = 2000 USDC
tier[1].price = 1000 USDC
tier[2].price = 500 USDC
tier[3].price = 250 USDC
tier[4].price = 125 USDC
tier[5].price = 62.5 USDC
tier[6].price = 31.25 USDC