BreakInvariantBounty.sol 2.6 KB

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