/smartcontracts

Charitychain is the first fundraising platform on which fundraisers must give first

CharityChain

Charitychain is a non-profit open source project. Charitychain is the first fundraising platform on which fundraisers must give first

  • The campaign author deposits 50% of the campaign goal.
  • Contributors try to unblock the initial donation by collecting 50% of the goal.
  • If they succeed, 100% of the funds go to the NGO, otherwise, everyone is refunded

N|Solid

Current status of smart contract

The smartcontract is in preparation (work in progress) for a third-party code audit.

Overview

  • This contract manages a single campaign. It's not a Factory
  • All the code is in this class, there is no dependency on third-party libraries
  • There are less than 200 lines of code.

Constructor

The constructor can receive funds with the payable modifier. To create a campaign, 3 arguments and an initial payment in Eth are required.

  • The name of the campaign
  • The end of the campaign (block number)
  • The recipient's Ethereum wallet address
  • An initial contribution

The campaign is created with a goal equal to twice the first contribution.

State Machine

  • CampaignInprogress
  • CampaignFailure
  • CampaignSuccess

As long as the end date is not exceeded, the campaign continues, even if the goal is already reached.

Restricting Access

  • Beneficiary
  • Owner

Contribute

The contribute() transaction is only available in the CampaignInprogress state. A contributionID is created for each contribution. This ID is associated with the contributor's address.

Possible scenarios

The campaign success

If the end date of the campaign is exceeded and the amount collected is greater than the goal, then the current campaign stage becomes CampaignSuccess. In this state, the only possible action on the contract is withdrawal of money by the beneficiary.

    function payoutToBeneficiary() public atStage(Stages.CampaignSuccess) onlybeneficiary() {
        uint256 payoutAmount = this.balance;
        msg.sender.transfer(payoutAmount);
        ...
    }

The campaign Failure

If the campaign is complete (current block above expiry) and the amount collected is less than the goal, then the current campaign stage becomes CampaignFailure. Contributors must recover their contributions with the function withdrawRefundContribution()

 function withdrawRefundContribution(uint256 _contributionID) public atStage(Stages.CampaignFailure) validRefund(_contributionID) {
 ...
 }

In case of unexpected behavior

There is an emergency mechanism that force expiry of campaign an allows everyone to claim their money depending on the stage of the campaign. Only the Owner can execute this transaction.

    function emergencyCampaignExpiry() external onlyOwner {
        expiry = 0;
    }

Informations

events

the smart contracts can fire 3 events:

event LogContributionMade (address _contributor);
event LogContributionRefunded(address _payoutDestination, uint256 _payoutAmount);
event LogBeneficiaryPayoutMade (address _payoutDestination, uint256 _amountRaised);

Funding Cap

A fundingCap system is implemented (arbitrarily set at 10x fundingGoal), if achieved, he prevents any new contribution.

Static Analysis

No issues found with solium

Work In Progress

  • Optimizations (especially on the size of int)
  • Improved validation rules (especially on the end date when the contract was created)
  • Bug Bounty Program
  • Runtime Analysis (Unit testing)
  • Code Review
  • Code Audit

Credit: This contract has been rewritten several times a year ago, it is now mainly inspired by the Weifund project because in my opinion, it is the simplest and most elegant implementation of crowdfunding smart contract on Ethereum.