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 functionstargetFunction
: 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 bitmasknewFunction
: 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 bitmasktargetFunction
: 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
Configuration | Binary | Decimal | Stake Fee | Withdraw Fee | Claim Fee |
---|---|---|---|---|---|
FEE_ON_NONE | 00000000 | 0 | No | No | No |
FEE_ON_STAKE | 00000001 | 1 | Yes | No | No |
FEE_ON_WITHDRAW | 00000010 | 2 | No | Yes | No |
FEE_ON_CLAIM | 00000100 | 4 | No | No | Yes |
STAKE + WITHDRAW | 00000011 | 3 | Yes | Yes | No |
STAKE + CLAIM | 00000101 | 5 | Yes | No | Yes |
WITHDRAW + CLAIM | 00000110 | 6 | No | Yes | Yes |
FEE_ON_ALL | 00000111 | 7 | Yes | Yes | Yes |
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
Constant | Value | Binary | Description |
---|---|---|---|
FEE_ON_NONE | 0 | 00000000 | No fees enabled |
FEE_ON_STAKE | 1 | 00000001 | Fee on staking functions |
FEE_ON_WITHDRAW | 2 | 00000010 | Fee on withdrawal functions |
FEE_ON_CLAIM | 4 | 00000100 | Fee on claim functions |
FEE_ON_ALL | 7 | 00000111 | All fees enabled |
Combination Examples
Description | Calculation | Result | Binary |
---|---|---|---|
Stake + Withdraw | 1 | 2 | 3 | 00000011 |
Stake + Claim | 1 | 4 | 5 | 00000101 |
Withdraw + Claim | 2 | 4 | 6 | 00000110 |
All Functions | 1 | 2 | 4 | 7 | 00000111 |
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
- Validate Inputs: Always validate bitmask values before storage
- Use Constants: Use predefined constants instead of magic numbers
- Document Choices: Comment the reasoning behind fee configurations
- Test Combinations: Verify all possible combinations work correctly
Performance Optimization
- Inline Checks: Use inline bitwise operations for frequently called functions
- Cache Values: Store fee configurations in immutable variables when possible
- Batch Updates: Update multiple fee functions in single transactions
- Minimize Storage: Use uint8 for storage efficiency
Security Considerations
- Input Validation: Validate all fee function parameters
- Access Control: Restrict fee configuration changes to authorized accounts
- Audit Trails: Emit events for all fee configuration changes
- Overflow Protection: Ensure bitmask values don't exceed valid ranges