EigenLayer has two variables that limit the incoming deposits: maxTotalDeposits and maxPerDeposit. If current deposit would exceed at least one of these two variables, that is if:
By the time Kelp is able to mitigate the issue (for example, by moving a part of the funds back to LRTDepositPool via transferBackToLRTDepositPool), and given that EL deposits may be open only for a few hours, users' stETH deposited into Kelp may not be deposited into EL and will not be earning EL yield for a few weeks, until EL opens deposits again.
Proof of Concept
Kelp accumulates 100_000e18 of stETH while EL deposits are paused.
Few days pass. stETH balance of the stETH NodeDelegator grows due to rebasing and is now 100_100e18.
EL sets maxTotalDeposit = 200_000e18, maxPerDeposit remains at 100_000e18.
depositIntoStrategy tries to deposit the whole balance of the contract. The transaction fails, because NodeDelegator's balance of stETH (100_100e18) is above maxPerDeposit, and because the deposit would exceed maxTotalDeposits as well.
Revert due to EigenLayer deposits from the outside of Kelp
There will also be EL depositors who are faster than LRTManager. If, for example, by the time LRTManager is able to deposit, there's already 40k of successful deposits, depositAssetIntoStrategy will fail (if NodeOperator's balance is above 60k). Because the time is of the essence, it is important to make sure that the deposit will be successful regardless of how much funds NodeOperator holds.
Lines of code
https://github.com/code-423n4/2023-11-kelp/blob/f751d7594051c0766c7ecd1e68daeb0661e43ee3/src/NodeDelegator.sol#L51-L68
Vulnerability details
Impact
EigenLayer has two variables that limit the incoming deposits: maxTotalDeposits and maxPerDeposit. If current deposit would exceed at least one of these two variables, that is if:
the deposit is reverted.
Kelp mitigates this issue by setting depositLimitByAsset for each LST to 100k:
LRTConfig.sol#L61-L63
However, it does not take into account that stETH is rebasing, and the balance of NodeDelegator may exceed the 100k limit while EL is still paused.
Then, NodeDelegator is able to deposit only its whole balance, which would be reverted by EL due to one of the two previously mentioned checks:
NodeDelegator.sol#L63-L67
By the time Kelp is able to mitigate the issue (for example, by moving a part of the funds back to LRTDepositPool via
transferBackToLRTDepositPool
), and given that EL deposits may be open only for a few hours, users' stETH deposited into Kelp may not be deposited into EL and will not be earning EL yield for a few weeks, until EL opens deposits again.Proof of Concept
depositIntoStrategy
tries to deposit the whole balance of the contract. The transaction fails, because NodeDelegator's balance of stETH (100_100e18) is abovemaxPerDeposit
, and because the deposit would exceedmaxTotalDeposits
as well.Revert due to EigenLayer deposits from the outside of Kelp
There will also be EL depositors who are faster than LRTManager. If, for example, by the time LRTManager is able to deposit, there's already 40k of successful deposits,
depositAssetIntoStrategy
will fail (if NodeOperator's balance is above 60k). Because the time is of the essence, it is important to make sure that the deposit will be successful regardless of how much funds NodeOperator holds.Recommended Mitigation Steps
The new functions used in the mitigation should be added respectively to their IEigenStrategyManager and IStrategy interfaces.
Assessed type
Math