Skip to main content

FeeFunctions

Overview

FeeFunctions is a utility library that provides constants and helper functions for managing fee configurations using bitmasks. It enables fine-grained control over which contract functions should apply fees, providing flexibility for different fee strategies and user experiences.

Contract Specification

library FeeFunctions

Purpose: Provides standardized constants and utilities for fee function management Usage: Used by all staking contracts and factory contracts for fee configuration

Fee Function Constants

Individual Function Flags

uint8 public constant FEE_ON_STAKE = 1;      // 0x01 (00000001)
uint8 public constant FEE_ON_WITHDRAW = 2; // 0x02 (00000010)
uint8 public constant FEE_ON_CLAIM = 4; // 0x04 (00000100)

Combined Function Flags

uint8 public constant FEE_ON_ALL = 7;        // 0x07 (00000111)
uint8 public constant FEE_ON_NONE = 0; // 0x00 (00000000)

Bitmask Operations

Understanding Bitmasks

Bitmasks allow efficient storage and checking of multiple boolean flags in a single integer:

// Binary representation
FEE_ON_STAKE = 00000001 (1)
FEE_ON_WITHDRAW = 00000010 (2)
FEE_ON_CLAIM = 00000100 (4)

// Combined flags using bitwise OR
FEE_ON_STAKE | FEE_ON_WITHDRAW = 00000011 (3)
FEE_ON_STAKE | FEE_ON_CLAIM = 00000101 (5)
FEE_ON_WITHDRAW | FEE_ON_CLAIM = 00000110 (6)
FEE_ON_ALL = 00000111 (7)

Utility Functions

hasFeeEnabled

function hasFeeEnabled(uint8 feeFunctions, uint8 targetFunction) internal pure returns (bool)

Checks if a specific fee function is enabled in a bitmask.

Parameters:

  • feeFunctions: The bitmask containing enabled fee functions
  • targetFunction: The specific function to check

Returns:

  • Boolean indicating if the target function has fees enabled

Implementation:

function hasFeeEnabled(uint8 feeFunctions, uint8 targetFunction) internal pure returns (bool) {
return (feeFunctions & targetFunction) != 0;
}

addFeeFunction

function addFeeFunction(uint8 feeFunctions, uint8 newFunction) internal pure returns (uint8)

Adds a fee function to an existing bitmask.

Parameters:

  • feeFunctions: Current bitmask
  • newFunction: Function to add

Returns:

  • Updated bitmask with new function enabled

Implementation:

function addFeeFunction(uint8 feeFunctions, uint8 newFunction) internal pure returns (uint8) {
return feeFunctions | newFunction;
}

removeFeeFunction

function removeFeeFunction(uint8 feeFunctions, uint8 targetFunction) internal pure returns (uint8)

Removes a fee function from an existing bitmask.

Parameters:

  • feeFunctions: Current bitmask
  • targetFunction: Function to remove

Returns:

  • Updated bitmask with target function disabled

Implementation:

function removeFeeFunction(uint8 feeFunctions, uint8 targetFunction) internal pure returns (uint8) {
return feeFunctions & ~targetFunction;
}

Common Fee Configurations

Predefined Configurations

// No fees on any function
uint8 public constant NO_FEES = FEE_ON_NONE;

// Entry-only fees (stake only)
uint8 public constant ENTRY_FEES = FEE_ON_STAKE;

// Exit-only fees (withdraw only)
uint8 public constant EXIT_FEES = FEE_ON_WITHDRAW;

// Reward fees (claim only)
uint8 public constant REWARD_FEES = FEE_ON_CLAIM;

// Entry and exit fees
uint8 public constant ENTRY_EXIT_FEES = FEE_ON_STAKE | FEE_ON_WITHDRAW;

// All transaction fees
uint8 public constant ALL_FEES = FEE_ON_ALL;

Custom Configurations

// Staking and claiming fees (no withdrawal fees)
uint8 public constant STAKE_CLAIM_FEES = FEE_ON_STAKE | FEE_ON_CLAIM;

// Withdrawal and claiming fees (no staking fees)
uint8 public constant WITHDRAW_CLAIM_FEES = FEE_ON_WITHDRAW | FEE_ON_CLAIM;

Bitmask Configuration Table

