Saffron leverages Lido's liquid Ethereum staking for its fixed-income strategy. The protocol charges a protocol fee on the Variable Side's staking earnings. These earnings primarily consist of the difference between the initial ETH staked by the Fixed Side and the ETH received upon claiming Lido withdrawals after the vault ends, minus any protocol fees.
The potential issue lies in the calculation within the finalizeVaultEndedWithdrawals function of the LidoVault contract.
The code calculates vaultEndedStakingEarnings correctly when amountWithdrawn (the total ETH withdrawn from Lido) exceeds fixedETHDeposit (the initial ETH staked). However, if amountWithdrawn is less than or equal to fixedETHDeposit, signifying either a loss or no profit from staking, vaultEndedStakingEarnings remains 0. Subsequently, the applyProtocolFee function, which calculates the protocol fee based on vaultEndedStakingEarnings, results in a 0 protocol fee even when there might be earnings from fixed side early exit fees (feeEarnings).
Impact
The impact of this issue is that the protocol might miss out on collecting protocol fees from the portion of Variable Side earnings attributed to accrued feeEarnings when amountWithdrawn is less than or equal to fixedETHDeposit.
Scenario
Let's imagine a scenario where:
Fixed Side deposits total 100 ETH.
Due to market fluctuations, the staked ETH on Lido yields only 98 ETH upon withdrawal at the vault's end.
During the vault's duration, Fixed Side early exit fees accumulate to 5 ETH.
In this scenario, amountWithdrawn would be 98 ETH, fixedETHDeposit would be 100 ETH, and feeEarnings would be 5 ETH. The current code would calculate vaultEndedStakingEarnings as 0, leading to a 0 protocol fee, even though the Variable Side benefits from the 5 ETH in feeEarnings.
Proposed Fix
To rectify this, the calculation of the base amount on which the protocol fee is applied should include feeEarnings. One way to modify the code is as follows:
// ... existing code ...
uint256 protocolFeeBasis = 0;
if (amountWithdrawn > fixedETHDeposit) {
vaultEndedStakingEarnings = amountWithdrawn - fixedETHDeposit;
protocolFeeBasis = vaultEndedStakingEarnings;
} else {
protocolFeeBasis = feeEarnings;
}
uint256 protocolFee = applyProtocolFee(protocolFeeBasis);
// If amountWithdrawn > fixedETHDeposit, we deduct the fee from vaultEndedStakingEarnings
// Otherwise, we deduct it from feeEarnings
if (amountWithdrawn > fixedETHDeposit) {
vaultEndedStakingEarnings -= protocolFee;
} else {
feeEarnings -= protocolFee;
}
// ... existing code ...
This modification ensures that even if there are no staking earnings (amountWithdrawn <= fixedETHDeposit), the protocol fee is still calculated and deducted from the feeEarnings.
0xloophole
Medium
Inaccurate Protocol Fee Calculation in Lido Vault
Details
Saffron leverages Lido's liquid Ethereum staking for its fixed-income strategy. The protocol charges a protocol fee on the Variable Side's staking earnings. These earnings primarily consist of the difference between the initial ETH staked by the Fixed Side and the ETH received upon claiming Lido withdrawals after the vault ends, minus any protocol fees.
The potential issue lies in the calculation within the finalizeVaultEndedWithdrawals function of the LidoVault contract.
https://github.com/sherlock-audit/2024-08-saffron-finance/blob/main/lido-fiv/contracts/LidoVault.sol#L661
The code calculates vaultEndedStakingEarnings correctly when amountWithdrawn (the total ETH withdrawn from Lido) exceeds fixedETHDeposit (the initial ETH staked). However, if amountWithdrawn is less than or equal to fixedETHDeposit, signifying either a loss or no profit from staking, vaultEndedStakingEarnings remains 0. Subsequently, the applyProtocolFee function, which calculates the protocol fee based on vaultEndedStakingEarnings, results in a 0 protocol fee even when there might be earnings from fixed side early exit fees (feeEarnings).
Impact
The impact of this issue is that the protocol might miss out on collecting protocol fees from the portion of Variable Side earnings attributed to accrued feeEarnings when amountWithdrawn is less than or equal to fixedETHDeposit.
Scenario
Let's imagine a scenario where:
Fixed Side deposits total 100 ETH. Due to market fluctuations, the staked ETH on Lido yields only 98 ETH upon withdrawal at the vault's end. During the vault's duration, Fixed Side early exit fees accumulate to 5 ETH.
In this scenario, amountWithdrawn would be 98 ETH, fixedETHDeposit would be 100 ETH, and feeEarnings would be 5 ETH. The current code would calculate vaultEndedStakingEarnings as 0, leading to a 0 protocol fee, even though the Variable Side benefits from the 5 ETH in feeEarnings.
Proposed Fix
To rectify this, the calculation of the base amount on which the protocol fee is applied should include feeEarnings. One way to modify the code is as follows:
This modification ensures that even if there are no staking earnings (amountWithdrawn <= fixedETHDeposit), the protocol fee is still calculated and deducted from the feeEarnings.