Incorrect earning calculation while vault is in active
Summary
When the variable depositors withdraw their earnings, the protocol calculates the totalEarnings and previousWithdrawnAmount using shares and the stETH balance. However, the calculation is incorrect because it multiplies the current stETH balance per stake by the previous withdrawn stakes. As a result, the variable depositors receive incorrect earnings, and the fixed depositors may receive a smaller amount.
Root Cause
There is an incorrect calculation of the totalEarnings and previousWithdrawnAmount parameters in the calculateVariableWithdrawState function within the LidoVault.withdraw function.
If the stETH balance per stake differs from the previous balance per stake, the totalEarnings is calculated incorrectly because it uses withdrawnStakingEarningsInStakes. Additionally, previousWithdrawnAmount is calculated incorrectly because the previous withdrawn shares are multiplied by the current balance per stake.
There is also an incorrect calculation of the totalEarnings and previousWithdrawnAmount parameters in the calculateVariableWithdrawState function within the LidoVault.vaultEndedWithdraw function.
Total earnings is 300 and Alice and Bob should receive same earnings because they deposits the same ethers.
However, Bob receives 154 instead of 150 and this is unfair for Alice.
Impact
The variable user may receive unfair earnings.
PoC
No response
Mitigation
The variable depositors should not be allowed to withdraw earnings before the vault ended.
tobi0x18
High
Incorrect earning calculation while vault is in active
Summary
When the variable depositors withdraw their earnings, the protocol calculates the
totalEarnings
andpreviousWithdrawnAmount
using shares and the stETH balance. However, the calculation is incorrect because it multiplies the current stETH balance per stake by the previous withdrawn stakes. As a result, the variable depositors receive incorrect earnings, and the fixed depositors may receive a smaller amount.Root Cause
There is an incorrect calculation of the
totalEarnings
andpreviousWithdrawnAmount
parameters in thecalculateVariableWithdrawState
function within theLidoVault.withdraw
function.If the stETH balance per stake differs from the previous balance per stake, the
totalEarnings
is calculated incorrectly because it useswithdrawnStakingEarningsInStakes
. Additionally,previousWithdrawnAmount
is calculated incorrectly because the previous withdrawn shares are multiplied by the current balance per stake.There is also an incorrect calculation of the
totalEarnings
andpreviousWithdrawnAmount
parameters in thecalculateVariableWithdrawState
function within theLidoVault.vaultEndedWithdraw
function.Internal pre-conditions
fixedSideCapacity
: 1000 wei (use wei instead of ETH for the simplicity)variableSideCapacity
: 30 weifixedSidestETHOnStartCapacity
: 1000 weifixedClaimTokenTotalSupply
: 1000protocolFeeBps
: 0 (for the simplicity)start < t1 < end
, lido gets 100 wei profit.start < t2 < end
, lido also gets 100 wei profit.External pre-conditions
No response
Attack Path
Let's consider the following scenario:
t1
, thelidoStETHBalance
is 1100 wei after gaining a profit of 100 wei, and Alice calls thewithdraw
function.t2
, thelidoStETHBalance
is 1250 wei after gaining a profit of 200 wei, and Bob calls thewithdraw
function.Total earnings is 300 and Alice and Bob should receive same earnings because they deposits the same ethers. However, Bob receives 154 instead of 150 and this is unfair for Alice.
Impact
The variable user may receive unfair earnings.
PoC
No response
Mitigation
The variable depositors should not be allowed to withdraw earnings before the vault ended.