* @dev This bounty will pay out to a researcher if they break invariant logic of the contract.
* This bounty will pay out to a researcher if they break invariant logic of the contract.
*/
*/
contract Bounty is PullPayment, Destructible {
contract Bounty is PullPayment, Destructible {
bool public claimed;
bool public claimed;
...
@@ -16,12 +15,20 @@ contract Bounty is PullPayment, Destructible {
...
@@ -16,12 +15,20 @@ contract Bounty is PullPayment, Destructible {
event TargetCreated(address createdAddress);
event TargetCreated(address createdAddress);
/**
* @dev Fallback function allowing the contract to recieve funds, if they haven't already been claimed.
*/
function() payable {
function() payable {
if (claimed) {
if (claimed) {
throw;
throw;
}
}
}
}
/**
* @dev Create and deploy the target contract (extension of Target contract), and sets the
* msg.sender as a researcher
* @return A target contract
*/
function createTarget() returns(Target) {
function createTarget() returns(Target) {
Target target = Target(deployContract());
Target target = Target(deployContract());
researchers[target] = msg.sender;
researchers[target] = msg.sender;
...
@@ -29,8 +36,16 @@ contract Bounty is PullPayment, Destructible {
...
@@ -29,8 +36,16 @@ contract Bounty is PullPayment, Destructible {
return target;
return target;
}
}
/**
* @dev Internal function to deploy the target contract.
* @return A target contract address
*/
function deployContract() internal returns(address);
function deployContract() internal returns(address);
/**
* @dev Sends the contract funds to the researcher that proved the contract is broken.
* @param Target contract
*/
function claim(Target target) {
function claim(Target target) {
address researcher = researchers[target];
address researcher = researchers[target];
if (researcher == 0) {
if (researcher == 0) {
...
@@ -47,12 +62,17 @@ contract Bounty is PullPayment, Destructible {
...
@@ -47,12 +62,17 @@ contract Bounty is PullPayment, Destructible {
}
}
/*
/**
* Target
* @title Target
*
* @dev Your main contract should inherit from this class and implement the checkInvariant method.
* Your main contract should inherit from this class and implement the checkInvariant method. This is a function that should check everything your contract assumes to be true all the time. If this function returns false, it means your contract was broken in some way and is in an inconsistent state. This is what security researchers will try to acomplish when trying to get the bounty.
*/
*/
contract Target {
contract Target {
/**
* @dev Checks all values a contract assumes to be true all the time. If this function returns
* false, the contract is broken in some way and is in an inconsistent state.
* In order to win the bounty, security researchers will try to cause this broken state.
* @return True if all invariant values are correct, false otherwise.
* @dev inheritable "property" contract that enables methods to be protected by requiring the
* Based on https://github.com/ethereum/dapp-bin/blob/master/wallet/wallet.sol
* acquiescence of either a single, or, crucially, each of a number of, designated owners.
*
* @dev Usage: use modifiers onlyowner (just own owned) or onlymanyowners(hash), whereby the same hash must be provided by some number (specified in constructor) of the set of owners (specified in the constructor) before the interior is executed.
* inheritable "property" contract that enables methods to be protected by requiring the acquiescence of either a single, or, crucially, each of a number of, designated owners.
*
* usage:
* use modifiers onlyowner (just own owned) or onlymanyowners(hash), whereby the same hash must be provided by some number (specified in constructor) of the set of owners (specified in the constructor) before the interior is executed.
*/
*/
contract Shareable {
contract Shareable {
// struct for the status of a pending operation.
// struct for the status of a pending operation.
struct PendingState {
struct PendingState {
uint yetNeeded;
uint yetNeeded;
...
@@ -44,18 +41,25 @@ contract Shareable {
...
@@ -44,18 +41,25 @@ contract Shareable {
}
}
_;
_;
}
}
// multi-sig function modifier: the operation must have an intrinsic hash in order
/**
// that later attempts can be realised as the same underlying operation and
* @dev Modifier for multisig functions.
// thus count as confirmations.
* @param _operation The operation must have an intrinsic hash in order that later attempts can be
* realised as the same underlying operation and thus count as confirmations.
*/
modifier onlymanyowners(bytes32 _operation) {
modifier onlymanyowners(bytes32 _operation) {
if (confirmAndCheck(_operation)) {
if (confirmAndCheck(_operation)) {
_;
_;
}
}
}
}
// constructor is given number of sigs required to do protected "onlymanyowners" transactions
/**
// as well as the selection of addresses capable of confirming them.
* @dev Constructor is given the number of sigs required to do protected "onlymanyowners"
* transactions as well as the selection of addresses capable of confirming them.
* @param _owners A list of owners.
* @param _required The amount required for a transaction to be approved.
* @param _limit Uint to represent the daily limit.
*/
function Shareable(address[] _owners, uint _required) {
function Shareable(address[] _owners, uint _required) {
owners[1] = msg.sender;
owners[1] = msg.sender;
ownerIndex[msg.sender] = 1;
ownerIndex[msg.sender] = 1;
...
@@ -69,7 +73,10 @@ contract Shareable {
...
@@ -69,7 +73,10 @@ contract Shareable {
}
}
}
}
// Revokes a prior confirmation of the given operation
/**
* @dev Revokes a prior confirmation of the given operation.
* @param _operation A string identifying the operation.
*/
function revoke(bytes32 _operation) external {
function revoke(bytes32 _operation) external {
uint index = ownerIndex[msg.sender];
uint index = ownerIndex[msg.sender];
// make sure they're an owner
// make sure they're an owner
...
@@ -85,15 +92,30 @@ contract Shareable {
...
@@ -85,15 +92,30 @@ contract Shareable {
}
}
}
}
// Gets an owner by 0-indexed position (using numOwners as the count)
/**
* @dev Gets an owner by 0-indexed position (using numOwners as the count)
* @param ownerIndex Uint The index of the owner
* @return The address of the owner
*/
function getOwner(uint ownerIndex) external constant returns (address) {
function getOwner(uint ownerIndex) external constant returns (address) {
return address(owners[ownerIndex + 1]);
return address(owners[ownerIndex + 1]);
}
}
/**
* @dev Checks if given address is an owner.
* @param _addr address The address which you want to check.
* @return True if the address is an owner and fase otherwise.
*/
function isOwner(address _addr) constant returns (bool) {
function isOwner(address _addr) constant returns (bool) {
return ownerIndex[_addr] > 0;
return ownerIndex[_addr] > 0;
}
}
/**
* @dev Function to check is specific owner has already confirme the operation.
* @param _operation The operation identifier.
* @param _owner The owner address.
* @return True if the owner has confirmed and false otherwise.
*/
function hasConfirmed(bytes32 _operation, address _owner) constant returns (bool) {
function hasConfirmed(bytes32 _operation, address _owner) constant returns (bool) {