Merge pull request #187 from DavidKnott/change-killable-contract-to-destructible

Change killable to destructible and kill to destroy
pull/185/head
Manuel Aráoz 8 years ago committed by GitHub
commit 0328250554
  1. 4
      contracts/Bounty.sol
  2. 4
      contracts/MultisigWallet.sol
  3. 15
      contracts/lifecycle/Destructible.sol
  4. 15
      contracts/lifecycle/Killable.sol
  5. 8
      contracts/lifecycle/TokenDestructible.sol
  6. 4
      docs/source/bounty.rst
  7. 2
      docs/source/index.rst
  8. 6
      docs/source/killable.rst
  9. 4
      test/Bounty.js
  10. 18
      test/Destructible.js
  11. 18
      test/Killable.js
  12. 8
      test/MultisigWallet.js
  13. 32
      test/TokenDestructible.js
  14. 32
      test/TokenKillable.js

@ -2,7 +2,7 @@ pragma solidity ^0.4.8;
import './payment/PullPayment.sol';
import './lifecycle/Killable.sol';
import './lifecycle/Destructible.sol';
/*
@ -10,7 +10,7 @@ import './lifecycle/Killable.sol';
*
* This bounty will pay out to a researcher if they break invariant logic of the contract.
*/
contract Bounty is PullPayment, Killable {
contract Bounty is PullPayment, Destructible {
bool public claimed;
mapping(address => address) public researchers;

@ -24,8 +24,8 @@ contract MultisigWallet is Multisig, Shareable, DayLimit {
Shareable(_owners, _required)
DayLimit(_daylimit) { }
// kills the contract sending everything to `_to`.
function kill(address _to) onlymanyowners(keccak256(msg.data)) external {
// destroys the contract sending everything to `_to`.
function destroy(address _to) onlymanyowners(keccak256(msg.data)) external {
selfdestruct(_to);
}

@ -0,0 +1,15 @@
pragma solidity ^0.4.8;
import "../ownership/Ownable.sol";
/*
* Destructible
* Base contract that can be destroyed by owner. All funds in contract will be sent to the owner.
*/
contract Destructible is Ownable {
function destroy() onlyOwner {
selfdestruct(owner);
}
}

@ -1,15 +0,0 @@
pragma solidity ^0.4.8;
import "../ownership/Ownable.sol";
/*
* Killable
* Base contract that can be killed by owner. All funds in contract will be sent to the owner.
*/
contract Killable is Ownable {
function kill() onlyOwner {
selfdestruct(owner);
}
}

@ -4,18 +4,18 @@ pragma solidity ^0.4.8;
import "../ownership/Ownable.sol";
import "../token/ERC20Basic.sol";
/// @title TokenKillable:
/// @title TokenDestructible:
/// @author Remco Bloemen <remco@2π.com>
///.Base contract that can be killed by owner. All funds in contract including
///.Base contract that can be destroyed by owner. All funds in contract including
/// listed tokens will be sent to the owner
contract TokenKillable is Ownable {
contract TokenDestructible is Ownable {
/// @notice Terminate contract and refund to owner
/// @param tokens List of addresses of ERC20 or ERC20Basic token contracts to
// refund
/// @notice The called token contracts could try to re-enter this contract.
// Only supply token contracts you
function kill(address[] tokens) onlyOwner {
function destroy(address[] tokens) onlyOwner {
// Transfer tokens to owner
for(uint i = 0; i < tokens.length; i++) {

@ -55,6 +55,6 @@ If researchers break the contract, they can claim their reward.
For each researcher who wants to hack the contract and claims the reward, refer to our `Test <https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/test/Bounty.js/>`_ for the detail.
Finally, if you manage to protect your contract from security researchers, you can reclaim the bounty funds. To end the bounty, kill the contract so that all the rewards go back to the owner.::
Finally, if you manage to protect your contract from security researchers, you can reclaim the bounty funds. To end the bounty, destroy the contract so that all the rewards go back to the owner.::
bounty.kill();
bounty.destroy();

@ -27,7 +27,7 @@ The code is open-source, and `available on github <https://github.com/OpenZeppel
ownable
Pausable
killable
destructible
claimable
migrations
safemath

@ -1,11 +1,11 @@
Killable
Destructible
=============================================
Base contract that can be killed by owner.
Base contract that can be destroyed by owner.
Inherits from contract Ownable.
kill( ) onlyOwner
destroy( ) onlyOwner
"""""""""""""""""""
Destroys the contract and sends funds back to the owner.

@ -31,7 +31,7 @@ contract('Bounty', function(accounts) {
assert.equal(reward, web3.eth.getBalance(bounty.address).toNumber());
});
it('empties itself when killed', async function(){
it('empties itself when destroyed', async function(){
let owner = accounts[0];
let reward = web3.toWei(1, 'ether');
let bounty = await SecureTargetBounty.new();
@ -39,7 +39,7 @@ contract('Bounty', function(accounts) {
assert.equal(reward, web3.eth.getBalance(bounty.address).toNumber());
await bounty.kill();
await bounty.destroy();
assert.equal(0, web3.eth.getBalance(bounty.address).toNumber());
});

@ -0,0 +1,18 @@
'use strict';
var Destructible = artifacts.require('../contracts/lifecycle/Destructible.sol');
require('./helpers/transactionMined.js');
contract('Destructible', function(accounts) {
it('should send balance to owner after destruction', async function() {
let destructible = await Destructible.new({from: accounts[0], value: web3.toWei('10','ether')});
let owner = await destructible.owner();
let initBalance = web3.eth.getBalance(owner);
await destructible.destroy({from: owner});
let newBalance = web3.eth.getBalance(owner);
assert.isTrue(newBalance > initBalance);
});
});

@ -1,18 +0,0 @@
'use strict';
var Killable = artifacts.require('../contracts/lifecycle/Killable.sol');
require('./helpers/transactionMined.js');
contract('Killable', function(accounts) {
it('should send balance to owner after death', async function() {
let killable = await Killable.new({from: accounts[0], value: web3.toWei('10','ether')});
let owner = await killable.owner();
let initBalance = web3.eth.getBalance(owner);
await killable.kill({from: owner});
let newBalance = web3.eth.getBalance(owner);
assert.isTrue(newBalance > initBalance);
});
});

@ -22,11 +22,11 @@ contract('MultisigWallet', function(accounts) {
let walletBalance = web3.eth.getBalance(wallet.address);
let hash = 1234;
//Call kill function from two different owner accounts, satisfying owners required
await wallet.kill(accounts[0], {data: hash});
let txnHash = await wallet.kill(accounts[0], {from: accounts[1], data: hash});
//Call destroy function from two different owner accounts, satisfying owners required
await wallet.destroy(accounts[0], {data: hash});
let txnHash = await wallet.destroy(accounts[0], {from: accounts[1], data: hash});
//Get balances of owner and wallet after kill function is complete, compare with previous values
//Get balances of owner and wallet after destroy function is complete, compare with previous values
let newOwnerBalance = web3.eth.getBalance(accounts[0]);
let newWalletBalance = web3.eth.getBalance(wallet.address);

@ -0,0 +1,32 @@
'use strict';
var TokenDestructible = artifacts.require('../contracts/lifecycle/TokenDestructible.sol');
var StandardTokenMock = artifacts.require("./helpers/StandardTokenMock.sol");
require('./helpers/transactionMined.js');
contract('TokenDestructible', function(accounts) {
it('should send balance to owner after destruction', async function() {
let destructible = await TokenDestructible.new({from: accounts[0], value: web3.toWei('10','ether')});
let owner = await destructible.owner();
let initBalance = web3.eth.getBalance(owner);
await destructible.destroy([], {from: owner});
let newBalance = web3.eth.getBalance(owner);
assert.isTrue(newBalance > initBalance);
});
it('should send tokens to owner after destruction', async function() {
let destructible = await TokenDestructible.new({from: accounts[0], value: web3.toWei('10','ether')});
let owner = await destructible.owner();
let token = await StandardTokenMock.new(destructible.address, 100);
let initContractBalance = await token.balanceOf(destructible.address);
let initOwnerBalance = await token.balanceOf(owner);
assert.equal(initContractBalance, 100);
assert.equal(initOwnerBalance, 0);
await destructible.destroy([token.address], {from: owner});
let newContractBalance = await token.balanceOf(destructible.address);
let newOwnerBalance = await token.balanceOf(owner);
assert.equal(newContractBalance, 0);
assert.equal(newOwnerBalance, 100);
});
});

@ -1,32 +0,0 @@
'use strict';
var TokenKillable = artifacts.require('../contracts/lifecycle/TokenKillable.sol');
var StandardTokenMock = artifacts.require("./helpers/StandardTokenMock.sol");
require('./helpers/transactionMined.js');
contract('TokenKillable', function(accounts) {
it('should send balance to owner after death', async function() {
let killable = await TokenKillable.new({from: accounts[0], value: web3.toWei('10','ether')});
let owner = await killable.owner();
let initBalance = web3.eth.getBalance(owner);
await killable.kill([], {from: owner});
let newBalance = web3.eth.getBalance(owner);
assert.isTrue(newBalance > initBalance);
});
it('should send tokens to owner after death', async function() {
let killable = await TokenKillable.new({from: accounts[0], value: web3.toWei('10','ether')});
let owner = await killable.owner();
let token = await StandardTokenMock.new(killable.address, 100);
let initContractBalance = await token.balanceOf(killable.address);
let initOwnerBalance = await token.balanceOf(owner);
assert.equal(initContractBalance, 100);
assert.equal(initOwnerBalance, 0);
await killable.kill([token.address], {from: owner});
let newContractBalance = await token.balanceOf(killable.address);
let newOwnerBalance = await token.balanceOf(owner);
assert.equal(newContractBalance, 0);
assert.equal(newOwnerBalance, 100);
});
});
Loading…
Cancel
Save