Assessment reports>Lido Fixed Income>Medium findings>Variable side cannot always withdraw fee share
Category: Coding Mistakes

Variable side cannot always withdraw fee share

Medium Severity
Medium Impact
High Likelihood

Description

During a vault's lifetime, a variable-side depositor can withdraw both their share of the yields and their share of the early exit fees charged by withdrawing fixed-side depositors. This is implemented in the withdraw function:

function withdraw(uint256 side) external {
  // [...] [ case !isEnded() && side == VARIABLE ]

  require(variableToVaultOngoingWithdrawalRequestIds[msg.sender].length == 0, "WAR");

  // [...]

  if (lidoStETHBalance > fixedETHDeposits) {

    // [...]

    if (ethAmountOwed >= minStETHWithdrawalAmount()) {
      // [...]

      variableToVaultOngoingWithdrawalRequestIds[msg.sender] = requestWithdrawViaETH(
        msg.sender,
        ethAmountOwed
      );

      // [...]

      return;
    }
  }

  // there are no staking earnings that can be withdrawn but there are fixed side early withdrawal fees
  if (feeEarnings > 0) {
    uint256 feeEarningsShare = calculateVariableFeeEarningsShare();
    require(feeEarningsShare > 0, "NZW");

    transferWithdrawnFunds(msg.sender, feeEarningsShare);

    emit VariableFundsWithdrawn(feeEarningsShare, msg.sender, isStarted(), isEnded());
    return;
  }

However, note that the first type of withdrawal is tried first and, if it succeeds in queueing a withdrawal, the fee earnings are not withdrawn. Also, if the user has an ongoing withdrawal in the queue, they also cannot withdraw due to the require.

Impact

Even though the feeEarnings consists of ETH held in the contract, variable-side depositors inconveniently cannot withdraw it unless they also withdraw their yield earnings and wait for that withdrawal to complete.

Recommendations

We recommend processing the fee earnings withdrawal even if there is a pending yield withdrawal and also even if the withdrawal call successfully caused the queueing of a new yield withdrawal.

Remediation

This issue has been acknowledged by Saffron, and a fix was implemented in commit ee03623d.

Zellic © 2024Back to top ↑