// File: src/core/MiddlewareManager.sol



// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity 0.8.14;

import { Owned } from "solmate/src/auth/Owned.sol";

import { IMiddlewareManager } from "../interfaces/IMiddlewareManager.sol";

/**
 * @title MiddlewareManager
 * @author CyberConnect
 * @notice This contract manages middleware whitelist.
 * Only allowed middleware can be used in CyberConnect Protocol.
 */
contract MiddlewareManager is Owned, IMiddlewareManager {
    /*//////////////////////////////////////////////////////////////
                                STATES
    //////////////////////////////////////////////////////////////*/

    mapping(address => bool) internal _mwAllowlist;

    /*//////////////////////////////////////////////////////////////
                                 CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(address owner) Owned(owner) {}

    /*//////////////////////////////////////////////////////////////
                                 EXTERNAL
    //////////////////////////////////////////////////////////////*/

    /// @inheritdoc IMiddlewareManager
    function allowMw(address mw, bool allowed) external override onlyOwner {
        bool preAllowed = _mwAllowlist[mw];
        _mwAllowlist[mw] = allowed;

        emit AllowMw(mw, preAllowed, allowed);
    }

    /*//////////////////////////////////////////////////////////////
                         EXTERNAL VIEW
    //////////////////////////////////////////////////////////////*/

    /// @inheritdoc IMiddlewareManager
    function isMwAllowed(address mw) external view override returns (bool) {
        return _mwAllowlist[mw];
    }
}

// File: lib/solmate/src/auth/Owned.sol



// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Simple single owner authorization mixin.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol)
abstract contract Owned {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event OwnershipTransferred(address indexed user, address indexed newOwner);

    /*//////////////////////////////////////////////////////////////
                            OWNERSHIP STORAGE
    //////////////////////////////////////////////////////////////*/

    address public owner;

    modifier onlyOwner() virtual {
        require(msg.sender == owner, "UNAUTHORIZED");

        _;
    }

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(address _owner) {
        owner = _owner;

        emit OwnershipTransferred(address(0), _owner);
    }

    /*//////////////////////////////////////////////////////////////
                             OWNERSHIP LOGIC
    //////////////////////////////////////////////////////////////*/

    function transferOwnership(address newOwner) public virtual onlyOwner {
        owner = newOwner;

        emit OwnershipTransferred(msg.sender, newOwner);
    }
}

// File: src/interfaces/IMiddlewareManager.sol



// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity 0.8.14;

import { IMiddlewareManagerEvents } from "../interfaces/IMiddlewareManagerEvents.sol";

/**
 * @title IMiddlewareManager
 * @author CyberConnect
 */
interface IMiddlewareManager is IMiddlewareManagerEvents {
    /**
     * @notice Allows the middleware.
     *
     * @param mw The middleware address.
     * @param allowed The allowance state.
     */
    function allowMw(address mw, bool allowed) external;

    /**
     * @notice Checks if the middleware is allowed.
     *
     * @param mw The middleware address.
     * @return bool The allowance state.
     */
    function isMwAllowed(address mw) external view returns (bool);
}

// File: src/interfaces/IMiddlewareManagerEvents.sol



// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity 0.8.14;

/**
 * @title IMiddlewareManagerEvents
 * @author CyberConnect
 */
interface IMiddlewareManagerEvents {
    /**
     * @notice Emitted when a profile middleware has been allowed.
     *
     * @param mw The middleware address.
     * @param preAllowed The previously allow state.
     * @param newAllowed The newly set allow state.
     */
    event AllowMw(
        address indexed mw,
        bool indexed preAllowed,
        bool indexed newAllowed
    );
}