Merge branch 'develop' into multiplemilestones
This commit is contained in:
commit
9fe3d681c7
20
README.md
20
README.md
|
@ -10,15 +10,25 @@ A set of standard contracts to be used as interfaces for any kind of bounty, eit
|
||||||
|
|
||||||
## 1. Rationale
|
## 1. Rationale
|
||||||
|
|
||||||
|
Ethereum smart contracts can trivially facilitate transactions of resources (or tokens) between individuals or groups, but service transactions are more complex. Requesting individuals (issuers) must first approve the work they're receiving before paying out funds, meaning bounty hunters must have trust that the issuer will pay them in the spirit of the original contract.
|
||||||
|
|
||||||
|
The _StandardBounty.sol_ contract facilitates transactions on qualitative data (often representing artifacts of completion of some service), allowing bounty issuers to systematically approve the work they receive.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Bounties can be used to facilitate transactions between two parties, where a quantitative task, qualitative task or artifact is being exchanged for ETH.
|
Bounties can be used to facilitate transactions between two parties, where a quantitative task, qualitative task or artifact is being exchanged for ETH.
|
||||||
|
|
||||||
Code bug bounties are included here as an implemented extension of the generalized bounty and to serve as an example of a pure quantitative bounty that can automatically be paid out.
|
Code bug bounties are included here as an implemented extension of the generalized bounty and to serve as an example of a pure quantitative bounty that can automatically be paid out.
|
||||||
|
|
||||||
## 2. Implementation
|
## 2. Implementation
|
||||||
|
|
||||||
The generalized bounty contract (StandardBounty.sol) is implemented as a State Machine as represented below:
|
A single bounty contract can be used to pay amounts of ETH or a given token, based on the successful completion of specific **Milestones**. The contract aims to reduce the necessary trust in the issuer by forcing them to deposit sufficient Ether (or tokens) to at minimum pay out each milestone once.
|
||||||
|
|
||||||
|
A bounty begins in the `draft` stage, where requirements, deadlines, and reward amounts can still be altered.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
![Bounties State Machine](/standardbountyfsm.png?raw=true "StandardBounty Finite State Machine")
|
|
||||||
|
|
||||||
### 2.1 Invariant check pattern for _CodeBugBounty.sol_
|
### 2.1 Invariant check pattern for _CodeBugBounty.sol_
|
||||||
|
|
||||||
|
@ -29,9 +39,3 @@ If the invariants are not chosen correctly or their code is implemented poorly y
|
||||||
## 3. Development
|
## 3. Development
|
||||||
|
|
||||||
All the extension bounty types (particular cases like _CodeBugBounty.sol_) **musn't** break the state diagram above. They should differ in validation of state change but not in transition rules.
|
All the extension bounty types (particular cases like _CodeBugBounty.sol_) **musn't** break the state diagram above. They should differ in validation of state change but not in transition rules.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,3 +15,89 @@ contract Bountied {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pragma solidity ^0.4.11;
|
||||||
|
import "StandardBounty.sol";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// @title Bountied
|
||||||
|
/// @dev Contract to be tested and that should disburse the
|
||||||
|
/// `fulfillmentAmount` if it is sees its invariant truths broken
|
||||||
|
/// @author Gonçalo Sá <goncalo.sa@consensys.net>, Mark Beylin <mark.beylin@consensys.net>
|
||||||
|
contract Bountied {
|
||||||
|
/// @dev checkInvariant(): function definition of a function that
|
||||||
|
/// returns a boolean of constant truths you wish to maintain in
|
||||||
|
/// this logical copy of your bountied contract
|
||||||
|
|
||||||
|
StandardBounty public bounty;
|
||||||
|
|
||||||
|
address issuer;
|
||||||
|
|
||||||
|
|
||||||
|
modifier onlyIssuer(){
|
||||||
|
require(msg.sender == issuer);
|
||||||
|
_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function bountied(){
|
||||||
|
issuer = msg.sender;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function setContract(address _bountyAddr)
|
||||||
|
onlyIssuer
|
||||||
|
{
|
||||||
|
bounty = StandardBounty(_bountyAddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function checkInvariant() returns(bool){
|
||||||
|
|
||||||
|
if (uint(bounty.bountyStage()) == 0){
|
||||||
|
for (uint i = 0; i < bounty.numMilestones(); i++){
|
||||||
|
if (bounty.numFulfillments(i) != 0 ||
|
||||||
|
bounty.numAccepted(i) != 0 ||
|
||||||
|
bounty.numPaid(i) != 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (uint(bounty.bountyStage()) == 1){
|
||||||
|
for (i = 0; i < bounty.numMilestones(); i++){
|
||||||
|
uint realAccepted = 0;
|
||||||
|
uint realPaid = 0;
|
||||||
|
for (uint j = 0; j < bounty.numFulfillments(i); j++){
|
||||||
|
var(p,a,b,c,d) = bounty.fulfillments(i, j);
|
||||||
|
if (a)
|
||||||
|
realAccepted ++;
|
||||||
|
if (p)
|
||||||
|
realPaid ++;
|
||||||
|
}
|
||||||
|
if (bounty.numFulfillments(i) < bounty.numAccepted(i) ||
|
||||||
|
bounty.numFulfillments(i) < bounty.numPaid(i) ||
|
||||||
|
bounty.numAccepted(i) < bounty.numPaid(i) ||
|
||||||
|
realAccepted != bounty.numAccepted(i) ||
|
||||||
|
realPaid != bounty.numPaid(i))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.balance < bounty.unpaidAmount())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
} else if (uint(bounty.bountyStage()) == 2){
|
||||||
|
|
||||||
|
if (this.balance < bounty.unpaidAmount())
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue