Skip to main content

FactoryFeeManager

Fee management library providing flexible fee structures and custom fee configurations for factory-deployed vesting contracts.

Library Information

File Location: contracts/libraries/FactoryFeeManager.sol

Usage Pattern:

import {FactoryFeeManager} from "./libraries/FactoryFeeManager.sol";

contract MyFactory is FactoryFeeManager {
constructor(
address feeCollector,
uint256 defaultGasFee,
uint256 defaultTokenFee
) FactoryFeeManager(feeCollector, defaultGasFee, defaultTokenFee) {}
}

Overview

The FactoryFeeManager library provides sophisticated fee management capabilities for factory contracts in the TokenOps ecosystem. It supports both gas-based and token-based fees, custom fee configurations for specific deployers, and flexible fee collector management. This library ensures consistent fee structures across all deployed vesting managers while allowing for customization based on deployer requirements.

Key Features

  • Dual fee types - Support for both gas fees (Fixed ETH) and token-based fees (Percentage of distributed tokens)
  • Custom fee configurations - Per-deployer custom fee structures override defaults
  • Fee collector management - Centralized fee collection with role-based access
  • Default fee fallback - Graceful fallback to default fees when custom fees aren't configured
  • Gas optimization - Efficient storage layout and calculation algorithms
  • Event-driven transparency - All fee changes and payments logged via events

Fee Types

FeeType Enum

enum FeeType {
Gas, // Fixed gas fee in wei (ETH)
DistributionToken // Percentage fee in basis points from distributed tokens
}

Gas Fees

  • Fixed amount in wei (ETH) charged per deployment or operation
  • Immediate payment required during factory operations
  • Simple calculation with no dependency on token amounts
  • Ideal for native token vesting or when consistent pricing is desired

Token Fees

  • Percentage-based fees calculated from distributed token amounts
  • Measured in basis points (100 basis point = 1%)
  • Deducted during token distribution operations
  • Ideal for ERC20 token vesting where fees scale with token value

State Variables

Core Storage

contract FactoryFeeManager {
// Default fee configuration
address public feeCollector;
uint256 public defaultGasFee; // Gas fee in wei
uint256 public defaultTokenFee; // Token fee in basis points

ITypes.FeeType public defaultFeeType = ITypes.FeeType.Gas; // Gas fee as default
mapping(address campaignCreator => CustomFee customFee)
internal _customFees; // Custom fee setup
}

Custom Fee Configuration

struct CustomFee {
bool enabled;
ITypes.FeeType preferredFeeType;
uint256 gasFee;
uint256 tokenFee;
}

Constructor

constructor(
address feeCollector_,
uint256 defaultGasFee_,
uint256 defaultTokenFee_
) {
if (feeCollector_ == address(0)) revert Errors.InvalidAddress();
if (defaultTokenFee_ > BASIS_POINTS) revert Errors.FeeTooHigh();

feeCollector = feeCollector_;
defaultGasFee = defaultGasFee_;
defaultTokenFee = defaultTokenFee_;
}

Parameters:

  • feeCollector_: Address that will receive all collected fees
  • defaultGasFee_: Default gas fee amount in wei for gas-based operations
  • defaultTokenFee_: Default token fee in basis points for token-based operations

Constraints:

  • Fee collector cannot be zero address
  • Token fee cannot exceed maximum limit (10000 basis points = 100%)

Core Functions

setFeeCollector

function setFeeCollector(address newFeeCollector) external onlyOwner;

setDefaultGasFee

function setDefaultGasFee(uint256 newGasFee) external onlyOwner;

setDefaultTokenFee

function setDefaultTokenFee(uint256 newTokenFee) external onlyOwner;

setDefaultFeeType

function setDefaultFeeType(ITypes.FeeType feeType) external onlyOwner;

resetGasFee

function resetGasFee() external onlyOwner;

resetTokenFee

function resetTokenFee() external onlyOwner;

setCustomFee

function setCustomFee(address campaignCreator, ITypes.FeeType feeType, uint256 gasFee, uint256 tokenFee)
external
onlyOwner;

disableCustomFee

function disableCustomFee(address campaignCreator) external onlyOwner;

getCustomFee

function getCustomFee(address campaignCreator) external view returns (CustomFee memory);

_getFee

function _getFee(address campaignCreator) internal view returns (uint256);

_getFeeType

function _getFeeType(address campaignCreator) internal view returns (ITypes.FeeType);

Events

Events

FeeCollectorSet

Emitted when a new fee collector is set

event FeeCollectorSet(address admin, address indexed newFeeCollector);

SetDefaultGasFee

Emitted when the default gas fee is updated

event SetDefaultGasFee(address admin, uint256 oldGasFee, uint256 newGasFee);

SetDefaultTokenFee

Emitted when the default token fee is updated

event SetDefaultTokenFee(address admin, uint256 oldTokenFee, uint256 newTokenFee);

ChangeDefaultFeeType

Emitted when the default fee type is changed

event ChangeDefaultFeeType(address admin, ITypes.FeeType newFeeType);

SetCustomFee

Emitted when a custom fee is set for a campaign creator

event SetCustomFee(
address admin,
bool enabled,
address indexed campaignCreator,
ITypes.FeeType feeType,
uint256 gasFee,
uint256 tokenFee
);

Security Considerations

Fee Validation

  • Maximum fee limits prevent excessive fees
  • Fee collector validation ensures fees can be collected

Access Control

  • Admin-only functions for fee configuration management
  • Deployer-specific fees cannot be manipulated by other users
  • Fee collector protection through address validation

Gas Optimization

  • Efficient storage layout minimizes gas costs
  • Batch operations where possible to reduce transaction costs
  • Event emission for off-chain tracking and analytics

The FactoryFeeManager library provides a comprehensive fee management system that enables flexible, scalable fee structures for factory-deployed vesting contracts.