Project

One World
NFTDeFi
15,000 USDC
View results
Submission Details
Severity: medium
Valid

Polygon's block reorg problem may lead to use join a wrong DAO

Summary

Polygon's block reorg problem may lead to use join a wrong DAO created by an attacker.

Vulnerability Details

A DAO is created by deploying a proxy using the new keyword.

MembershipFactory.sol#L72-L76:

TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
membershipImplementation,
address(proxyAdmin),
abi.encodeWithSignature("initialize(string,string,string,address,address)", daoConfig.ensname, "OWP", baseURI, _msgSender(), daoConfig.currency)
);

To join a DAO, a user needs to specify the address of the DAO membership along with the index of the tier to join, and protocol validates the tier index and tier amount of this specified DAO address.

MembershipFactory.sol#L140-L150:

function joinDAO(address daoMembershipAddress, uint256 tierIndex) external {
require(daos[daoMembershipAddress].noOfTiers > tierIndex, "Invalid tier.");
require(daos[daoMembershipAddress].tiers[tierIndex].amount > daos[daoMembershipAddress].tiers[tierIndex].minted, "Tier full.");
uint256 tierPrice = daos[daoMembershipAddress].tiers[tierIndex].price;
uint256 platformFees = (20 * tierPrice) / 100;
daos[daoMembershipAddress].tiers[tierIndex].minted += 1;
IERC20(daos[daoMembershipAddress].currency).transferFrom(_msgSender(), owpWallet, platformFees);
IERC20(daos[daoMembershipAddress].currency).transferFrom(_msgSender(), daoMembershipAddress, tierPrice - platformFees);
IMembershipERC1155(daoMembershipAddress).mint(_msgSender(), tierIndex, 1);
emit UserJoinedDAO(_msgSender(), daoMembershipAddress, tierIndex);
}

It works fine under normal circumstances, however, things might go wrong if there is a reorg. In fact, high-depth block reorgs are happening DAILY in Polygon, and a third of these had double-digit block reorg depth, as can be viewd on Polygonscan’s Forked Blocks page.

It's possible that DAO creations and joinings are included fully within a reorg, an attacker is able to frontrun the creator's DAO creation, effectively stealing the DAO instance at that particular address(MembershipFactory uses new to create DAO proxies, and the address is depent on the contract's nonce), leading to the user pays funds to join a malicious DAO.

Consider the following scenario:

  1. A popular DAO membership is created with limited amount in each tier, assuming the DAO proxy address is proxyA;

  2. The users backrun to mint membership NFTs therefore they join the DAO at the same block of the DAO creation;

  3. Reorg happens at the DAO creation block;

  4. An Attacker frontruns the the origin DAO creation transaction to deploy his own DAO, so attacker's DAO address is proxyA;

  5. The origin DAO creation transaction is executed, but the DAO is deployed on a different address other than proxyA;

  6. The users' joining DAO transactions are exeucted, but they are minted with the tokens of the malicious DAO.

Impact

High-depth block reorgs are not rare on Polygon, therefore the probability of this issue may be low but not negligible, and the impact is high as users waste funds to join a wrong DAO.

Tools Used

Manual Review

Recommendations

Deployments of DAO proxy instances should be done employing create2 with a salt calculated based on msg.sender and nonce.

Updates

Lead Judging Commences

0xbrivan2 Lead Judge
6 months ago
0xbrivan2 Lead Judge 6 months ago
Submission Judgement Published
Validated
Assigned finding tags:

reorg issues

Support

FAQs

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