diff --git a/README.md b/README.md index e80f6ea25..8d8ac3bd4 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ contract MetaCoin is Rejector { For more info see [the Truffle Beta package management tutorial](http://truffleframework.com/tutorials/package-management). ## Security -Zeppelin is meant to provide secure, tested and community-audited code, but please use common sense when doing anything that deals with real money! We take no responsibility for your implementation decisions. +Zeppelin is meant to provide secure, tested and community-audited code, but please use common sense when doing anything that deals with real money! We take no responsibility for your implementation decisions and any security problem you might experience. If you find a security issue, please email [security@openzeppelin.org](mailto:security@openzeppelin.org). diff --git a/contracts/bounties/CrowdsaleTokenBounty.sol b/contracts/bounties/CrowdsaleTokenBounty.sol new file mode 100644 index 000000000..74b4c0cd4 --- /dev/null +++ b/contracts/bounties/CrowdsaleTokenBounty.sol @@ -0,0 +1,38 @@ +pragma solidity ^0.4.0; +import '../PullPayment.sol'; +import '../token/CrowdsaleToken.sol'; + +/* + * Bounty + * This bounty will pay out if you can cause a CrowdsaleToken's balance + * to be lower than its totalSupply, which would mean that it doesn't + * have sufficient ether for everyone to withdraw. + */ +contract CrowdsaleTokenBounty is PullPayment { + + bool public claimed; + mapping(address => address) public researchers; + + function() { + if (claimed) throw; + } + + function createTarget() returns(CrowdsaleToken) { + CrowdsaleToken target = new CrowdsaleToken(); + researchers[target] = msg.sender; + return target; + } + + function claim(CrowdsaleToken target) { + address researcher = researchers[target]; + if (researcher == 0) throw; + // Check CrowdsaleToken contract invariants + // Customize this to the specifics of your contract + if (target.totalSupply() == target.balance) { + throw; + } + asyncSend(researcher, this.balance); + claimed = true; + } + +} diff --git a/contracts/Bounty.sol b/contracts/bounties/SimpleTokenBounty.sol similarity index 88% rename from contracts/Bounty.sol rename to contracts/bounties/SimpleTokenBounty.sol index 3f8bf8d4a..4b54ded6d 100644 --- a/contracts/Bounty.sol +++ b/contracts/bounties/SimpleTokenBounty.sol @@ -1,6 +1,6 @@ pragma solidity ^0.4.0; -import './PullPayment.sol'; -import './token/SimpleToken.sol'; +import '../PullPayment.sol'; +import '../token/SimpleToken.sol'; /* * Bounty @@ -8,7 +8,7 @@ import './token/SimpleToken.sol'; * to be lower than its totalSupply, which would mean that it doesn't * have sufficient ether for everyone to withdraw. */ -contract Bounty is PullPayment { +contract SimpleTokenBounty is PullPayment { bool public claimed; mapping(address => address) public researchers; diff --git a/migrations/2_deploy_contracts.js b/migrations/2_deploy_contracts.js index b29a532cc..8b400d5d1 100644 --- a/migrations/2_deploy_contracts.js +++ b/migrations/2_deploy_contracts.js @@ -2,7 +2,8 @@ module.exports = function(deployer) { deployer.deploy(PullPaymentBid); deployer.deploy(BadArrayUse); deployer.deploy(ProofOfExistence); - deployer.deploy(Bounty); + deployer.deploy(SimpleTokenBounty); + deployer.deploy(CrowdsaleTokenBounty); deployer.deploy(Ownable); deployer.deploy(LimitFunds); };