Liquid Staking

Stakelink
DeFiHardhatOracle
50,000 USDC
View results
Submission Details
Severity: medium
Invalid

Reward Discrepancy and Accounting Inconsistency Caused by Skipping updateDeposits() Prior to exitVault() Execution

Summary

The exitVault() function in the OperatorVault contract calls _withdrawRewards() to withdraw unclaimed rewards but requires updateDeposits() to be called beforehand. However, there is no mechanism enforcing the prior call to updateDeposits(). This can lead to incorrect accounting of deposits, missed rewards updates, and potential reward discrepancies.

Vulnerability Details

OperatorVault::exitVault()natspec explicitly states that OperatorVault::updateDeposits()must be called beforehand.

The OperatorVault::exitVault()has been further called in OperatorVCS::removeVault function

(uint256 principalWithdrawn, uint256 rewardsWithdrawn) = IOperatorVault(vault).exitVault();

Again , there is another OperatorVCS::updateDeposits() function in the OperatorVCS inside which OperatorVault::updateDeposits()is called through the IVault interface , but then again OperatorVCS::removeVaultdoesn't include the above inside the function which is not good.

The function OperatorVault::exitVault() assumes that OperatorVault::updateDeposits() has been executed to accurately update the vault’s total deposits and rewards before exiting. If updateDeposits() is not called:

  1. Incorrect Tracking of Rewards: Any rewards earned between the last update and the exit may remain unaccounted.

  2. Unclaimed Rewards Mismatch: _withdrawRewards() uses outdated values for unclaimedRewards, potentially transferring incorrect reward amounts.

  3. Principal/Reward Discrepancy: exitVault() transfers the vault’s balance without reflecting recent changes, leading to inaccuracies in vault closure.

  4. Security Risk: In edge cases, rewards may be overpaid or underpaid, or discrepancies could allow manipulation of vault funds.

Impact

  • Financial Loss: The vault controller or operator may receive incorrect rewards due to outdated accounting.

  • Inconsistent Accounting: Future interactions with the vault may be affected by discrepancies in total deposits and tracked rewards.

  • Operator Manipulation Risk: Deliberately skipping updateDeposits() could result in untracked rewards or incorrect payouts, especially if used during a vault exit after large deposits or withdrawals.

Tools Used

  • Manual Code Review

Recommendations

  1. Enforce Call to updateDeposits(): Modify exitVault() to explicitly call updateDeposits() before executing withdrawal logic.

    function exitVault() external onlyVaultController returns (uint256, uint256) {
    updateDeposits(0, address(0)); //Use the intended parameters
    ...
    }
  2. Validation Checks: Add a boolean flag that ensures updateDeposits() has been called recently before exitVault() can proceed.

By addressing this vulnerability, the vault’s reward and deposit accounting will remain consistent, preventing potential reward discrepancies and financial losses during operator exits.

Updates

Lead Judging Commences

inallhonesty Lead Judge 9 months ago
Submission Judgement Published
Validated
Assigned finding tags:

[INVALID] `exitVault` doesn't call `updateDeposits` before calling `_withdrawRewards` in the vault removal process

Appeal created

dimah7 Judge
9 months ago
inallhonesty Lead Judge
8 months ago
inallhonesty Lead Judge 8 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
Assigned finding tags:

[INVALID] `exitVault` doesn't call `updateDeposits` before calling `_withdrawRewards` in the vault removal process

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.