Skip to content

Instantly share code, notes, and snippets.

@Georgi87
Created April 15, 2017 15:17
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 Georgi87/9410209ebf7be3a600ffc03248e886b9 to your computer and use it in GitHub Desktop.
Save Georgi87/9410209ebf7be3a600ffc03248e886b9 to your computer and use it in GitHub Desktop.
pragma solidity 0.4.4;
import "StandardToken.sol";
contract ReceiptToken is StandardToken {
address owner;
modifier isOwner() {
if (msg.sender != owner)
throw;
_;
}
function ReceiptToken()
public
{
owner = msg.sender;
}
function issue(address receiver, uint amount)
public
isOwner
{
balances[receiver] += amount;
totalSupply += amount;
}
}
contract Campagin {
event Contribution(address indexed sender, uint amount);
event Refund(address indexed sender, uint amount);
address public receiver;
uint public fundingGoal;
uint public cap;
uint public startDate;
uint public endDate;
uint public backers;
uint public totalReceived;
ReceiptToken public receiptToken;
Stages public stage;
mapping (address => uint) public contributions;
enum Stages {
Deployed,
Started,
EndedSuccessfully,
EndedUnsuccessfully
}
modifier timedTransitions() {
if (stage == Stages.Deployed && now > startDate)
stage = Stages.Started;
if (stage == Stages.Started && endDate > 0 && now > endDate)
if (fundingGoal == 0 || fundingGoal >= totalReceived)
stage = Stages.EndedSuccessfully;
else
stage = Stages.EndedUnsuccessfully;
_;
}
modifier atStage(Stages _stage) {
if (stage != _stage)
throw;
_;
}
function Campagin(address _receiver, uint _fundingGoal, uint _cap, uint _startDate, uint _endDate)
public
{
if ( _receiver == 0
|| _endDate > 0 && _startDate > _endDate
|| _cap > 0 && _fundingGoal > _cap
|| _fundingGoal > 0 && _endDate == 0)
throw;
receiver = _receiver;
fundingGoal = _fundingGoal;
cap = _cap;
if (_startDate == 0)
_startDate = now;
endDate = _endDate;
startDate = _startDate;
receiptToken = new ReceiptToken();
stage = Stages.Deployed;
}
function ()
public
payable
{
contribute();
}
function contribute()
public
payable
timedTransitions
atStage(Stages.Started)
returns (uint amount)
{
amount = msg.value;
// Set amount to max amount possible
if (cap > 0 && totalReceived + amount > cap)
amount = cap - totalReceived;
// Increase number of backers
if (contributions[msg.sender] == 0)
backers += 1;
// Add contribution
contributions[msg.sender] += amount;
totalReceived += amount;
// Forward funding if not refundable
uint refund = msg.value - amount;
if (totalReceived >= fundingGoal && !receiver.send(this.balance - refund))
throw;
// Return ETH exceeding the funding goal
if (refund > 0 && !msg.sender.send(refund))
throw;
// Issue receipt token immediately, if campaing has no end
if (endDate == 0)
receiptToken.issue(msg.sender, amount);
Contribution(msg.sender, amount);
}
function receipt()
public
timedTransitions
atStage(Stages.EndedSuccessfully)
returns (uint amount)
{
amount = contributions[msg.sender];
contributions[msg.sender] = 0;
receiptToken.issue(msg.sender, amount);
Receipt(msg.sender, amount);
}
function refund()
public
timedTransitions
atStage(Stages.EndedUnsuccessfully)
returns (uint amount)
{
amount = contributions[msg.sender];
contributions[msg.sender] = 0;
if (!msg.sender.send(amount))
throw;
Refund(msg.sender, amount);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment