diff --git a/contracts/mocks/OwnableMock.sol b/contracts/mocks/OwnableMock.sol new file mode 100644 index 000000000..41fd2209c --- /dev/null +++ b/contracts/mocks/OwnableMock.sol @@ -0,0 +1,11 @@ +pragma solidity ^0.4.24; + +import { Ownable } from '../ownership/Ownable.sol'; + +contract OwnableMock is Ownable { + + constructor() { + initialize(); + } + +} diff --git a/contracts/ownership/Ownable.sol b/contracts/ownership/Ownable.sol index e7d2810de..56e100ec4 100644 --- a/contracts/ownership/Ownable.sol +++ b/contracts/ownership/Ownable.sol @@ -1,12 +1,13 @@ pragma solidity ^0.4.24; +import "../Initializable.sol"; /** * @title Ownable * @dev The Ownable contract has an owner address, and provides basic authorization control * functions, this simplifies the implementation of "user permissions". */ -contract Ownable { +contract Ownable is Initializable { address private _owner; @@ -21,7 +22,7 @@ contract Ownable { * @dev The Ownable constructor sets the original `owner` of the contract to the sender * account. */ - constructor() public { + function initialize() public initializer { _owner = msg.sender; } diff --git a/test/ownership/Ownable.test.js b/test/ownership/Ownable.test.js index 9b9c1bf3e..d07c633c4 100644 --- a/test/ownership/Ownable.test.js +++ b/test/ownership/Ownable.test.js @@ -1,11 +1,18 @@ +const { EVMRevert } = require('../helpers/EVMRevert'); +const { expectThrow } = require('../helpers/expectThrow'); + const { shouldBehaveLikeOwnable } = require('./Ownable.behavior'); -const Ownable = artifacts.require('Ownable'); +const Ownable = artifacts.require('OwnableMock'); contract('Ownable', function ([_, owner, ...otherAccounts]) { beforeEach(async function () { this.ownable = await Ownable.new({ from: owner }); }); + it('cannot be reinitialized', async function () { + await expectThrow(this.ownable.initialize(), EVMRevert); + }); + shouldBehaveLikeOwnable(owner, otherAccounts); });