contract Rootable {

    address internal _ROOT_;
    bool internal _INIT_;

    event RootTransferred(address indexed previousRoot, address indexed newRoot);

    modifier notInit() {
        require(!_INIT_, "INITIALIZED");
        _;
    }

    function initRoot(address newRoot) internal notInit {
        _INIT_ = true;
        _ROOT_ = newRoot;

        emit RootTransferred(address(0), newRoot);
    }

    /**
     * @dev Returns the address of the current root.
     */
    function root() public view returns (address) {
        return _ROOT_;
    }

    /**
     * @dev Throws if called by any account other than the root.
     */
    modifier onlyRoot() {
        require(_ROOT_ == msg.sender, "YouSwap: CALLER_IS_NOT_THE_ROOT");
        _;
    }

    /**
     * @dev Leaves the contract without root. It will not be possible to call
     * `onlyRoot` functions anymore. Can only be called by the current root.
     *
     * NOTE: Renouncing root will leave the contract without an root,
     * thereby removing any functionality that is only available to the root.
     */
    function renounceRoot() public onlyRoot {
        emit RootTransferred(_ROOT_, address(0));
        _ROOT_ = address(0);
    }

    /**
     * @dev Transfers root of the contract to a new account (`newRoot`).
     * Can only be called by the current root.
     */
    function transferRoot(address newRoot) public onlyRoot {
        require(newRoot != address(0), "NEW_ROOT_IS_THE_ZERO_ADDRESS");
        emit RootTransferred(_ROOT_, newRoot);
        _ROOT_ = newRoot;
    }
}
function transferRoot(address newRoot) public onlyRoot {
    require(newRoot != address(0), "NEW_ROOT_IS_THE_ZERO_ADDRESS");
    emit RootTransferred(_ROOT_, newRoot);
    _ROOT_ = newRoot;
}

/**
 * @dev Transfers root of the contract to a new account (`newRoot`).
 * Can only be called by the current root.
 */