// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.7.6; import { Context } from "@openzeppelin/contracts/utils/Context.sol"; abstract contract SafeOwnableNonUpgradable is Context { address private _owner; address private _candidate; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { // caller not owner require(owner() == _msgSender(), "SO_CNO"); _; } /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() external virtual onlyOwner { // emitting event first to avoid caching values emit OwnershipTransferred(_owner, address(0)); _owner = address(0); _candidate = address(0); } /** * @dev Set ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function setOwner(address newOwner) external onlyOwner { // newOwner is 0 require(newOwner != address(0), "SO_NW0"); // same as original require(newOwner != _owner, "SO_SAO"); // same as candidate require(newOwner != _candidate, "SO_SAC"); _candidate = newOwner; } /** * @dev Transfers ownership of the contract to a new account (`_candidate`). * Can only be called by the new owner. */ function updateOwner() external { // candidate is zero require(_candidate != address(0), "SO_C0"); // caller is not candidate require(_candidate == _msgSender(), "SO_CNC"); // emitting event first to avoid caching values emit OwnershipTransferred(_owner, _candidate); _owner = _candidate; _candidate = address(0); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Returns the candidate that can become the owner. */ function candidate() external view returns (address) { return _candidate; } }