0

Sorry for asking so basic question. But I can not figure out what to do.

As I am new to this topic. I have no idea how to solve this issue.

I have a basic contract for crowdfunding. It has some basic functions such as createCampaign donateToCampaign and some more. I thought my donateToCampaign function was correct and working fine as I can donate through MetaMask and it went smoothly with no errors. But after a donation to a campaign when I check my contract balance in goerli.etherscan.io it shows the balance is 0. Should not it have the donated funds added to its balance?

I can not figure out what is the problem with my function or if it is something else.

Here is my contract.

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;

contract CrowdFunding {
    event testConditon(
        uint256 deadline,
        uint256 currentTimeInMs,
        uint256 diff,
        bool condition
    );

    struct Campaign {
        address payable owner;
        string title;
        string description;
        uint256 target;
        uint256 deadline;
        uint256 amountCollected;
        string image;
        address[] donators;
        uint256[] donations;
    }

    mapping(uint256 => Campaign) public campaigns;

    uint256 public numberOfCampaigns = 0;

    function createCampaign(
        address _owner,
        string memory _title,
        string memory _description,
        uint256 _target,
        uint256 _deadline,
        string memory _image
    ) public returns (uint256) {
        Campaign storage campaign = campaigns[numberOfCampaigns];
        uint256 currentTimeInMs = block.timestamp * 1000;

        emit testConditon(
            _deadline,
            currentTimeInMs,
            _deadline - currentTimeInMs,
            _deadline > currentTimeInMs
        );

        require(
            _deadline > currentTimeInMs,
            "The deadline must be in the future"
        );

        campaign.owner = payable(_owner);
        campaign.title = _title;
        campaign.description = _description;
        campaign.target = _target;
        campaign.deadline = _deadline;
        campaign.image = _image;
        campaign.amountCollected = 0;

        numberOfCampaigns++;

        return numberOfCampaigns - 1;
    }

    function donateToCampaign(uint256 _id) public payable {
        uint256 amount = msg.value;

        Campaign storage campaign = campaigns[_id];

        campaign.donators.push(msg.sender);
        campaign.donations.push(amount);

        (bool sent, ) = payable(campaign.owner).call{value: amount}("");

        if (sent) {
            campaign.amountCollected += amount;
        }
    }

    function getDonators(uint256 _id)
        public
        view
        returns (address[] memory, uint256[] memory)
    {
        return (campaigns[_id].donators, campaigns[_id].donations);
    }

    function getCampaigns() public view returns (Campaign[] memory) {
        Campaign[] memory allCampaigns = new Campaign[](numberOfCampaigns);

        for (uint256 i = 0; i < numberOfCampaigns; i++) {
            Campaign storage item = campaigns[i];
            allCampaigns[i] = item;
        }

        return allCampaigns;
    }

    function withdraw(uint256 _id) public {
        Campaign storage campaign = campaigns[_id];

        require(
            campaign.amountCollected >= campaign.target,
            "The campaign has not reached its target"
        );

        //deadline has passed
        // require(
        //     campaign.deadline < block.timestamp * 1000,
        //     "The deadline has not passed yet"
        // );

        require(
            campaign.owner == msg.sender,
            "Only the owner of the campaign can withdraw the funds"
        );

        (bool success, ) = payable(campaign.owner).call{
            value: campaign.amountCollected
        }("");
        require(success, "Withdrawal failure");
        campaign.amountCollected = 0;
    }
}

Help me fix the problem.

2
  • The contract isn't keeping the ETH, but it's sending it to campaign.owner. Is this intentional?
    – 0xSanson
    Feb 14 at 23:19
  • No, I wanted the contract to keep the ETH and when the withdraw function calls it will send the ETH to the campaign owner.
    – BLIND
    Feb 15 at 6:59

1 Answer 1

0

Since you want to keep the ETH in the contract, you don't have to do payable(campaign.owner).call{value: amount}(""); during the donation. This line transfers the ETH sent with the donation directly to the owner.

This should work:

    function donateToCampaign(uint256 _id) public payable {
        uint256 amount = msg.value;

        Campaign storage campaign = campaigns[_id];

        campaign.donators.push(msg.sender);
        campaign.donations.push(amount);

        //(bool sent, ) = payable(campaign.owner).call{value: amount}("");

        campaign.amountCollected += amount;
    }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.