PRIV ProtocolPRIV Docs
Contracts

FeeManagerV2

Central fee management contract for protocol fee collection, burning, staker rewards, and treasury distribution.

FeeManagerV2

The FeeManagerV2 contract is the central hub for processing protocol fees from all PRIV marketplace contracts. It handles the three-way split between burning tokens (deflationary), distributing rewards to stakers, and funding the protocol treasury.


Overview

Fee Sources

The FeeManagerV2 receives fees from:

SourceFee RateDescription
DataXchange3%Data marketplace sales
DataWalletMarketplace3%Data wallet media purchases
AdNetwork3%Advertising spend

Note: All marketplaces use a unified 3% fee to prevent arbitrage and simplify the economic model.

Fee Processing (40/35/25 Split)

When fees are processed:

Fee Amount (100 PRIV)
├── 40% Burned (40 PRIV) → Supply decreases (deflationary)
├── 35% Stakers (35 PRIV) → PRIVStaking rewards pool
└── 25% Treasury (25 PRIV) → Protocol reserves

The burn/staking/treasury ratios are configurable via governance with a 2-day timelock.


Contract Details

Constants

ConstantValueDescription
MAX_RATIO10000Maximum ratio (100%)
BPS_DENOMINATOR10000Basis points denominator
RATIO_UPDATE_DELAY2 daysTimelock for ratio changes
MIN_PROCESS_AMOUNT0.01 PRIVMinimum to process (prevents dust)

State Variables

// The PRIV token contract (burnable)
IPRIVToken public immutable privToken;

// The PRIVStaking contract for rewards distribution
IPRIVStaking public stakingContract;

// Treasury address for protocol reserves
address public treasury;

// Current burn ratio in basis points (4000 = 40%)
uint256 public burnRatio;

// Current staking ratio in basis points (3500 = 35%)
uint256 public stakingRatio;

// Current treasury ratio in basis points (2500 = 25%)
uint256 public treasuryRatio;

// Accumulated fees pending processing
uint256 public pendingFees;

// Total fees ever received
uint256 public totalFeesReceived;

// Total PRIV burned
uint256 public totalBurned;

// Total PRIV distributed to stakers
uint256 public totalDistributedToStakers;

// Total PRIV sent to treasury
uint256 public totalSentToTreasury;

// Mapping of authorized fee sources
mapping(address => bool) public authorizedFeeSources;

Functions

Fee Collection

receiveFees

Receives fees from authorized marketplace contracts.

function receiveFees(uint256 amount) external whenNotPaused

Parameters:

  • amount - The amount of PRIV tokens to receive as fees

Requirements:

  • Caller must be an authorized fee source
  • Amount must be greater than 0
  • Caller must have approved the FeeManagerV2 to transfer PRIV

Events:

event FeesReceived(address indexed source, uint256 amount);

Fee Processing

processFees

Processes all accumulated pending fees with the 40/35/25 split.

function processFees() external nonReentrant whenNotPaused

Description:

  • Anyone can call this function to process pending fees
  • Burns 40% of fees (deflationary)
  • Distributes 35% to the staking rewards pool
  • Sends 25% to protocol treasury

Requirements:

  • Pending fees must be at least MIN_PROCESS_AMOUNT (0.01 PRIV)
  • Staking contract must be set
  • Treasury address must be set

Events:

event FeesProcessed(
    uint256 totalAmount,
    uint256 burnedAmount,
    uint256 stakingAmount,
    uint256 treasuryAmount
);

processFeesPartial

Processes a specific amount of pending fees.

function processFeesPartial(uint256 amount) external nonReentrant whenNotPaused

Parameters:

  • amount - The specific amount to process

Use Case: Useful for gas optimization or partial processing during high-fee periods.


Ratio Management

proposeRatioUpdate

Proposes new fee distribution ratios (governance with timelock).

function proposeRatioUpdate(
    uint256 newBurnRatio,
    uint256 newStakingRatio,
    uint256 newTreasuryRatio
) external onlyOwner

Parameters:

  • newBurnRatio - New burn ratio in basis points (4000 = 40%)
  • newStakingRatio - New staking ratio in basis points (3500 = 35%)
  • newTreasuryRatio - New treasury ratio in basis points (2500 = 25%)

Requirements:

  • All ratios must sum to exactly 10000 (100%)
  • Cannot propose same ratios as current
  • No pending update can exist

Events:

event RatioUpdateProposed(
    uint256 burnRatio,
    uint256 stakingRatio,
    uint256 treasuryRatio,
    uint256 effectiveTime
);

executeRatioUpdate

Executes a pending ratio update after the 2-day timelock.

