From 7bdefbeb9a39e634e46a91068bf810d9cdd5bb4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Venturo?= Date: Mon, 8 Oct 2018 12:51:11 -0300 Subject: [PATCH] Removed BreakInvariantBounty. --- contracts/drafts/BreakInvariantBounty.sol | 94 ---------------- contracts/mocks/BreakInvariantBountyMock.sol | 33 ------ test/drafts/BreakInvariantBounty.test.js | 110 ------------------- 3 files changed, 237 deletions(-) delete mode 100644 contracts/drafts/BreakInvariantBounty.sol delete mode 100644 contracts/mocks/BreakInvariantBountyMock.sol delete mode 100644 test/drafts/BreakInvariantBounty.test.js diff --git a/contracts/drafts/BreakInvariantBounty.sol b/contracts/drafts/BreakInvariantBounty.sol deleted file mode 100644 index 45417393e..000000000 --- a/contracts/drafts/BreakInvariantBounty.sol +++ /dev/null @@ -1,94 +0,0 @@ -pragma solidity ^0.4.24; - - -import "../Initializable.sol"; -import "../payment/PullPayment.sol"; -import "../ownership/Ownable.sol"; - - -/** - * @title BreakInvariantBounty - * @dev This bounty will pay out to a researcher if they break invariant logic of the contract. - */ -contract BreakInvariantBounty is Initializable, PullPayment, Ownable { - bool private _claimed; - mapping(address => address) private _researchers; - - event TargetCreated(address createdAddress); - - function initialize(address sender) public initializer { - PullPayment.initialize(); - Ownable.initialize(sender); - } - - /** - * @dev Fallback function allowing the contract to receive funds, if they haven't already been claimed. - */ - function() external payable { - require(!_claimed); - } - - /** - * @dev Determine if the bounty was claimed. - * @return true if the bounty was claimed, false otherwise. - */ - function claimed() public view returns(bool) { - return _claimed; - } - - /** - * @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() public returns(Target) { - Target target = Target(_deployContract()); - _researchers[target] = msg.sender; - emit TargetCreated(target); - return target; - } - - /** - * @dev Transfers the contract funds to the researcher that proved the contract is broken. - * @param target contract - */ - function claim(Target target) public { - require(!_claimed); - address researcher = _researchers[target]; - require(researcher != address(0)); - // Check Target contract invariants - require(!target.checkInvariant()); - _asyncTransfer(researcher, address(this).balance); - _claimed = true; - } - - /** - * @dev Transfers the current balance to the owner and terminates the contract. - */ - function destroy() public onlyOwner { - selfdestruct(owner()); - } - - /** - * @dev Internal function to deploy the target contract. - * @return A target contract address - */ - function _deployContract() internal returns(address); - -} - - -/** - * @title Target - * @dev Your main contract should inherit from this class and implement the checkInvariant method. - */ -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. - */ - function checkInvariant() public returns(bool); -} diff --git a/contracts/mocks/BreakInvariantBountyMock.sol b/contracts/mocks/BreakInvariantBountyMock.sol deleted file mode 100644 index 2e4bbefce..000000000 --- a/contracts/mocks/BreakInvariantBountyMock.sol +++ /dev/null @@ -1,33 +0,0 @@ -pragma solidity ^0.4.24; - -// When this line is split, truffle parsing fails. -// See: https://github.com/ethereum/solidity/issues/4871 -// solium-disable-next-line max-len -import {BreakInvariantBounty, Target} from "../drafts/BreakInvariantBounty.sol"; - - -contract TargetMock is Target { - bool private exploited; - - function exploitVulnerability() public { - exploited = true; - } - - function checkInvariant() public returns (bool) { - if (exploited) { - return false; - } - - return true; - } -} - -contract BreakInvariantBountyMock is BreakInvariantBounty { - constructor() public { - BreakInvariantBounty.initialize(msg.sender); - } - - function _deployContract() internal returns (address) { - return new TargetMock(); - } -} diff --git a/test/drafts/BreakInvariantBounty.test.js b/test/drafts/BreakInvariantBounty.test.js deleted file mode 100644 index 037ff53ef..000000000 --- a/test/drafts/BreakInvariantBounty.test.js +++ /dev/null @@ -1,110 +0,0 @@ -const { ethGetBalance, ethSendTransaction } = require('../helpers/web3'); -const expectEvent = require('../helpers/expectEvent'); -const { assertRevert } = require('../helpers/assertRevert'); - -const BreakInvariantBountyMock = artifacts.require('BreakInvariantBountyMock'); -const TargetMock = artifacts.require('TargetMock'); - -require('chai') - .use(require('chai-bignumber')(web3.BigNumber)) - .should(); - -const reward = new web3.BigNumber(web3.toWei(1, 'ether')); - -contract('BreakInvariantBounty', function ([_, owner, researcher, anyone, nonTarget]) { - beforeEach(async function () { - this.bounty = await BreakInvariantBountyMock.new({ from: owner }); - }); - - it('can set reward', async function () { - await ethSendTransaction({ from: owner, to: this.bounty.address, value: reward }); - (await ethGetBalance(this.bounty.address)).should.be.bignumber.equal(reward); - }); - - context('with reward', function () { - beforeEach(async function () { - await ethSendTransaction({ from: owner, to: this.bounty.address, value: reward }); - }); - - describe('destroy', function () { - it('returns all balance to the owner', async function () { - const ownerPreBalance = await ethGetBalance(owner); - await this.bounty.destroy({ from: owner, gasPrice: 0 }); - const ownerPostBalance = await ethGetBalance(owner); - - (await ethGetBalance(this.bounty.address)).should.be.bignumber.equal(0); - ownerPostBalance.sub(ownerPreBalance).should.be.bignumber.equal(reward); - }); - - it('reverts when called by anyone', async function () { - await assertRevert(this.bounty.destroy({ from: anyone })); - }); - }); - - describe('claim', function () { - it('is initially unclaimed', async function () { - (await this.bounty.claimed()).should.equal(false); - }); - - it('can create claimable target', async function () { - const { logs } = await this.bounty.createTarget({ from: researcher }); - expectEvent.inLogs(logs, 'TargetCreated'); - }); - - context('with target', async function () { - beforeEach(async function () { - const { logs } = await this.bounty.createTarget({ from: researcher }); - const event = expectEvent.inLogs(logs, 'TargetCreated'); - this.target = TargetMock.at(event.args.createdAddress); - }); - - context('before exploiting vulnerability', async function () { - it('reverts when claiming reward', async function () { - await assertRevert(this.bounty.claim(this.target.address, { from: researcher })); - }); - }); - - context('after exploiting vulnerability', async function () { - beforeEach(async function () { - await this.target.exploitVulnerability({ from: researcher }); - }); - - it('sends the reward to the researcher', async function () { - await this.bounty.claim(this.target.address, { from: anyone }); - - const researcherPreBalance = await ethGetBalance(researcher); - await this.bounty.withdrawPayments(researcher); - const researcherPostBalance = await ethGetBalance(researcher); - - researcherPostBalance.sub(researcherPreBalance).should.be.bignumber.equal(reward); - (await ethGetBalance(this.bounty.address)).should.be.bignumber.equal(0); - }); - - context('after claiming', async function () { - beforeEach(async function () { - await this.bounty.claim(this.target.address, { from: researcher }); - }); - - it('is claimed', async function () { - (await this.bounty.claimed()).should.equal(true); - }); - - it('no longer accepts rewards', async function () { - await assertRevert(ethSendTransaction({ from: owner, to: this.bounty.address, value: reward })); - }); - - it('reverts when reclaimed', async function () { - await assertRevert(this.bounty.claim(this.target.address, { from: researcher })); - }); - }); - }); - }); - - context('with non-target', function () { - it('reverts when claiming reward', async function () { - await assertRevert(this.bounty.claim(nonTarget, { from: researcher })); - }); - }); - }); - }); -});