Since I am developing a smart contract which requires multiple owners, I modified the Ownable class from OpenZeppelin like this
contract Ownable {
mapping(address => bool) public owner;
event AddedOwner(address newOwner);
event RemovedOwner(address removedOwner);
/**
* @dev The Ownable constructor sets the original `owner` of the contract to the sender
* account.
*/
function Ownable() public {
owner[msg.sender] = true;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(owner[msg.sender]);
_;
}
function addOwner(address _newOwner) onlyOwner public {
require(_newOwner != 0);
owner[_newOwner] = true;
AddedOwner(_newOwner);
}
function removeOwner(address _toRemove) onlyOwner public {
require(_toRemove != 0);
require(_toRemove != msg.sender);
owner[_toRemove] = false;
RemovedOwner(_toRemove);
}
}
This way, owners[address] equals true when the given address is an owner.
I was wondering if this is a reasonable solution or if there are vulnerabilities that I hadn't thought of. I can't think of another solution that allows to add owners dynamically
Edit: I need multiple owners because I have functions that requires to be called by multiple contracts that are deployed after this one. So I can't even add the owners in the constructor and using one variable for each owner can't be done since I don't know how many I'll need
I know how to use OpenZeppelin libraries, but since the Ownable contract does not provide multiple owners functionality, I copied the code and modified it.
Update:
As @medvedev1088 suggested, I created a contract that extends Ownable and adds the mapping for authorized addresses
contract Authorizable is Ownable {
mapping(address => bool) public authorized;
modifier onlyAuthorized() {
require(authorized[msg.sender] || owner == msg.sender);
_;
}
function addAuthorized(address _toAdd) onlyOwner public {
require(_toAdd != 0);
authorized[_toAdd] = true;
}
function removeAuthorized(address _toRemove) onlyOwner public {
require(_toRemove != 0);
require(_toRemove != msg.sender);
authorized[_toRemove] = false;
}
}