Summary
Link: https://github.com/Cyfrin/2024-11-one-world/blob/1e872c7ab393c380010a507398d4b4caca1ae32b/contracts/dao/MembershipFactory.sol#L147
Each time a member joins a DAO, the creator gets some fees:
IERC20(daos[daoMembershipAddress].currency).transferFrom(_msgSender(), daoMembershipAddress, tierPrice - platformFees);
However, there is no way for the DAO owner to retrieve those fees, because the contract is lacking a withdraw function.
Vulnerability Details
Some details...
Proof of Concept:
Add the following test to MembershipFactory.test.ts in the "Join DAO" describe block:
it("DAO creator cannot withdraw fees", async function () {
await testERC20.mint(addr1.address, ethers.utils.parseEther("100"));
await testERC20.connect(addr1).approve(membershipFactory.address, ethers.utils.parseEther("100"));
await membershipFactory.connect(addr1).joinDAO(membershipERC1155.address, 2);
expect(await testERC20.balanceOf(membershipERC1155.address)).to.equal(80);
expect(await testERC20.balanceOf(owner.address)).to.equal(20);
const calldataTransfer = testERC20.interface.encodeFunctionData("transfer", [owner.address, 80]);
const encodedCalldata = membershipERC1155.interface.encodeFunctionData("callExternalContract", [testERC20.address, calldataTransfer]);
await membershipFactory.callExternalContract(membershipERC1155.address, encodedCalldata);
expect(await testERC20.balanceOf(owner.address)).to.equal(100);
});
Impact
THe DAO creator cannot withdraw accrued fees.
Tools Used
Manual Review
Recommendations
Add a withdraw function that allows the DAO creator to withdraw accrued fees.