sherlock-audit / 2024-08-saffron-finance-judging

9 stars 5 forks source link

Albort - There be a logical error in the early exit fee calculation formula. #170

Open sherlock-admin4 opened 2 months ago

sherlock-admin4 commented 2 months ago

Albort

Medium

There be a logical error in the early exit fee calculation formula.

Summary

The calculateFixedEarlyExitFees function has an issue, primarily due to the incorrect fee calculation formula, which causes the calculated early exit fees to deviate from the expected result.

Vulnerability Detail

  1. Basis Points Calculation Error

The earlyExitFeeBps represents the fee rate in basis points (bps), typically ranging from 0 to 10,000, corresponding to 0% to 100%. In the calculation, the formula uses (1 + earlyExitFeeBps), which can lead to a calculation error.

Incorrectly adding 1 to basis points: In the formula, (1 + earlyExitFeeBps) adds one unit (1) to a value in basis points, which is mathematically incorrect since the units are inconsistent. Correct usage of basis points: The basis points value should be divided by 10,000 to obtain the corresponding percentage, which should then be used in the calculation.

  1. The Calculation Logic for Early Exit Fees is Unclear

The formula for calculating early exit fees in the function is rather complex, which could lead to difficulties in understanding and maintaining the code. Specifically, the fee calculation is divided into two parts, which may result in double counting or omissions.

In the first part of the fee calculation, the impact of the remaining time proportion on the fees has already been considered. The second part again calculates the unearned premium based on the remaining time, resulting in the same portion of the fees being counted twice.

When a user exits early, they are required to pay both the unearned upfront premium and the early exit fee based on that unearned premium. However, these two fees are redundantly included in the calculation.

Impact

This results in the user having to pay fees higher than expected, which does not align with a reasonable fee calculation logic.

Code Snippet

https://github.com/sherlock-audit/2024-08-saffron-finance/blob/main/lido-fiv/contracts/LidoVault.sol#L992

Tool used

Manual Review

Recommendation

function calculateFixedEarlyExitFees(
    uint256 upfrontPremium,
    uint256 timestampRequested
) internal view returns (uint256) {
    if (timestampRequested >= endTime) {

        return 0;
    }

    uint256 remainingDuration = endTime - timestampRequested;
    uint256 remainingProportion = remainingDuration.mulDiv(1e18, duration);

    uint256 earlyExitFeePercent = earlyExitFeeBps.mulDiv(1e18, 10000);

    uint256 unearnedPremium = upfrontPremium.mulDiv(remainingDuration, duration);
    uint256 earlyExitFee = unearnedPremium.mulDiv(earlyExitFeePercent, 1e18).div(1e18);

    uint256 totalEarlyExitFees = unearnedPremium + earlyExitFee;

    return totalEarlyExitFees;
}