Skip to content
Open
51 changes: 46 additions & 5 deletions contracts/Project.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,48 @@ pragma solidity ^0.4.2;

contract Project {

/* public properties */
/* Public properties */
address public owner;
uint public target;
uint public deadline;
uint public totalAmountRaised;
address[] public contributors;
mapping (address => uint) public contributions;

/* events */
/* Internal properties */
mapping (address => uint) internal balances;
bool hasOwnerWithdrawnFunds = false;

/* Events */
event ContributionMade(address contributor, uint amount);
event GoalReached(uint amount, address beneficiary);

function Project(address _owner, uint _target) public {
/* Constructor */
function Project(address _owner, uint _target, uint _durationInHours) public {
owner = _owner;
target = _target;
deadline = now + _durationInHours * 1 hours;
}

function contribute(address _contributor, uint _amount) public returns (bool success) {
/* Modifiers */
modifier afterDeadline() { if (now >= deadline) _; }
modifier projectOpen() { if (deadline < now) _; }

/* Publicly-exposed interface */

function contribute(address _contributor, uint _amount) public projectOpen returns (bool success) {
require(_amount > 0);

contributions[_contributor] += _amount;
totalAmountRaised += _amount;
balances[_contributor] += _amount;
contributors.push(_contributor);
ContributionMade(_contributor, _amount);
return true;
}

function balanceOf(address _contributor) public view returns (uint balance) {
return contributions[_contributor];
return balances[_contributor];
}

function isFullyFunded() public view returns (bool funded) {
Expand All @@ -37,4 +54,28 @@ contract Project {
return contributors.length;
}

function withdraw() public afterDeadline {
if (isFullyFunded()) {
withdrawForOwner();
} else {
withdrawForContributor();
}
}

/* Internal functions */

function withdrawForContributor() internal {
if (balances[msg.sender] > 0) {
msg.sender.transfer(balances[msg.sender]);
balances[msg.sender] = 0;
}
}

function withdrawForOwner() internal {
if (!hasOwnerWithdrawnFunds) {
owner.transfer(totalAmountRaised);
hasOwnerWithdrawnFunds = true;
}
}

}
16 changes: 16 additions & 0 deletions test/Project.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,20 @@ contract("Project", accounts => {
const numberOfContributions = await contract.numberOfContributions();
assert.equal(numberOfContributions, 3, "There are 3 contributions.");
});

it("should indicate whether a project is open or closed to contribution", async () => {});

it("should not allow an owner to withdraw funds if project is still open", async () => {});

it("should allow an owner to withdraw funds if project is closed and successful", async () => {});

it("should not allow an owner to withdraw funds if project is closed and unsuccessful", async () => {});

it("should allow a contributor to withdraw funds if project is closed and unsuccessful", async () => {});

it("should not allow a contributor to withdraw funds if project is closed and successful", async () => {});

xit("should not allow a contributor to withdraw funds if project is still open", async () => {});

it("should only allow contributors or owners to withdraw funds", async () => {});
});