harmonixfi / core-smart-contract

Core smart contracts of Harmonix Finance
https://harmonix.fi/
0 stars 1 forks source link

Calculate management fee when user withdraw fund #114

Open baonguyen1904 opened 2 weeks ago

baonguyen1904 commented 2 weeks ago

Thank you for the clarifications. Based on your answers, here is the final solution:

Solution Overview

  1. Expose Configurable Functions: Provide functions to set the frequency and threshold for fee collection.
  2. Accumulate Fees Across Users: Accumulate management fees across all users.
  3. Periodic Fee Calculation: Calculate the management fee at each interval.
  4. Handle Excess Funds: Keep any excess USDC in the vault for future use.

Changes in Smart Contract

State Variables: Add state variables to track the accumulated management fees, threshold, and the last fee collection time.

uint256 public accumulatedManagementFees;
uint256 public feeCollectionThreshold;
uint256 public feeCollectionInterval;
uint256 public lastFeeCollectionTime;

Initialization: Initialize the new variables in the constructor or initialization function.

function initialize(
    address _admin,
    address _usdc,
    uint256 _initialPPS,
    address _swapAddress,
    address[] memory _token0s,
    address[] memory _token1s,
    uint24[] memory _fees,
    uint256 _feeCollectionThreshold,
    uint256 _feeCollectionInterval
) internal virtual {
    baseDeltaNeutralVault_Initialize(_admin, _usdc, _initialPPS, _swapAddress, _token0s, _token1s, _fees);
    feeCollectionThreshold = _feeCollectionThreshold;
    feeCollectionInterval = _feeCollectionInterval;
    lastFeeCollectionTime = block.timestamp;
}

Set Fee Collection Parameters: Add a function to update the fee collection threshold and interval.

function setFeeCollectionParams(uint256 _threshold, uint256 _interval) external {
    _auth(ROCK_ONYX_ADMIN_ROLE);
    feeCollectionThreshold = _threshold;
    feeCollectionInterval = _interval;
}

Calculate and Accumulate Management Fees: Add a function to calculate and accumulate management fees periodically.

function calculateAndAccumulateManagementFees() external nonReentrant {
    require(block.timestamp >= lastFeeCollectionTime + feeCollectionInterval, "FEE_COLLECTION_INTERVAL_NOT_REACHED");

    uint256 totalFee = 0;
    for (uint256 i = 0; i < userDeposits.length; i++) {
        uint256 timeHeld = block.timestamp - userDeposits[i].depositTime;
        totalFee += calculateManagementFee(userDeposits[i].amount, timeHeld);
    }

    accumulatedManagementFees += totalFee;
    lastFeeCollectionTime = block.timestamp;
}

Threshold-based Fee Collection: Implement logic to check and collect fees when the threshold is reached.

function collectManagementFees() external nonReentrant {
    require(accumulatedManagementFees >= feeCollectionThreshold, "THRESHOLD_NOT_REACHED");

    uint256 ethToClose = feeCollectionThreshold / currentETHPrice;
    uint256 usdcCollected = closePositionAndCollectFees(ethToClose);

    accumulatedManagementFees -= feeCollectionThreshold;

    if (usdcCollected > feeCollectionThreshold) {
        // Handle excess funds
        uint256 excess = usdcCollected - feeCollectionThreshold;
        // Keep the excess in the vault for future use
        vaultState.excessFunds += excess;
    }

    emit FeeCollected(usdcCollected, feeCollectionThreshold);
}

function closePositionAndCollectFees(uint256 ethAmount) internal returns (uint256) {
    // Implement logic to close positions and collect USDC equivalent to ethAmount
    // Return the amount of USDC collected
}

Event Notifications: Add an event to notify when fees are collected.

event FeeCollected(uint256 usdcCollected, uint256 feeThreshold);

This solution ensures efficient management of accumulated management fees and their collection when the threshold is reached, while also maintaining the delta-neutral strategy.