Nesse artigo iremos aprender a como criar um sistema de financiamento coletivo através de um contrato inteligente.
Sistema de Financiamento Coletivo (Crowd Fund)
Como funciona o token ERC20 de financiamento coletivo?
- O usuário cria uma campanha.
- Os usuários podem se comprometer, transferindo seu token para uma campanha.
- Após o término da campanha, o criador da campanha pode reivindicar os fundos se o valor total prometido for maior que a meta da campanha.
- Caso contrário, a campanha não atingiu seu objetivo, então os usuários podem retirar o valor depositado.
// SPDX-License-Identifier: MITpragma solidity ^0.8.13;interface IERC20 {function transfer(address, uint) external returns (bool);function transferFrom(address,address,uint) external returns (bool);}contract CrowdFund {event Launch(uint id,address indexed creator,uint goal,uint32 startAt,uint32 endAt);event Cancel(uint id);event Pledge(uint indexed id, address indexed caller, uint amount);event Unpledge(uint indexed id, address indexed caller, uint amount);event Claim(uint id);event Refund(uint id, address indexed caller, uint amount);struct Campaign {// Criador da campanhaaddress creator;// Objetivo de tokens para arrecadaruint goal;// Valor doado para a campanhauint pledged;// Timestamp do início da campanhauint32 startAt;// Timestamp do final da campanhauint32 endAt;// True se a meta foi alcançada e o criador reivindicou os tokens.bool claimed;}IERC20 public immutable token;// Contagem total de campanhas criadas.// Também é usado para gerar id para novas campanhas.uint public count;// Mapeamento do id para a campanhamapping(uint => Campaign) public campaigns;// Mapeamento do id da campanha => doador => valor doadomapping(uint => mapping(address => uint)) public pledgedAmount;constructor(address _token) {token = IERC20(_token);}function launch(uint _goal,uint32 _startAt,uint32 _endAt) external {require(_startAt >= block.timestamp, "data início < agora");require(_endAt >= _startAt, "data final < data início");require(_endAt <= block.timestamp + 90 days, "data final > duração máxima (90 dias)");count += 1;campaigns[count] = Campaign({creator: msg.sender,goal: _goal,pledged: 0,startAt: _startAt,endAt: _endAt,claimed: false});emit Launch(count, msg.sender, _goal, _startAt, _endAt);}function cancel(uint _id) external {Campaign memory campaign = campaigns[_id];require(campaign.creator == msg.sender, "não é o criador");require(block.timestamp < campaign.startAt, "iniciada");delete campaigns[_id];emit Cancel(_id);}function pledge(uint _id, uint _amount) external {Campaign storage campaign = campaigns[_id];require(block.timestamp >= campaign.startAt, "não iniciada");require(block.timestamp <= campaign.endAt, "finalizada");campaign.pledged += _amount;pledgedAmount[_id][msg.sender] += _amount;token.transferFrom(msg.sender, address(this), _amount);emit Pledge(_id, msg.sender, _amount);}function unpledge(uint _id, uint _amount) external {Campaign storage campaign = campaigns[_id];require(block.timestamp <= campaign.endAt, "finalizada");campaign.pledged -= _amount;pledgedAmount[_id][msg.sender] -= _amount;token.transfer(msg.sender, _amount);emit Unpledge(_id, msg.sender, _amount);}function claim(uint _id) external {Campaign storage campaign = campaigns[_id];require(campaign.creator == msg.sender, "não é o criador");require(block.timestamp > campaign.endAt, "não finalizada");require(campaign.pledged >= campaign.goal, "doado < meta");require(!campaign.claimed, "já reivindicado");campaign.claimed = true;token.transfer(campaign.creator, campaign.pledged);emit Claim(_id);}function refund(uint _id) external {Campaign memory campaign = campaigns[_id];require(block.timestamp > campaign.endAt, "não finalizada");require(campaign.pledged < campaign.goal, "valor doado menor que a meta");uint bal = pledgedAmount[_id][msg.sender];pledgedAmount[_id][msg.sender] = 0;token.transfer(msg.sender, bal);emit Refund(_id, msg.sender, bal);}}
Este contrato de financiamento coletivo, poderia ser implementado para um sistema ao estilo do site Vakinha, onde os usuários podem criar campanhas para seus projetos NFT, desenvolvimento de jogos NFT e outros projetos pessoais ou campanhas sociais, através de campanhas de levantamento de fundos de criptomoedas.