BreakInvariantBounty.sol 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. pragma solidity ^0.4.24;
  2. import "../payment/PullPayment.sol";
  3. import "../ownership/Ownable.sol";
  4. /**
  5. * @title BreakInvariantBounty
  6. * @dev This bounty will pay out to a researcher if they break invariant logic of the contract.
  7. */
  8. contract BreakInvariantBounty is PullPayment, Ownable {
  9. bool private _claimable;
  10. mapping(address => address) private _researchers;
  11. event TargetCreated(address createdAddress);
  12. event BountyCanceled();
  13. constructor() public {
  14. _claimable = true;
  15. }
  16. /**
  17. * @dev Fallback function allowing the contract to receive funds, if they haven't already been claimed.
  18. */
  19. function() external payable {
  20. require(_claimable);
  21. }
  22. /**
  23. * @dev Determine if the bounty is claimable.
  24. * @return false if the bounty was claimed, true otherwise.
  25. */
  26. function claimable() public view returns(bool) {
  27. return _claimable;
  28. }
  29. /**
  30. * @dev Create and deploy the target contract (extension of Target contract), and sets the
  31. * msg.sender as a researcher
  32. * @return A target contract
  33. */
  34. function createTarget() public returns(Target) {
  35. Target target = Target(_deployContract());
  36. _researchers[target] = msg.sender;
  37. emit TargetCreated(target);
  38. return target;
  39. }
  40. /**
  41. * @dev Transfers the contract funds to the researcher that proved the contract is broken.
  42. * @param target contract
  43. */
  44. function claim(Target target) public {
  45. require(_claimable);
  46. address researcher = _researchers[target];
  47. require(researcher != address(0));
  48. // Check Target contract invariants
  49. require(!target.checkInvariant());
  50. _asyncTransfer(researcher, address(this).balance);
  51. _claimable = false;
  52. }
  53. /**
  54. * @dev Cancels the bounty and transfers all funds to the owner
  55. */
  56. function cancelBounty() public onlyOwner{
  57. require(_claimable);
  58. _asyncTransfer(owner(), address(this).balance);
  59. _claimable = false;
  60. emit BountyCanceled();
  61. }
  62. /**
  63. * @dev Internal function to deploy the target contract.
  64. * @return A target contract address
  65. */
  66. function _deployContract() internal returns(address);
  67. }
  68. /**
  69. * @title Target
  70. * @dev Your main contract should inherit from this class and implement the checkInvariant method.
  71. */
  72. contract Target {
  73. /**
  74. * @dev Checks all values a contract assumes to be true all the time. If this function returns
  75. * false, the contract is broken in some way and is in an inconsistent state.
  76. * In order to win the bounty, security researchers will try to cause this broken state.
  77. * @return True if all invariant values are correct, false otherwise.
  78. */
  79. function checkInvariant() public returns(bool);
  80. }