🚀 Build your Smart Contract for Crowdfunding

In the lesson, you are asked to develop a Smart Contract that statisfies the following specifications:

We want to build a fundraising DApp. This application will enable creators to publish projects proposals in order to raise money in the form of ERC20 tokens (token). A crowd funding campaign lasts for a fixed duration and money must be raised above a minimum goal to unklock the developpement of project (usage of the funds) otherwise the contributors are refunded.

  • launching: anyone can create a campaign. It requires a minium goal to reach (cap), start and end dates (openingTime, closingTime) and duration cannot exceeed 90 days.
  • raising: Contributors sends tokens to the contract during the raising stage. Campaign can be canceled by the creator at any moment. By default, the recipient of funds is the owner after that the campaign is closed. However if the campaign is canceled all the participants can individually ask to withdraw their funds.
  • withdrawing: after the raising period is expired or the cap is reached, the creator can close the campaign and get the funds.

Technical hints:

  • contract deployment corresponds to the launching stage. Parameters of the contract can be given in the contract constructor: constructor(IERC20 token_, uint cap_, uint start_, uint end_);
  • this contract mixes the previous Vote contract and a set of Escrow contracts. The approve function of the ERC20 will also be usefull.

The Smart Contract must implement the following interface:

interface ICrowdfunding {

    function creator() external view returns (address);
    function start() external view returns (uint);
    function end() external view returns (uint);
    function closed() external view returns (bool);

    function cap() external view returns (uint);
    function token() external view returns (address);
    function depositsOf(address participant) external view returns (uint256);
    function amountRaised() external view returns (uint256);

    function participate(uint256 amount) external;
    function close() external;
    function cancel() external;
    function withdraw() external;

    event Deposited(address indexed participant, uint256 amount);
    event Withdrawn(address indexed participant, uint256 amount);
    event Canceled();
    event Closed();
}