diff --git a/contracts/bounties/BreakInvariantBounty.sol b/contracts/bounties/BreakInvariantBounty.sol index 1677fb5abb2..b8b97977eb9 100644 --- a/contracts/bounties/BreakInvariantBounty.sol +++ b/contracts/bounties/BreakInvariantBounty.sol @@ -2,14 +2,13 @@ pragma solidity ^0.4.24; import "../payment/PullPayment.sol"; -import "../lifecycle/Destructible.sol"; /** * @title BreakInvariantBounty * @dev This bounty will pay out to a researcher if they break invariant logic of the contract. */ -contract BreakInvariantBounty is PullPayment, Destructible { +contract BreakInvariantBounty is PullPayment, Ownable { bool public claimed; mapping(address => address) public researchers; @@ -47,6 +46,13 @@ contract BreakInvariantBounty is PullPayment, Destructible { 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 diff --git a/contracts/lifecycle/Destructible.sol b/contracts/lifecycle/Destructible.sol deleted file mode 100644 index c10630d88dc..00000000000 --- a/contracts/lifecycle/Destructible.sol +++ /dev/null @@ -1,22 +0,0 @@ -pragma solidity ^0.4.24; - - -import "../ownership/Ownable.sol"; - - -/** - * @title Destructible - * @dev Base contract that can be destroyed by owner. All funds in contract will be sent to the owner. - */ -contract Destructible is Ownable { - /** - * @dev Transfers the current balance to the owner and terminates the contract. - */ - function destroy() public onlyOwner { - selfdestruct(owner); - } - - function destroyAndSend(address _recipient) public onlyOwner { - selfdestruct(_recipient); - } -} diff --git a/contracts/lifecycle/TokenDestructible.sol b/contracts/lifecycle/TokenDestructible.sol deleted file mode 100644 index 783a4e7887b..00000000000 --- a/contracts/lifecycle/TokenDestructible.sol +++ /dev/null @@ -1,36 +0,0 @@ -pragma solidity ^0.4.24; - -import "../ownership/Ownable.sol"; -import "../token/ERC20/IERC20.sol"; - - -/** - * @title TokenDestructible: - * @author Remco Bloemen - * @dev Base contract that can be destroyed by owner. All funds in contract including - * listed tokens will be sent to the owner. - */ -contract TokenDestructible is Ownable { - - constructor() public payable { } - - /** - * @notice Terminate contract and refund to owner - * @param _tokens List of addresses of ERC20 token contracts to - refund. - * @notice The called token contracts could try to re-enter this contract. Only - supply token contracts you trust. - */ - function destroy(address[] _tokens) public onlyOwner { - - // Transfer tokens to owner - for (uint256 i = 0; i < _tokens.length; i++) { - IERC20 token = IERC20(_tokens[i]); - uint256 balance = token.balanceOf(this); - token.transfer(owner, balance); - } - - // Transfer Eth to owner and terminate contract - selfdestruct(owner); - } -} diff --git a/contracts/mocks/DestructibleMock.sol b/contracts/mocks/DestructibleMock.sol deleted file mode 100644 index 5fb1bbbc662..00000000000 --- a/contracts/mocks/DestructibleMock.sol +++ /dev/null @@ -1,8 +0,0 @@ -pragma solidity ^0.4.24; - -import "../lifecycle/Destructible.sol"; - - -contract DestructibleMock is Destructible { - function() public payable {} -} diff --git a/contracts/mocks/ERC223TokenMock.sol b/contracts/mocks/ERC223TokenMock.sol deleted file mode 100644 index de3dec54456..00000000000 --- a/contracts/mocks/ERC223TokenMock.sol +++ /dev/null @@ -1,33 +0,0 @@ -pragma solidity ^0.4.24; - -import "../token/ERC20/ERC20.sol"; - - -contract ERC223ContractInterface { - function tokenFallback(address _from, uint256 _value, bytes _data) external; -} - - -contract ERC223TokenMock is ERC20 { - - constructor(address _initialAccount, uint256 _initialBalance) public { - _mint(_initialAccount, _initialBalance); - } - - // ERC223 compatible transfer function (except the name) - function transferERC223(address _to, uint256 _value, bytes _data) public - returns (bool success) - { - transfer(_to, _value); - bool isContract = false; - // solium-disable-next-line security/no-inline-assembly - assembly { - isContract := not(iszero(extcodesize(_to))) - } - if (isContract) { - ERC223ContractInterface receiver = ERC223ContractInterface(_to); - receiver.tokenFallback(msg.sender, _value, _data); - } - return true; - } -} diff --git a/contracts/mocks/HasNoEtherTest.sol b/contracts/mocks/HasNoEtherTest.sol deleted file mode 100644 index 46798845887..00000000000 --- a/contracts/mocks/HasNoEtherTest.sol +++ /dev/null @@ -1,12 +0,0 @@ -pragma solidity ^0.4.24; - -import "../../contracts/ownership/HasNoEther.sol"; - - -contract HasNoEtherTest is HasNoEther { - - // Constructor with explicit payable — should still fail - constructor() public payable { - } - -} diff --git a/contracts/ownership/Contactable.sol b/contracts/ownership/Contactable.sol deleted file mode 100644 index 9ed32cbbb7a..00000000000 --- a/contracts/ownership/Contactable.sol +++ /dev/null @@ -1,22 +0,0 @@ -pragma solidity ^0.4.24; - -import "./Ownable.sol"; - - -/** - * @title Contactable token - * @dev Basic version of a contactable contract, allowing the owner to provide a string with their - * contact information. - */ -contract Contactable is Ownable { - - string public contactInformation; - - /** - * @dev Allows the owner to set a string with their contact information. - * @param _info The contact information to attach to the contract. - */ - function setContactInformation(string _info) public onlyOwner { - contactInformation = _info; - } -} diff --git a/contracts/ownership/HasNoContracts.sol b/contracts/ownership/HasNoContracts.sol deleted file mode 100644 index f73cc6e5852..00000000000 --- a/contracts/ownership/HasNoContracts.sol +++ /dev/null @@ -1,22 +0,0 @@ -pragma solidity ^0.4.24; - -import "./Ownable.sol"; - - -/** - * @title Contracts that should not own Contracts - * @author Remco Bloemen - * @dev Should contracts (anything Ownable) end up being owned by this contract, it allows the owner - * of this contract to reclaim ownership of the contracts. - */ -contract HasNoContracts is Ownable { - - /** - * @dev Reclaim ownership of Ownable contracts - * @param _contractAddr The address of the Ownable to be reclaimed. - */ - function reclaimContract(address _contractAddr) external onlyOwner { - Ownable contractInst = Ownable(_contractAddr); - contractInst.transferOwnership(owner); - } -} diff --git a/contracts/ownership/HasNoEther.sol b/contracts/ownership/HasNoEther.sol deleted file mode 100644 index cdccd4f5ae3..00000000000 --- a/contracts/ownership/HasNoEther.sol +++ /dev/null @@ -1,41 +0,0 @@ -pragma solidity ^0.4.24; - -import "./Ownable.sol"; - - -/** - * @title Contracts that should not own Ether - * @author Remco Bloemen - * @dev This tries to block incoming ether to prevent accidental loss of Ether. Should Ether end up - * in the contract, it will allow the owner to reclaim this Ether. - * @notice Ether can still be sent to this contract by: - * calling functions labeled `payable` - * `selfdestruct(contract_address)` - * mining directly to the contract address - */ -contract HasNoEther is Ownable { - - /** - * @dev Constructor that rejects incoming Ether - * The `payable` flag is added so we can access `msg.value` without compiler warning. If we - * leave out payable, then Solidity will allow inheriting contracts to implement a payable - * constructor. By doing it this way we prevent a payable constructor from working. Alternatively - * we could use assembly to access msg.value. - */ - constructor() public payable { - require(msg.value == 0); - } - - /** - * @dev Disallows direct send by setting a default function without the `payable` flag. - */ - function() external { - } - - /** - * @dev Transfer all Ether held by the contract to the owner. - */ - function reclaimEther() external onlyOwner { - owner.transfer(address(this).balance); - } -} diff --git a/contracts/ownership/HasNoTokens.sol b/contracts/ownership/HasNoTokens.sol deleted file mode 100644 index 563a6404701..00000000000 --- a/contracts/ownership/HasNoTokens.sol +++ /dev/null @@ -1,35 +0,0 @@ -pragma solidity ^0.4.24; - -import "./CanReclaimToken.sol"; - - -/** - * @title Contracts that should not own Tokens - * @author Remco Bloemen - * @dev This blocks incoming ERC223 tokens to prevent accidental loss of tokens. - * Should tokens (any ERC20 compatible) end up in the contract, it allows the - * owner to reclaim the tokens. - */ -contract HasNoTokens is CanReclaimToken { - - /** - * @dev Reject all ERC223 compatible tokens - * @param _from address The address that is transferring the tokens - * @param _value uint256 the amount of the specified token - * @param _data Bytes The data passed from the caller. - */ - function tokenFallback( - address _from, - uint256 _value, - bytes _data - ) - external - pure - { - _from; - _value; - _data; - revert(); - } - -} diff --git a/contracts/ownership/NoOwner.sol b/contracts/ownership/NoOwner.sol deleted file mode 100644 index 42c3131dc04..00000000000 --- a/contracts/ownership/NoOwner.sol +++ /dev/null @@ -1,15 +0,0 @@ -pragma solidity ^0.4.24; - -import "./HasNoEther.sol"; -import "./HasNoTokens.sol"; -import "./HasNoContracts.sol"; - - -/** - * @title Base contract for contracts that should not own things. - * @author Remco Bloemen - * @dev Solves a class of errors where a contract accidentally becomes owner of Ether, Tokens or - * Owned contracts. See respective base contracts for details. - */ -contract NoOwner is HasNoEther, HasNoTokens, HasNoContracts { -} diff --git a/contracts/token/ERC721/IDeprecatedERC721.sol b/contracts/token/ERC721/IDeprecatedERC721.sol deleted file mode 100644 index 5913d4476da..00000000000 --- a/contracts/token/ERC721/IDeprecatedERC721.sol +++ /dev/null @@ -1,15 +0,0 @@ -pragma solidity ^0.4.24; - -import "./IERC721.sol"; - - -/** - * @title ERC-721 methods shipped in OpenZeppelin v1.7.0, removed in the latest version of the standard - * @dev Only use this interface for compatibility with previously deployed contracts - * Use ERC721 for interacting with new contracts which are standard-compliant - */ -contract IDeprecatedERC721 is IERC721 { - function takeOwnership(uint256 _tokenId) public; - function transfer(address _to, uint256 _tokenId) public; - function tokensOf(address _owner) public view returns (uint256[]); -} diff --git a/test/lifecycle/Destructible.test.js b/test/lifecycle/Destructible.test.js deleted file mode 100644 index a2ba054c175..00000000000 --- a/test/lifecycle/Destructible.test.js +++ /dev/null @@ -1,33 +0,0 @@ -const DestructibleMock = artifacts.require('DestructibleMock'); -const { ethGetBalance } = require('../helpers/web3'); - -const BigNumber = web3.BigNumber; - -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); - -contract('Destructible', function ([_, owner, recipient]) { - beforeEach(async function () { - this.destructible = await DestructibleMock.new({ from: owner }); - await web3.eth.sendTransaction({ - from: owner, - to: this.destructible.address, - value: web3.toWei('10', 'ether'), - }); - }); - - it('should send balance to owner after destruction', async function () { - const initBalance = await ethGetBalance(owner); - await this.destructible.destroy({ from: owner }); - const newBalance = await ethGetBalance(owner); - newBalance.should.be.bignumber.gt(initBalance); - }); - - it('should send balance to recepient after destruction', async function () { - const initBalance = await ethGetBalance(recipient); - await this.destructible.destroyAndSend(recipient, { from: owner }); - const newBalance = await ethGetBalance(recipient); - newBalance.should.be.bignumber.gt(initBalance); - }); -}); diff --git a/test/lifecycle/TokenDestructible.test.js b/test/lifecycle/TokenDestructible.test.js deleted file mode 100644 index 7e61d800f72..00000000000 --- a/test/lifecycle/TokenDestructible.test.js +++ /dev/null @@ -1,39 +0,0 @@ -const { ethGetBalance } = require('../helpers/web3'); - -const TokenDestructible = artifacts.require('TokenDestructible'); -const ERC20Mock = artifacts.require('ERC20Mock'); - -const BigNumber = web3.BigNumber; - -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); - -contract('TokenDestructible', function ([_, owner]) { - let tokenDestructible; - - beforeEach(async function () { - tokenDestructible = await TokenDestructible.new({ - from: owner, - value: web3.toWei('10', 'ether'), - }); - }); - - it('should send balance to owner after destruction', async function () { - const initBalance = await ethGetBalance(owner); - await tokenDestructible.destroy([], { from: owner }); - - const newBalance = await ethGetBalance(owner); - newBalance.should.be.bignumber.gt(initBalance); - }); - - it('should send tokens to owner after destruction', async function () { - const token = await ERC20Mock.new(tokenDestructible.address, 100); - (await token.balanceOf(tokenDestructible.address)).should.be.bignumber.equal(100); - (await token.balanceOf(owner)).should.be.bignumber.equal(0); - - await tokenDestructible.destroy([token.address], { from: owner }); - (await token.balanceOf(tokenDestructible.address)).should.be.bignumber.equal(0); - (await token.balanceOf(owner)).should.be.bignumber.equal(100); - }); -}); diff --git a/test/ownership/Contactable.test.js b/test/ownership/Contactable.test.js deleted file mode 100644 index bae2d201a9d..00000000000 --- a/test/ownership/Contactable.test.js +++ /dev/null @@ -1,25 +0,0 @@ -const Contactable = artifacts.require('Contactable'); - -contract('Contactable', function () { - let contactable; - - beforeEach(async function () { - contactable = await Contactable.new(); - }); - - it('should have an empty contact info', async function () { - (await contactable.contactInformation()).should.equal(''); - }); - - describe('after setting the contact information', function () { - const contactInfo = 'contact information'; - - beforeEach(async function () { - await contactable.setContactInformation(contactInfo); - }); - - it('should return the setted contact information', async function () { - (await contactable.contactInformation()).should.equal(contactInfo); - }); - }); -}); diff --git a/test/ownership/HasNoContracts.test.js b/test/ownership/HasNoContracts.test.js deleted file mode 100644 index f900fb1cb5a..00000000000 --- a/test/ownership/HasNoContracts.test.js +++ /dev/null @@ -1,29 +0,0 @@ -const { expectThrow } = require('../helpers/expectThrow'); - -const Ownable = artifacts.require('Ownable'); -const HasNoContracts = artifacts.require('HasNoContracts'); - -contract('HasNoContracts', function ([_, owner, anyone]) { - let hasNoContracts = null; - let ownable = null; - - beforeEach(async function () { - // Create contract and token - hasNoContracts = await HasNoContracts.new({ from: owner }); - ownable = await Ownable.new({ from: owner }); - - // Force ownership into contract - await ownable.transferOwnership(hasNoContracts.address, { from: owner }); - }); - - it('should allow owner to reclaim contracts', async function () { - await hasNoContracts.reclaimContract(ownable.address, { from: owner }); - (await ownable.owner()).should.equal(owner); - }); - - it('should allow only owner to reclaim contracts', async function () { - await expectThrow( - hasNoContracts.reclaimContract(ownable.address, { from: anyone }) - ); - }); -}); diff --git a/test/ownership/HasNoEther.test.js b/test/ownership/HasNoEther.test.js deleted file mode 100644 index 7f03f1a62a9..00000000000 --- a/test/ownership/HasNoEther.test.js +++ /dev/null @@ -1,61 +0,0 @@ -const { expectThrow } = require('../helpers/expectThrow'); -const { ethSendTransaction, ethGetBalance } = require('../helpers/web3'); - -const HasNoEtherTest = artifacts.require('HasNoEtherTest'); -const ForceEther = artifacts.require('ForceEther'); - -const BigNumber = web3.BigNumber; - -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); - -contract('HasNoEther', function ([_, owner, anyone]) { - const amount = web3.toWei('1', 'ether'); - - beforeEach(async function () { - this.hasNoEther = await HasNoEtherTest.new({ from: owner }); - }); - - it('should not accept ether in constructor', async function () { - await expectThrow(HasNoEtherTest.new({ value: amount })); - }); - - it('should not accept ether', async function () { - await expectThrow( - ethSendTransaction({ - from: owner, - to: this.hasNoEther.address, - value: amount, - }), - ); - }); - - it('should allow owner to reclaim ether', async function () { - const startBalance = await ethGetBalance(this.hasNoEther.address); - startBalance.should.be.bignumber.equal(0); - - // Force ether into it - const forceEther = await ForceEther.new({ value: amount }); - await forceEther.destroyAndSend(this.hasNoEther.address); - (await ethGetBalance(this.hasNoEther.address)).should.be.bignumber.equal(amount); - - // Reclaim - const ownerStartBalance = await ethGetBalance(owner); - await this.hasNoEther.reclaimEther({ from: owner }); - const ownerFinalBalance = await ethGetBalance(owner); - ownerFinalBalance.should.be.bignumber.gt(ownerStartBalance); - - (await ethGetBalance(this.hasNoEther.address)).should.be.bignumber.equal(0); - }); - - it('should allow only owner to reclaim ether', async function () { - // Force ether into it - const forceEther = await ForceEther.new({ value: amount }); - await forceEther.destroyAndSend(this.hasNoEther.address); - (await ethGetBalance(this.hasNoEther.address)).should.be.bignumber.equal(amount); - - // Reclaim - await expectThrow(this.hasNoEther.reclaimEther({ from: anyone })); - }); -}); diff --git a/test/ownership/HasNoTokens.test.js b/test/ownership/HasNoTokens.test.js deleted file mode 100644 index 2a62dafb76a..00000000000 --- a/test/ownership/HasNoTokens.test.js +++ /dev/null @@ -1,46 +0,0 @@ -const { expectThrow } = require('../helpers/expectThrow'); - -const HasNoTokens = artifacts.require('HasNoTokens'); -const ERC223TokenMock = artifacts.require('ERC223TokenMock'); - -const BigNumber = web3.BigNumber; - -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); - -contract('HasNoTokens', function ([_, owner, initialAccount, anyone]) { - let hasNoTokens = null; - let token = null; - - beforeEach(async function () { - // Create contract and token - hasNoTokens = await HasNoTokens.new({ from: owner }); - token = await ERC223TokenMock.new(initialAccount, 100); - - // Force token into contract - await token.transfer(hasNoTokens.address, 10, { from: initialAccount }); - - (await token.balanceOf(hasNoTokens.address)).should.be.bignumber.equal(10); - }); - - it('should not accept ERC223 tokens', async function () { - await expectThrow(token.transferERC223(hasNoTokens.address, 10, '', { from: initialAccount })); - }); - - it('should allow owner to reclaim tokens', async function () { - const ownerStartBalance = await token.balanceOf(owner); - await hasNoTokens.reclaimToken(token.address, { from: owner }); - - const ownerFinalBalance = await token.balanceOf(owner); - ownerFinalBalance.sub(ownerStartBalance).should.be.bignumber.equal(10); - - (await token.balanceOf(hasNoTokens.address)).should.be.bignumber.equal(0); - }); - - it('should allow only owner to reclaim tokens', async function () { - await expectThrow( - hasNoTokens.reclaimToken(token.address, { from: anyone }) - ); - }); -});