contract FeeHandlerFactory {

    event Created(
        address indexed provider,
        ActionFeeHandler indexed feeHandler,
        uint256 indexed num
    );

    // Denominator => For a fee of 1% => Input num = 100, as 100 / 10.000 = 0.01 == 1%
    uint256 public constant DEN = 10000;

    // provider => num => ActionFeeHandler
    mapping(address => mapping(uint256 => ActionFeeHandler)) public feeHandlerByProviderAndNum;
    mapping(address => ActionFeeHandler[]) public feeHandlersByProvider;
    mapping(address => mapping(address => bool)) public isWhitelistedToken;

    /// @notice Deploys a new feeHandler instance
    /// @dev Input _num = 100 for 1% fee, _num = 50 for 0.5% fee, etc
    function create(uint256 _num) public returns (ActionFeeHandler feeHandler) {
        require(
            feeHandlerByProviderAndNum[msg.sender][_num] == ActionFeeHandler(0),
            "FeeHandlerFactory.create: already deployed"
        );
        require(_num <= DEN, "FeeHandlerFactory.create: num greater than DEN");
        feeHandler = new ActionFeeHandler(msg.sender, this, _num, DEN);
        feeHandlerByProviderAndNum[msg.sender][_num] = feeHandler;
        feeHandlersByProvider[msg.sender].push(feeHandler);
        emit Created(msg.sender, feeHandler, _num);
    }

    // Provider Token whitelist
    function addTokensToWhitelist(address[] calldata _tokens) external {
        for (uint i; i < _tokens.length; i++) {
            isWhitelistedToken[msg.sender][_tokens[i]] = true;
        }
    }

    function removeTokensFromWhitelist(address[] calldata _tokens) external {
        for (uint i; i < _tokens.length; i++) {
            isWhitelistedToken[msg.sender][_tokens[i]] = false;
        }
    }
}
function addTokensToWhitelist(address[] calldata _tokens) external {
        for (uint i; i < _tokens.length; i++) {
            isWhitelistedToken[msg.sender][_tokens[i]] = true;
        }
    }
// Provider Token whitelist