Skip to content

Commit 41f84f8

Browse files
Aniket-Enggnventuro
authored andcommitted
Removed selfdestruct from BreakInvariantBounty (#1385)
* signing prefix added * Minor improvement * Tests changed * Successfully tested * Minor improvements * Minor improvements * Revert "Dangling commas are now required. (#1359)" This reverts commit a688977. * updates * fixes #1384 * introduced claimable and cancelBounty * cancelBounty tests * Update BreakInvariantBounty.test.js
1 parent b17de01 commit 41f84f8

File tree

2 files changed

+58
-31
lines changed

2 files changed

+58
-31
lines changed

contracts/bounties/BreakInvariantBounty.sol

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,25 @@ import "../ownership/Ownable.sol";
88
* @dev This bounty will pay out to a researcher if they break invariant logic of the contract.
99
*/
1010
contract BreakInvariantBounty is PullPayment, Ownable {
11-
bool private _claimed;
11+
bool private _claimable = true;
1212
mapping(address => address) private _researchers;
1313

1414
event TargetCreated(address createdAddress);
15+
event BountyCanceled();
1516

1617
/**
1718
* @dev Fallback function allowing the contract to receive funds, if they haven't already been claimed.
1819
*/
1920
function() external payable {
20-
require(!_claimed);
21+
require(_claimable);
2122
}
2223

2324
/**
24-
* @dev Determine if the bounty was claimed.
25-
* @return true if the bounty was claimed, false otherwise.
25+
* @dev Determine if the bounty is claimable.
26+
* @return false if the bounty was claimed, true otherwise.
2627
*/
27-
function claimed() public view returns(bool) {
28-
return _claimed;
28+
function claimable() public view returns(bool) {
29+
return _claimable;
2930
}
3031

3132
/**
@@ -45,20 +46,23 @@ contract BreakInvariantBounty is PullPayment, Ownable {
4546
* @param target contract
4647
*/
4748
function claim(Target target) public {
48-
require(!_claimed);
49+
require(_claimable);
4950
address researcher = _researchers[target];
5051
require(researcher != address(0));
5152
// Check Target contract invariants
5253
require(!target.checkInvariant());
5354
_asyncTransfer(researcher, address(this).balance);
54-
_claimed = true;
55+
_claimable = false;
5556
}
5657

5758
/**
58-
* @dev Transfers the current balance to the owner and terminates the contract.
59+
* @dev Cancels the bounty and transfers all funds to the owner
5960
*/
60-
function destroy() public onlyOwner {
61-
selfdestruct(owner());
61+
function cancelBounty() public onlyOwner{
62+
require(_claimable);
63+
_asyncTransfer(owner(), address(this).balance);
64+
_claimable = false;
65+
emit BountyCanceled();
6266
}
6367

6468
/**

test/BreakInvariantBounty.test.js

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const { ethGetBalance, ethSendTransaction } = require('./helpers/web3');
2+
const { ether } = require('./helpers/ether');
23
const { sendEther } = require('./helpers/sendTransaction');
34
const { balanceDifference } = require('./helpers/balanceDiff');
45
const expectEvent = require('./helpers/expectEvent');
@@ -11,7 +12,7 @@ require('chai')
1112
.use(require('chai-bignumber')(web3.BigNumber))
1213
.should();
1314

14-
const reward = new web3.BigNumber(web3.toWei(1, 'ether'));
15+
const reward = ether(1);
1516

1617
contract('BreakInvariantBounty', function ([_, owner, researcher, anyone, nonTarget]) {
1718
beforeEach(async function () {
@@ -28,24 +29,9 @@ contract('BreakInvariantBounty', function ([_, owner, researcher, anyone, nonTar
2829
await sendEther(owner, this.bounty.address, reward);
2930
});
3031

31-
describe('destroy', function () {
32-
it('returns all balance to the owner', async function () {
33-
const ownerPreBalance = await ethGetBalance(owner);
34-
await this.bounty.destroy({ from: owner, gasPrice: 0 });
35-
const ownerPostBalance = await ethGetBalance(owner);
36-
37-
(await ethGetBalance(this.bounty.address)).should.be.bignumber.equal(0);
38-
ownerPostBalance.sub(ownerPreBalance).should.be.bignumber.equal(reward);
39-
});
40-
41-
it('reverts when called by anyone', async function () {
42-
await assertRevert(this.bounty.destroy({ from: anyone }));
43-
});
44-
});
45-
4632
describe('claim', function () {
47-
it('is initially unclaimed', async function () {
48-
(await this.bounty.claimed()).should.equal(false);
33+
it('is initially claimable', async function () {
34+
(await this.bounty.claimable()).should.equal(true);
4935
});
5036

5137
it('can create claimable target', async function () {
@@ -83,8 +69,8 @@ contract('BreakInvariantBounty', function ([_, owner, researcher, anyone, nonTar
8369
await this.bounty.claim(this.target.address, { from: researcher });
8470
});
8571

86-
it('is claimed', async function () {
87-
(await this.bounty.claimed()).should.equal(true);
72+
it('is not claimable', async function () {
73+
(await this.bounty.claimable()).should.equal(false);
8874
});
8975

9076
it('no longer accepts rewards', async function () {
@@ -104,5 +90,42 @@ contract('BreakInvariantBounty', function ([_, owner, researcher, anyone, nonTar
10490
});
10591
});
10692
});
93+
94+
describe('cancelBounty', function () {
95+
context('before canceling', function () {
96+
it('is claimable', async function () {
97+
(await this.bounty.claimable()).should.equal(true);
98+
});
99+
100+
it('can be canceled by the owner', async function () {
101+
const { logs } = await this.bounty.cancelBounty({ from: owner });
102+
expectEvent.inLogs(logs, 'BountyCanceled');
103+
(await balanceDifference(owner, () => this.bounty.withdrawPayments(owner)))
104+
.should.be.bignumber.equal(reward);
105+
});
106+
107+
it('reverts when canceled by anyone', async function () {
108+
await assertRevert(this.bounty.cancelBounty({ from: anyone }));
109+
});
110+
});
111+
112+
context('after canceling', async function () {
113+
beforeEach(async function () {
114+
await this.bounty.cancelBounty({ from: owner });
115+
});
116+
117+
it('is not claimable', async function () {
118+
(await this.bounty.claimable()).should.equal(false);
119+
});
120+
121+
it('no longer accepts rewards', async function () {
122+
await assertRevert(ethSendTransaction({ from: owner, to: this.bounty.address, value: reward }));
123+
});
124+
125+
it('reverts when recanceled', async function () {
126+
await assertRevert(this.bounty.cancelBounty({ from: owner }));
127+
});
128+
});
129+
});
107130
});
108131
});

0 commit comments

Comments
 (0)