Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

branch_indigo - withdraw() has Inconsistent protocol fee accounting between vault ongoing and vault ends #169

Open
sherlock-admin3 opened this issue Sep 21, 2024 · 0 comments

Comments

@sherlock-admin3
Copy link

sherlock-admin3 commented Sep 21, 2024

branch_indigo

Medium

withdraw() has Inconsistent protocol fee accounting between vault ongoing and vault ends

Summary

withdraw() has Inconsistent protocol fee accounting between vault ongoing and vault ends. withdraw() will calculate incorrect post-protocol fee earnings for variable-side users.

Vulnerability Detail

Before vault ends, when a variable-side user requests a withdrawal of earnings, the post fee earning is: (proportional_totalEarnings - previousWithdrawnAmount) * (1 - protocolFeeBps). Note in this case both (proportional_totalEarnings and previousWithdrawnAmount are pre-fee values.

  function withdraw(uint256 side) external {
...
          (uint256 currentState, uint256 ethAmountOwed) = calculateVariableWithdrawState(
            (lidoStETHBalance.mulDiv(currentStakes + withdrawnStakingEarningsInStakes, currentStakes) - fixedETHDeposits),
            variableToWithdrawnStakingEarningsInShares[msg.sender].mulDiv(lidoStETHBalance, currentStakes)
          );
...

After vault ends, when a variable-side user requests a withdrawal of earnings, the protocol fee is simply applied on proportional totalEarnings. The post fee earning is: (proportional_totalEarnings - totalProtocolFee - previousWithdrawnAmount) . Note that in this case proportional_totalEarnings - totalProtocolFee is a post-fee value, but previousWithdrawnAmount is still pre-fee values.

  function vaultEndedWithdraw(uint256 side) internal {
...
       //@audit After vault ends, totalEarnings is a post-fee value, but variableToWithdrawnStakingEarningsInShares[msg.sender] is always pre-fee value. Inconsistent with withdraw before vault ends.
|>      uint256 totalEarnings = vaultEndingETHBalance.mulDiv(withdrawnStakingEarningsInStakes,vaultEndingStakesAmount) - totalProtocolFee  + vaultEndedStakingEarnings;
        (uint256 currentState, uint256 stakingEarningsShare) = calculateVariableWithdrawState(
          totalEarnings,
          variableToWithdrawnStakingEarningsInShares[msg.sender].mulDiv(vaultEndingETHBalance, vaultEndingStakesAmount)
        );

(https://github.com/sherlock-audit/2024-08-saffron-finance/blob/38dd9c8436db341c331f1b14545770c1766fc0ee/lido-fiv/contracts/LidoVault.sol#L775)

Since previousWithdrawnAmount is always pre-fee values, the earnings shouldn't include fees. And fees should be deducted afterwards.

Impact

When vault ends, withdraw() will calculate incorrect post-protocol fee earnings for variable-side users.

Code Snippet

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

Tool used

Manual Review

Recommendation

In vaultEndedWithdraw(), use pre-fee values for totalEarnings.

@sherlock-admin4 sherlock-admin4 changed the title Tangy Raisin Woodpecker - withdraw() has Inconsistent protocol fee accounting between vault ongoing and vault ends branch_indigo - withdraw() has Inconsistent protocol fee accounting between vault ongoing and vault ends Sep 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants
@sherlock-admin3 and others