GivingThanks

First Flight #28
Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: medium
Valid

donate() has reentrancy attack

Summary

The donate() function sends Ether to a specified charity address using a low-level call. If the recipient contract (the charity) has a fallback function that initiates a recursive call back to donate(), it could repeatedly drain the contract's Ether before the function completes.

Impact

A reentrancy attack could result in the theft of Ether from the contract if the logic of donate() can be recursively executed before the state is updated.

Tools Used

manual

Recommendations

  • Use the Checks-Effects-Interactions Pattern

  • Add the ReentrancyGuard Modifier

    function donate(address charity) public payable nonReentrant {
    require(registry.isVerified(charity), "Charity not verified");
    // Mint the token before sending Ether (state change first)
    _mint(msg.sender, tokenCounter);
    string memory uri = _createTokenURI(msg.sender, block.timestamp, msg.value);
    _setTokenURI(tokenCounter, uri);
    tokenCounter += 1;
    // Transfer Ether to the charity
    (bool sent, ) = charity.call{value: msg.value}("");
    require(sent, "Failed to send Ether");
    }
Updates

Lead Judging Commences

n0kto Lead Judge 9 months ago
Submission Judgement Published
Validated
Assigned finding tags:

finding-donate-reentrancy-multiple-NFT-minted

Impact: High, one charity can reenter the donate function with the same ETH provided and mint several NFT. Likelyhood: Low, any malicious charity can do it but Admin is trusted and should verify the charity contract before "verifying" it.

Support

FAQs

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