he joinDAO
function is vulnerable to a re-entrancy attack due to external calls made before state updates. Specifically, the function performs an ERC20 transferFrom
call, which an attacker could exploit to recursively re-enter joinDAO
before the membership count is updated. This allows an attacker to mint multiple memberships within a single tier, bypassing intended tier limits.
The joinDAO
function is vulnerable to re-entrancy because it performs an external call to transfer ERC20 tokens (using IERC20.transferFrom
) before finalizing the membership count update. Specifically, this call can trigger an attacker-controlled contract that can recursively call joinDAO
, resulting in multiple membership mints within a tier that should have been limited.
A re-entrancy vulnerability in the joinDAO
function could allow an attacker to repeatedly call the function before state updates are finalized, potentially minting multiple memberships in a tier beyond its intended limit. If exploited, this would allow malicious users to bypass the maximum membership restrictions on each tier, impacting the DAO’s resource allocation and user experience.
If an attacker successfully exploits this vulnerability, they could:
Mint multiple memberships in a single tier, exceeding the intended limit.
Potentially fill up high-demand tiers with multiple memberships under a single malicious address.
Cause financial or reputational damage to the DAO by breaking membership limits.
Code
The vulnerable sequence in the joinDAO
function is as follows:
If the IERC20.transferFrom
calls allow for re-entrancy (for example, if an attacker uses a custom ERC20 token with a transferFrom
function that makes a callback), the attacker can re-enter joinDAO
before the minted count (daos[daoMembershipAddress].tiers[tierIndex].minted
) is incremented.
Manual Review
To prevent re-entrancy attacks, consider the following mitigations:
Check-Effects-Interactions Pattern: Update the state before making any external calls. For joinDAO
, ensure the minted
count is incremented before any token transfers are initiated.
Re-Entrancy Guard: Add a re-entrancy guard modifier, such as OpenZeppelin’s nonReentrant
, to prevent re-entrant calls within joinDAO
.
Use Pull Payment Pattern: Instead of transferring funds within joinDAO
, implement a “pull payment” mechanism where funds are claimed by recipients after the transaction completes, reducing the potential for re-entrancy.
Here’s an example of how the joinDAO
function would look after applying the Check-Effects-Interactions Pattern:
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.