Open howlbot-integration[bot] opened 6 months ago
Currently there is not difference between two functions. underlyingToShare
calls underlyingToSharesView
itself.
![Uploading Screenshot 2024-05-22 at 3.16.19 PM.png…]()
Since there is no proof of an actual strategy used by Renzo in which the two functions are different, this is preventative of a future error and QA.
alcueca changed the severity to QA (Quality Assurance)
alcueca marked the issue as grade-a
alcueca marked the issue as grade-b
Lines of code
https://github.com/code-423n4/2024-04-renzo/blob/1c7cc4e632564349b204b4b5e5f494c9b0bc631d/contracts/Delegation/OperatorDelegator.sol#L193-L257
Vulnerability details
Proof of Concept
Take a look at https://github.com/code-423n4/2024-04-renzo/blob/1c7cc4e632564349b204b4b5e5f494c9b0bc631d/contracts/Delegation/OperatorDelegator.sol#L193-L257
This function is used whenever there is a need to like start a withdrawal from specified tokens strategies for any given amounts, now as hinted by the "@audit" tag we can see that whenever the token is not native ETH, the logic is quite similar, however in this case the strategy is not set to
beaconChainEthStrategy
and instead it's directly gotten from thetokenStrategyMapping
mapping, issue however is with the way the equivalent shares fortokenAmount
is being calculated, we can see that thequeueWithdrawals()
function queries theIStrategyManager#.underlyingToSharesView()
function, but going to this section of the inheritedIStrategyManager
interface from EigenLayer https://github.com/Layr-Labs/eigenlayer-contracts/blob/dbfa12128a41341b936f3e8da5d6da58c6233877/src/contracts/interfaces/IStrategy.sol#L74 we can see that theunderlyingToSharesView()
in some cases is not going to be executed with current state data, i.e quoting them:Would be key to note that the
OperatorDelegator#queueWithdrawals()
function in scope is not a view function unlike OperatorDelegator#getTokenBalanceFromStrategy(), so there is no need to query the non-state modifying underlying tokens to shares converter, in contrast using the non-state modifying converter would mean that for some strategies the wrong rate is going to be used when converting the underlying to shares, note that this can be coined from common logic and even the inherited EigenLayer documentation which indicates that for different strategies the implementation of both theunderlyingToSharesView()
and theunderlyingToShares()
can be different and considering popular DEFI logics we know that the view functions for exchange rates work with stale data (or to be more accurate, already stored/lagging data, this can be coined from popular logic whereexchangeRateStored()
a view function uses already stored data, whereasexchangeRateCurrent
would be a non-view function and actually modify state and use the right state data and current exchange rate)Impact
Shares gotten for the tokenAmounts for some strategies would be wrong as the non-state modifying rate converter is being used.
Recommended Mitigation Steps
Since the non-view modified
OperatorDelegator#queueWithdrawals()
function as the name suggests is infact used in order to queue withdrawals then the right amount of equivalent shares needs to be attached to thetokenAmounts
in each instance, so considering different strategies are planned to be integrated then this function should query theunderlyingToShares()
function to ensure the right state data is used in the conversion to get the equivalent shares.Assessed type
Context