ConfigurationBinaryDecimalStake FeeWithdraw FeeClaim Fee
FEE_ON_NONE000000000NoNoNo
FEE_ON_STAKE000000011YesNoNo
FEE_ON_WITHDRAW000000102NoYesNo
FEE_ON_CLAIM000001004NoNoYes
STAKE + WITHDRAW000000113YesYesNo
STAKE + CLAIM000001015YesNoYes
WITHDRAW + CLAIM000001106NoYesYes
FEE_ON_ALL000001117YesYesYes

Bitwise Operations

Checking Single Function

// Check if staking fees are enabled
bool hasStakeFee = (feeFunctions & FEE_ON_STAKE) != 0;

// Check if withdrawal fees are enabled
bool hasWithdrawFee = (feeFunctions & FEE_ON_WITHDRAW) != 0;

// Check if claim fees are enabled
bool hasClaimFee = (feeFunctions & FEE_ON_CLAIM) != 0;

Enabling Functions

// Enable staking fees
feeFunctions = feeFunctions | FEE_ON_STAKE;

// Enable multiple fees at once
feeFunctions = feeFunctions | (FEE_ON_STAKE | FEE_ON_WITHDRAW);

// Enable all fees
feeFunctions = FEE_ON_ALL;

Disabling Functions

// Disable staking fees
feeFunctions = feeFunctions & ~FEE_ON_STAKE;

// Disable multiple fees at once
feeFunctions = feeFunctions & ~(FEE_ON_STAKE | FEE_ON_WITHDRAW);

// Disable all fees
feeFunctions = FEE_ON_NONE;

Toggling Functions

// Toggle staking fees
feeFunctions = feeFunctions ^ FEE_ON_STAKE;

// Toggle multiple fees
feeFunctions = feeFunctions ^ (FEE_ON_STAKE | FEE_ON_CLAIM);

Constants Reference

Individual Flags

ConstantValueBinaryDescription
FEE_ON_NONE000000000No fees enabled
FEE_ON_STAKE100000001Fee on staking functions
FEE_ON_WITHDRAW200000010Fee on withdrawal functions
FEE_ON_CLAIM400000100Fee on claim functions
FEE_ON_ALL700000111All fees enabled

Combination Examples

DescriptionCalculationResultBinary
Stake + Withdraw1 | 2300000011
Stake + Claim1 | 4500000101
Withdraw + Claim2 | 4600000110
All Functions1 | 2 | 4700000111

Error Conditions

Invalid Bitmask

// Bitmask values > 7 are invalid
if (feeFunctions > FeeFunctions.FEE_ON_ALL) {
revert InvalidFeeFunctionsMask();
}

Reserved Bits

// Bits 3-7 are reserved for future use
uint8 constant RESERVED_MASK = 0xF8; // 11111000
if ((feeFunctions & RESERVED_MASK) != 0) {
revert ReservedBitsUsed();
}

Future Extensions

Extensibility Design

The bitmask design allows for future fee function additions:

// Future fee functions (not yet implemented)
uint8 public constant FEE_ON_TRANSFER = 8; // 0x08 (00001000)
uint8 public constant FEE_ON_DELEGATE = 16; // 0x10 (00010000)
uint8 public constant FEE_ON_COMPOUND = 32; // 0x20 (00100000)

Backward Compatibility

Existing contracts will continue to work with new fee function additions since they only check the bits they understand.

Best Practices

Configuration Management

  1. Validate Inputs: Always validate bitmask values before storage
  2. Use Constants: Use predefined constants instead of magic numbers
  3. Document Choices: Comment the reasoning behind fee configurations
  4. Test Combinations: Verify all possible combinations work correctly

Performance Optimization

  1. Inline Checks: Use inline bitwise operations for frequently called functions
  2. Cache Values: Store fee configurations in immutable variables when possible
  3. Batch Updates: Update multiple fee functions in single transactions
  4. Minimize Storage: Use uint8 for storage efficiency

Security Considerations

  1. Input Validation: Validate all fee function parameters
  2. Access Control: Restrict fee configuration changes to authorized accounts
  3. Audit Trails: Emit events for all fee configuration changes
  4. Overflow Protection: Ensure bitmask values don't exceed valid ranges