Assessment reports>StakeKit>Low findings>Precision loss prevents harvesting fees
Category: Protocol Risks

Precision loss prevents harvesting fees

Low Severity
Low Impact
Low Likelihood

Description

In the current implementation, the computeHarvestFee function returns a percentage of the fee based on the time elapsed since the last harvest. The fee is calculated as a yearly rate using 10000 as the denominator for the fee calculation.

For example, if the fee is 100 (1%) per year, approximately 0.0027% would be charged per day, as the fee is divided by SECONDS_IN_YEAR (31,536,000).

With this implementation, the time must elapse at least 315,360 seconds (approximately 3.65 days) to harvest the minimum fee of one basis point. This means that if no one interacts with the vault for this period, only then would the minimum fee be harvested.

function computeHarvestFee() public view returns (uint256) {
    uint256 timeElapsed = block.timestamp - lastStamp;
    uint256 mgmtFeeNum = config.managementFee * timeElapsed ;
    uint256 perfFeeNum = config.performanceFee * timeElapsed;
// [...]
    uint256 fee =
        (totalUnderlyingStamp * mgmtFeeNum + gain * perfFeeNum) / (currentTotalUnderlying * SECONDS_IN_YEAR);
    return fee;
}

Impact

This leads to precision loss for the short-term fee calculation, preventing the vault from harvesting fees as expected.

Recommendations

We recommend several approaches to address this issue:

  1. Restrict the harvest() function to be callable only by the owner.

  2. Implement a minimum time threshold between harvests (e.g., one day) to ensure fee accumulation.

Remediation

This issue has been acknowledged by StakeKit, and fixes were implemented in the following commits:

Zellic © 2025Back to top ↑