Skip to content

Instantly share code, notes, and snippets.

@numtel
Created February 16, 2022 00:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save numtel/01acb98feb3dcfbe2cc33bc0393979ad to your computer and use it in GitHub Desktop.
Save numtel/01acb98feb3dcfbe2cc33bc0393979ad to your computer and use it in GitHub Desktop.
Crowdfunding smart contract (not tested)
pragma solidity >=0.8.0 <0.9.0;
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
contract BuskVault {
uint public constant goalAmount = ${goal};
IERC20 public constant token = IERC20(${token});
uint public constant start = ${start}; // Timestamp
uint public constant end = ${end}; // Timestamp
address public constant creator = ${creator};
bool cancelled;
uint balance;
uint depositorCount;
mapping(address => uint) depositors;
event Deposit(address depositor, uint amount);
event Withdrawal(address depositor, uint amount);
event Cancelled();
event Received();
modifier onlyCreator() {
require(msg.sender == creator, "Not authorized");
}
modifier onlyUnfinishedOrUnmet() {
require(cancelled == true || block.timestamp < end || balance < goal,
"Finished and Goal Met");
}
modifier onlyLive() {
require(cancelled == false, "Cancelled Already");
require(block.timestamp < end, "Ended Already");
}
function deposit(uint amount) external onlyLive {
require(block.timestamp >= start, "Not Yet Started");
require(amount > 0, "Cannot Deposit Zero");
token.transferFrom(msg.sender, address(this), amount);
if(depositors[msg.sender] == 0) {
depositorCount++;
}
balance += amount;
depositors[msg.sender] += amount;
emit Deposit(msg.sender, amount);
}
function withdraw(uint amount) external onlyUnfinishedOrUnmet {
require(amount > 0, "Cannot Withdraw Zero");
require(depositors[msg.sender] >= amount, "Balance Insufficient");
token.transferFrom(address(this), msg.sender, amount);
if(depositors[msg.sender] == amount {
depositorCount--;
}
depositors[msg.sender] -= amount;
balance -= amount;
emit Withdrawal(msg.sender, amount);
}
function withdrawAll() external {
uint memory senderBalance = depositors[msg.sender];
withdraw(senderBalance);
}
function cancel() external onlyCreator onlyLive {
cancelled = true;
emit Cancelled();
}
function receive() external onlyCreator {
require(cancelled == false, "Cancelled Already");
require(block.timestamp >= end, "Not Yet Finished");
require(balance >= goal, "Goal Not Met");
token.transferFrom(address(this), creator, balance);
emit Received();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment