From 525a5522b0699fd7ec21e4b2d6dc90ba3854ec24 Mon Sep 17 00:00:00 2001 From: Remco Bloemen Date: Tue, 14 Mar 2017 14:09:59 +0000 Subject: [PATCH] Add TokenKillable --- contracts/lifecycle/TokenKillable.sol | 30 +++++++++++++++++++++++++ test/TokenKillable.js | 32 +++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 contracts/lifecycle/TokenKillable.sol create mode 100644 test/TokenKillable.js diff --git a/contracts/lifecycle/TokenKillable.sol b/contracts/lifecycle/TokenKillable.sol new file mode 100644 index 000000000..e0dfbfe71 --- /dev/null +++ b/contracts/lifecycle/TokenKillable.sol @@ -0,0 +1,30 @@ +pragma solidity ^0.4.8; + + +import "../ownership/Ownable.sol"; +import "../token/ERC20Basic.sol"; + +/// @title TokenKillable: +/// @author Remco Bloemen +///.Base contract that can be killed by owner. All funds in contract including +/// listed tokens will be sent to the owner +contract TokenKillable 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 { + + // Transfer tokens to owner + for(uint i = 0; i < tokens.length; i++) { + ERC20Basic token = ERC20Basic(tokens[i]); + uint256 balance = token.balanceOf(this); + token.transfer(owner, balance); + } + + // Transfer Eth to owner and terminate contract + selfdestruct(owner); + } +} diff --git a/test/TokenKillable.js b/test/TokenKillable.js new file mode 100644 index 000000000..88b06c1b0 --- /dev/null +++ b/test/TokenKillable.js @@ -0,0 +1,32 @@ +'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); + }); +});