If the issuer chooses to allow for 3rd party mediation, they allow the arbiter to accept fulfillments on their behalf, and are disallowed from fulfilling the bounty.
Bounties are formed in the `Draft` stage, a period the issuer can use to edit any of the bounty elements, and attain sufficient funding. During the active stage requirements or payout amounts cannot be altered, however the deadline may be extended. Fulfillments can only be accepted in the `Active` stage, even if the deadline has passed. The issuer can kill the bounty returning all funds to them (less the amount due for already accepted but unpaid submissions), however this behaviour is highly discouraged and can hurt reputation.
A bounty can only be contributed to, activated, or fulfilled before the given deadline. This deadline can be moved forward or backwards in the draft stage, but once the bounty is activated it can only be extended. This helps maintain the contractual nature of the relationship, where issuers cannot move deadlines forward arbitrarily while individuals are fulfilling the tasks.
All data representing the requirements are stored off-chain, and their hash is updated here. Requirements and auxiliary data are mutable while the bounty is in the `Active` stage, but becomes immutable when the bounty is activated, thereby "locking in" the terms of the contract, the requirements for acceptance for each milestone. These should be as rich as possible from the outset, to avoid conflicts stemming from task fulfillers believing they merited the bounty reward.
The total bounty amount is broken down into stepwise payments for each milestone, allowing different individuals to fulfill different pieces of a bounty task. This array stores the amount of wei (or ERC20 token) which will pay out when work is accepted.
Instantiates the variables describing the bounty, while it is in the draft stage. The contract gives `tx.origin` the issuer privileges so that a factory design pattern can be used.
issuer = tx.origin; //this allows for the issuance of a bounty using a factory
issuerContact = _contactInfo;
bountyStage = BountyStages.Draft;
deadline = _deadline;
data = _data;
numMilestones = _numMilestones;
arbiter = _arbiter;
fulfillmentAmounts = _fulfillmentAmounts;
}
```
#### Contribute()
This allows a bounty to receive 3rd party contributions from the crowd. The Ether (or tokens) which are deposited are at the mercy of the issuer, who can at any point call `killBounty()` to drain remaining funds.
```
function contribute (uint value)
payable
isBeforeDeadline
isNotDead
amountIsNotZero(value)
amountEqualsValue(value)
{
ContributionAdded(msg.sender, msg.value);
}
```
#### ActivateBounty()
If the bounty has sufficient funds to pay out each milestone at least once, it can be activated, allowing individuals to add submissions.
```
function activateBounty(uint value)
payable
public
isBeforeDeadline
onlyIssuer
amountEqualsValue(value)
validateFunding
{
transitionToState(BountyStages.Active);
ContributionAdded(msg.sender, msg.value);
BountyActivated(msg.sender);
}
```
#### FulfillBounty()
Once the bounty is active, anyone can fulfill it and submit the necessary deliverables for a given milestone (as long as the deadline has not passed). Anyone can fulfill the bounty, except for the issuer and arbiter, who are disallowed from doing so.
```
function fulfillBounty(string _data, string _dataType, uint _milestoneId)
Submissions can be accepted by the issuer while the bounty is active, and the contract has sufficient funds to pay out all previously accepted submissions. Arbiters also have the ability to accept work, but should only do so after mediating between the issuer and fulfiller to resolve the conflict.
```
function acceptFulfillment(uint _fulfillmentId, uint _milestoneId)