function executeRatioUpdate() external onlyOwner

Requirements:

  • A pending update must exist
  • Timelock must have elapsed (2 days)

cancelRatioUpdate

Cancels a pending ratio update.

function cancelRatioUpdate() external onlyOwner

Admin Functions

setStakingContract

Updates the staking contract address.

function setStakingContract(address newStakingContract) external onlyOwner

setTreasury

Updates the treasury address.

function setTreasury(address newTreasury) external onlyOwner

authorizeFeeSource

Authorizes a marketplace contract to send fees.

function authorizeFeeSource(address source) external onlyOwner

revokeFeeSource

Revokes authorization from a fee source.

function revokeFeeSource(address source) external onlyOwner

pause / unpause

Emergency pause controls.

function pause() external onlyOwner
function unpause() external onlyOwner

emergencyRecoverTokens

Recovers accidentally sent tokens.

function emergencyRecoverTokens(
    address token,
    address to,
    uint256 amount
) external onlyOwner

Cannot recover pending PRIV fees - only excess tokens.


View Functions

getStats

Returns comprehensive fee manager statistics.

function getStats() external view returns (
    uint256 _pendingFees,
    uint256 _totalReceived,
    uint256 _totalBurned,
    uint256 _totalDistributedToStakers,
    uint256 _totalSentToTreasury,
    uint256 _burnRatio,
    uint256 _stakingRatio,
    uint256 _treasuryRatio
)

calculateFeeSplit

Preview how fees would be split at current ratios.

function calculateFeeSplit(uint256 amount) external view returns (
    uint256 burnAmount,
    uint256 stakingAmount,
    uint256 treasuryAmount
)

ratioUpdateTimeRemaining

Returns seconds until pending update can be executed.

function ratioUpdateTimeRemaining() external view returns (uint256)

Security Features

FeatureDescription
ReentrancyGuardProtection against reentrancy attacks
PausableEmergency pause functionality
OwnableAccess control for admin functions
Timelock2-day delay for ratio changes
AuthorizationOnly approved contracts can send fees
SafeERC20Safe token transfer handling
Ratio ValidationEnsures ratios always sum to 100%

Integration Example

import { ethers } from 'ethers';

const feeManagerABI = [...]; // ABI
const feeManagerAddress = '0x...';

const feeManager = new ethers.Contract(
  feeManagerAddress,
  feeManagerABI,
  signer
);

// Check current stats
const stats = await feeManager.getStats();
console.log('Pending fees:', ethers.formatEther(stats._pendingFees));
console.log('Total burned:', ethers.formatEther(stats._totalBurned));
console.log('Total to stakers:', ethers.formatEther(stats._totalDistributedToStakers));
console.log('Total to treasury:', ethers.formatEther(stats._totalSentToTreasury));

// Current ratios (40/35/25)
console.log('Burn ratio:', stats._burnRatio / 100, '%');    // 40%
console.log('Staking ratio:', stats._stakingRatio / 100, '%'); // 35%
console.log('Treasury ratio:', stats._treasuryRatio / 100, '%'); // 25%

// Process fees (anyone can call)
if (stats._pendingFees >= ethers.parseEther('0.01')) {
  const tx = await feeManager.processFees();
  await tx.wait();
}

// Preview fee split for 100 PRIV
const [burnAmount, stakingAmount, treasuryAmount] = await feeManager.calculateFeeSplit(
  ethers.parseEther('100')
);
console.log('Would burn:', ethers.formatEther(burnAmount));       // 40 PRIV
console.log('Would stake:', ethers.formatEther(stakingAmount));   // 35 PRIV
console.log('Would treasury:', ethers.formatEther(treasuryAmount)); // 25 PRIV

Events Reference

EventDescription
FeesReceivedFees received from a marketplace
FeesProcessedFees burned, distributed to stakers, and sent to treasury
RatioUpdateProposedNew ratios proposed
RatiosUpdatedRatio change executed
RatioUpdateCancelledPending update cancelled
StakingContractUpdatedStaking contract changed
TreasuryUpdatedTreasury address changed
FeeSourceAuthorizedNew fee source authorized
FeeSourceRevokedFee source revoked

Migration from FeeManager (V1)

FeeManagerV2 replaces the original FeeManager with the following changes:

AspectFeeManager (V1)FeeManagerV2
Split50% burn / 50% stakers40% burn / 35% stakers / 25% treasury
TreasuryNoneProtocol treasury receives 25%
RatiosSingle burn ratioThree configurable ratios
Stats5 return values8 return values

Existing marketplace contracts can be migrated by updating the FeeManager address they point to.