Closed c4-bot-1 closed 4 weeks ago
From the Guidelines:
Vulnerabilities submitted during the preceding audit should not be submitted as new HM issues during the mitigation review. They will be considered out of scope and ineligible for awards. If a warden feels an issue from the preceding audit was overlooked or undervalued, it is recommended to look into submitting it to the sponsor via other channels (e.g., a bug bounty program).
alcueca marked the issue as unsatisfactory: Out of scope
Lines of code
https://github.com/Renzo-Protocol/Contracts/blob/74a6c9963d4e9359c542901fdd2dd3f5a6864f16/contracts/RestakeManager.sol#L339-L370
Vulnerability details
Proof of Concept
Now to dive into the issue, let's take a look at the RestakeManager's
chooseOperatorDelegatorForDeposit()
function here https://github.com/Renzo-Protocol/Contracts/blob/74a6c9963d4e9359c542901fdd2dd3f5a6864f16/contracts/RestakeManager.sol#L339-L370We can see that this function picks the
OperatorDelegator
that's to be chosen for the deposit.Now from the previous contest the trusted roles in the protocol have been listed, with one being the
RESTAKE_MANAGER_ADMIN
that could as well allocate a specific max tvl for anoperatorDelegator
, see https://github.com/code-423n4/2024-04-renzo/blob/1c7cc4e632564349b204b4b5e5f494c9b0bc631d/README.md#L343We can consider this a subtle invariant, considering if a max allocation is placed on an
operatorDelegator
it shouldn't be able to hold more than this value, problem however is that with the waychooseOperatorDelegatorForDeposit
has been coded, it could actually cause the deposit to exceed the operator delegator's allocation limit by an arbitrarily large amount.This is because, when choosing the
operatorDelegator
theTVLs
without adding the deposit are used for the calculation instead of TVLs as they would be after the deposit. So as long as the allocation is not0
and does not previously exceed the limit, any amount will be deposited into the first operator delegator that was under its allocation before the new deposit.A rough-worded POC:
100
.20
.100
.chooseOperatorDelegatorForDeposit
loop reaches theoperator delegator
, it will allow this deposit, which would then make theoperator delegator
more than it's allocation.90
was previously deposited, a new deposit of1000
is going to be accepted, cause thetvl
check does not take into account the value of what's to be deposited.Impact
When more than one operator delegator is used, the allocation limit is a safety mechanism that limits the exposure to a particular operator (and the AVSes it validates). Due to this issue, the allocation limit safety mechanism fails in limiting the exposure of the protocol since it can be arbitrarily surpassed. If the underlying AVS is not profitable enough, or justifies only a certain allocation due to risk management, this issue may cause loss of funds or loss of yield to ezETH holders.
When multiple operator delegators are utilized, the allocation limit serves as a safety measure to restrict exposure to a specific operator (and the AVSes it validates). However, this mechanism can fail because the allocation limit can be arbitrarily exceeded as explained in this report. Now if the underlying AVS is not sufficiently profitable or warrants only a certain allocation due to risk considerations, then this issue could lead to losses or reduced yields for ezETH holders.
Tools Used
Recommended Mitigation Steps
As accurately suggested here, the
tvl
check should include the new deposit's value in the calculation to ensure the operator delegator never gets overallocated to, i.wfunction chooseOperatorDelegatorForDeposit( uint256[] memory tvls,
Assessed type
Context