openzeppelin-contracts: Ownable contracts cannot be created by factories
If a contract is Ownable, the owner is automatically set to the deployer account. Because transferOwnership can only be called by the owner, these contracts cannot be deployed by generic factory contracts because they will retain ownership and have no way of transferring it to another account.
There’s two ways to work around this in 3.0, neither of them very comfortable:
- Override
Context._msgSendersuch thatOwnableassumes the deployer account is a different one, potentially specified as a constructor argument. - Perform a delegatecall to the
transferOwnershipfunction as part of the constructor. This is really only possible in proxies because there is a contract that can be delegatecalled. In non-proxied contracts, the bytecode inthishasn’t been set yet, and it cannot be delegatecalled.
It seems that we should simply bring back the internal _transferOwnership that was removed in 3.0. In restrospect, I don’t think it was removed for any good reasons, and this is a very clear situation where it would’ve been useful. We did bring back the internal _setupRole, which is the analogous function in AccessControl.
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 2
- Comments: 17 (12 by maintainers)
thanks . well, seems like transferOwnership inside the initialize function will do the work as it use msgSender() . see https://github.com/daostack/infra/blob/7cb1a3c38bca58f335c1e7bf9293351ffe1f0108/contracts/Reputation.sol#L76
The issue is with generic factories. So, factories that can be used to deploy any contract and that don’t contain any logic specific to that contract.