29054 - [SC - Medium] Lido discounted withdrawals are not accounted for
Submitted on Mar 5th 2024 at 22:27:05 UTC by @OxDEADBEEF for Boost | Puffer Finance
Report ID: #29054
Report type: Smart Contract
Report severity: Medium
Target: https://etherscan.io/address/0xd9a442856c234a39a81a089c06451ebaa4306a72
Impacts:
Protocol insolvency
Permanent freezing of funds
Description
Brief/Intro
The PufferVault stakes ETH into LIDO to gain yield. The operator can request withdrawals from LIDO and anyone can claim them. The current implementation assumes the amount requested is the amount that will be claimable and updates the vaults accounting respectively.
However - LIDO can provide a lower (discounted) amount from the requested amount. This will cause the vault to calculate as if it has more assets then it really has - leading to an inflated share/asset ratio.
Vulnerability Details
pufferVault calculates the totalAssets() based on all floating ETH value. This includes stETH that is locked in LIDO for withdrawing by checking $.lidoLockedETH:
This appears fine because it is expected that LIDO will release ETH from stETH at a 1:1 value. However - this is not true. In slashing events on LIDO - when claiming withdrawals, there can be a "discounted" amount.
https://stake.lido.fi/withdrawals/request
Withdraw request and claim:
Notice the above behavior where:
$.lidoLockedETHis increased by REQUESTED withdraw value$.lidoLockedETHis deducted by RECEIVED amount.
As explained above - in slashing events, the RECEIVED amount will be less then the REQUESTED amount.
This means that $.lidoLockedETH will hold a value that is not retrievable. totalAssets() will be higher then the actual value the contract has.
Impact Details
Since totalAssets() will be inflated - the share/asset ratio will be incorrect. Currently withdrawals are not allowed.
If withdrawals are allowed - there can be an insolvency issue where users cannot withdraw/redeem all their shares.
Deposits will be minted an incorrect share amount
Proof of Concept
Here is proof showing that totalAssets does not change after taking the loss and of the claim.
Add the following test to test/Integration/PufferTest.integration.t.sol
To run the test:
Last updated
Was this helpful?