contract Owned {

    address public owner;
    address public newOwnerCandidate;

    event OwnershipRequested(address indexed by, address indexed to);
    event OwnershipTransferred(address indexed from, address indexed to);
    event OwnershipRemoved();

    /**
     * @dev The constructor sets the `msg.sender` as the`owner` of the contract
     */
    constructor() public {
        owner = msg.sender;
    }

    /**
     * @dev `owner` is the only address that can call a function with this
     * modifier
     */
    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }

    /**
     * @dev In this 1st option for ownership transfer `proposeOwnership()` must
     *  be called first by the current `owner` then `acceptOwnership()` must be
     *  called by the `newOwnerCandidate`
     * @notice `onlyOwner` Proposes to transfer control of the contract to a
     *  new owner
     * @param _newOwnerCandidate The address being proposed as the new owner
     */
    function proposeOwnership(address _newOwnerCandidate) external onlyOwner {
        newOwnerCandidate = _newOwnerCandidate;
        emit OwnershipRequested(msg.sender, newOwnerCandidate);
    }

    /**
     * @notice Can only be called by the `newOwnerCandidate`, accepts the
     *  transfer of ownership
     */
    function acceptOwnership() external {
        require(msg.sender == newOwnerCandidate);

        address oldOwner = owner;
        owner = newOwnerCandidate;
        newOwnerCandidate = 0x0;

        emit OwnershipTransferred(oldOwner, owner);
    }

    /**
     * @dev In this 2nd option for ownership transfer `changeOwnership()` can
     *  be called and it will immediately assign ownership to the `newOwner`
     * @notice `owner` can step down and assign some other address to this role
     * @param _newOwner The address of the new owner
     */
    function changeOwnership(address _newOwner) external onlyOwner {
        require(_newOwner != 0x0);

        address oldOwner = owner;
        owner = _newOwner;
        newOwnerCandidate = 0x0;

        emit OwnershipTransferred(oldOwner, owner);
    }

    /**
     * @dev In this 3rd option for ownership transfer `removeOwnership()` can
     *  be called and it will immediately assign ownership to the 0x0 address;
     *  it requires a 0xdece be input as a parameter to prevent accidental use
     * @notice Decentralizes the contract, this operation cannot be undone
     * @param _dac `0xdac` has to be entered for this function to work
     */
    function removeOwnership(address _dac) external onlyOwner {
        require(_dac == 0xdac);
        owner = 0x0;
        newOwnerCandidate = 0x0;
        emit OwnershipRemoved();
    }
}
/**
 * @title Owned
 * @author Adria Massanet <adria@codecontext.io>
 * @notice The Owned contract has an owner address, and provides basic
 *  authorization control functions, this simplifies & the implementation of
 *  user permissions; this contract has three work flows for a change in
 *  ownership, the first requires the new owner to validate that they have the
 *  ability to accept ownership, the second allows the ownership to be
 *  directly transferred without requiring acceptance, and the third allows for
 *  the ownership to be removed to allow for decentralization
 */
function changeOwnership(address _newOwner) external onlyOwner {
    require(_newOwner != 0x0);

    address oldOwner = owner;
    owner = _newOwner;
    newOwnerCandidate = 0x0;

    emit OwnershipTransferred(oldOwner, owner);
}

/**
 * @dev In this 2nd option for ownership transfer `changeOwnership()` can
 *  be called and it will immediately assign ownership to the `newOwner`
 * @notice `owner` can step down and assign some other address to this role
 * @param _newOwner The address of the new owner
 */