EigenLayer Contest - bughunter007's results

Enabling restaking of staked Ether, to be used as cryptoeconomic security for decentralized protocols and applications.

General Information

Platform: Code4rena

Start Date: 27/04/2023

Pot Size: $90,500 USDC

Total HM: 4

Participants: 43

Period: 7 days

Judge: GalloDaSballo

Id: 233

League: ETH

EigenLayer

Findings Distribution

Researcher Performance

Rank: 28/43

Findings: 2

Award: $338.99

QA:
grade-b

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: ABA

Also found by: 0xWaitress, 8olidity, ABA, MiloTruck, ToonVH, bughunter007, bytes032, juancito, rvierdiiev

Labels

bug
2 (Med Risk)
partial-50
duplicate-132

Awards

267.3946 USDC - $267.39

External Links

Lines of code

https://github.com/code-423n4/2023-04-eigenlayer/blob/5e4872358cd2bda1936c29f460ece2308af4def6/src/contracts/core/StrategyManager.sol#L526-L579 https://github.com/code-423n4/2023-04-eigenlayer/blob/5e4872358cd2bda1936c29f460ece2308af4def6/src/contracts/core/StrategyManager.sol#L442-L449 https://github.com/code-423n4/2023-04-eigenlayer/blob/5e4872358cd2bda1936c29f460ece2308af4def6/src/contracts/core/StrategyManager.sol#L456-L469

Vulnerability details

Impact

The function slashQueuedWithdrawal of StrategyManager.sol takes optional parameter of indicesToSkip. As per code comments, the purpose of this parameter is to skip malicious strategies so that function call will not revert. However same risk possesses for regular queued withdrawls i.e completeQueuedWithdrawal & completeQueuedWithdrawals functions. These two functions are missing indicesToSkip parameter to skip malicious strategies which may cause withdrawls to fail.

Also erroneous input to indicesToSkip parameter will permanently lock the tokens in the strategy. There is no mechanism to recover those tokens.

Proof of Concept

//Admin provides erroroneous indicesToSkip parameter to the following finction of StrategyManager.sol function slashQueuedWithdrawal(address recipient, QueuedWithdrawal calldata queuedWithdrawal, IERC20[] calldata tokens, uint256[] calldata indicesToSkip)

The following code disables calling slashQueuedWithdrawal function again with same withdrawalRoot

// reset the storage slot in mapping of queued withdrawals withdrawalRootPending[withdrawalRoot] = false;

//The following code skips the withdrawl. Any erroneous input to indicesToSkip parameter will permanently lock the tokens in the strategy as user will not get his burned shares back.

if (indicesToSkipIndex < indicesToSkip.length && indicesToSkip[indicesToSkipIndex] == i) { unchecked { ++indicesToSkipIndex; } }

Tools Used

VS Code

Add indicesToSkip parameter to completeQueuedWithdrawal & completeQueuedWithdrawals functions. The skipped withdrawls must be recorded in unclaimedFunds data strucure that contains beneficiary address, strategy, and number of shares. Provide a function call for beneficiary to claim unclaimed funds from a strategy. Once funds are claimed, remove the information from unclaimedFunds data structure.

#0 - c4-pre-sort

2023-05-09T13:38:58Z

0xSorryNotSorry marked the issue as duplicate of #132

#1 - c4-judge

2023-05-31T18:33:00Z

GalloDaSballo marked the issue as partial-50

#2 - GalloDaSballo

2023-05-31T18:33:22Z

The issue of a reverting strategy is mentioned, the report could have been written better to be clearer and had a POC / Code snippet

Findings Information

Labels

bug
grade-b
QA (Quality Assurance)
Q-22

Awards

71.6048 USDC - $71.60

External Links

L1) The function claimableUserDelayedWithdrawals of DelayedWithDrawlRouter.sol is not functioning as per function specification comments.

https://github.com/code-423n4/2023-04-eigenlayer/blob/5e4872358cd2bda1936c29f460ece2308af4def6/src/contracts/pods/DelayedWithdrawalRouter.sol#L109-L119

The comments section for claimableUserDelayedWithdrawals function says following //Getter function to get all delayedWithdrawals that are currently claimable by the user But the function doesn't actually returns currently claimable withdrawls as there is no block number verification. It actually returns all claimable withdrawls (withdrawls that can be claimed in current block + withdrawls that can be claimed in future blocks)

Mitigation: Add block number verification in the for loop as shown below. claimableDelayedWithdrawals array will have to be re-sized. if (block.number < claimableDelayedWithdrawals[i].blockCreated + withdrawalDelayBlocks) { break; }

#0 - GalloDaSballo

2023-06-01T18:06:27Z

L1) The function claimableUserDelayedWithdrawals of DelayedWithDrawlRouter.sol is not functioning as per function specification comments.

L + 3

#1 - c4-judge

2023-06-02T09:38:46Z

GalloDaSballo marked the issue as grade-b

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter