Lucene search

K
code423n4Code4renaCODE423N4:2023-06-LYBRA-FINDINGS-ISSUES-982
HistoryJul 03, 2023 - 12:00 a.m.

A user could drain collateral from LybraStETHVault.sol even if they have redeemed all their eUSD for their deposited collateral

2023-07-0300:00:00
Code4rena
github.com
5
lybrastethvault
collateral drain
redemption
vulnerability
validation
mitigation

Lines of code

Vulnerability details

Impact

Suppose a user deposits certain Ether and mints eUSD. The user collects mining rewards for sometime (assuming that the their earnings are not claimable by others). After sometime, the user redeems all their eUSD for StETH. Now, even after redemption, the user would still continue to get mining rewards in esLBR, through which they could get eUSD shares (ProtocolRewardsPool.sol) and finally StETH via the rigidRedemption() function.

Proof of Concept

Let us say a user deposits 32 ether StETH and mints 32000 ether eUSD (at ether price 1600 dollars) via the rigidRedemption() function of the LybraStETHVault.sol (LybraEUSDVaultBase.sol).
Assuming the user has sufficient deposit in the ETH/LBR staking pool to make their mining rewards not clamable by others, after some days, the user get their mining rewards by calling getReward() in the EUSDMiningIncentives.sol. After this, the user redeems all their eUSD for StETH (via rigidRedemption() function of the LybraStETHVault.sol (LybraEUSDVaultBase.sol)) in the same block (as of calling the getReward()).

The thing to note that neither depositedAsset[user] nor the borrowed[user] are set for the user that redeemed. Due to this, the user could again, after some days, call the getReward() in the EUSDMiningIncentives.sol and could get a non-zero reward (in form of esLBR). This is because (stakedOf(user)) is still non-zero (in LOC 136 of EUSDMiningIncentives.sol).

Due to this, the user keeps getting esLBR. The user could then convert esLBR into eUSD shares by calling getReward() in the ProtocolRewardsPool.sol. Finally, the user could redeem this eUSD for StETH via rigidRedemption() function of the LybraStETHVault.sol (LybraEUSDVaultBase.sol)).

I discussed this with one of the sponsors. They said user getting mining rewards even after redemption is intended.

However, upon further analysis, it was found that the reward could be used to drain collateral from LybraStETHVault.sol.

Tools Used

Manual review

Recommended Mitigation Steps

In rigidRedemption(), check for the depositedAsset[user (who is redeeming, not the provider)] to be non-zero, and, set the depositedAsset[user] as zero. This way, the borrowed[_onBehalfOf] would still be non-zero (that is, the user would keep getting rewards in esLBR), but the user won’t be able to drain StETH from the LybraStETHVault.sol via rigidRedemption().

Assessed type

Invalid Validation


The text was updated successfully, but these errors were encountered:

All reactions