Full Report
RocketPool and Lido are both third party staking pools for Ethereum 2.0. Proof of stake, vs. proof of work, is the future, as it should make the Ethereum much more performant. Instead of random people computing a hash, a staker will propose and validate blocks from other validators. A person is only a staker if they have deposited funds into the staker contract themselves. Currently, to be a staker in Ethereum 2.0, it is 32ETH or around 112K. Because this is so expensive, staking pools were created. The purpose of this is to pool together user funds to become a staker as a group. Then, from staking, you get rewards for doing so. When an Ethereum transaction is made, it isn't made instantaneously. Instead, it is stuck into a queue of our transactions. The validators will choose which transactions to put into the next block, depending on the amount paid to perform the transaction. So, what would happen if somebody abused their knowledge of the queue to do something malicious? This is called frontrunning. The deposit contract is used for sending the money to be a validator. This takes in three main parameters: BLS public key for validator, withdrawal credentials and signature of the data above. This is how a user signs up for the service. When value is added to deposit for a NEW user, the user is created within an IF statement. However, if the user, which is defined by the public key is already in the system, the funds are simply added to that validator. An attacker can SEE the presence of a deposit using a specific public key. Once they see this, they can create their own transaction linking their account to this public key PRIOR to the original user. Once the original users transaction goes through, the funds will be added to the attacker account, because of the else clause, instead of being in the new users account. Damn, that's crazy! Frontrunning appears to be more of a problem within the cryptocurrency bot community. However, it does have serious consequences in the security world as well. In this case, the identification of a user was NOT their address; instead, a value that could be spoofed. Interesting bug that the developers explain well here as well. It should be noted that this required a node operator to go rogue to perform this attack; this is considered a privileged user nonetheless but still got a 100K bounty for each project this effected. The authors include a few possible mitigations as well.
Analysis Summary
# Vulnerability: Frontrunning Attack on Staking Pool Deposits Leading to Fund Redirection
## CVE Details
- CVE ID: Not explicitly assigned in the provided text. (This vulnerability was reported via bug bounty programs.)
- CVSS Score: Critical (Inferred, given the $100K bug bounty payouts and the ability to steal user deposits).
- CWE: CWE-242 (Improper Neutralization of Unique Code Identifiers) or similar flaw related to relying on predictable transaction ordering (Frontrunning).
## Affected Systems
- Products: RocketPool and Lido Finance (Ethereum 2.0 staking pools).
- Versions: The specific vulnerable contract versions are not listed, but it affects the implementation logic interacting with the Ethereum 2.0 Deposit Contract.
- Configurations: Any configuration where a malicious, privileged node operator controls the creation or processing of deposits for these staking pools.
## Vulnerability Description
The vulnerability exists in how RocketPool and Lido handle new user deposits signaled to the Ethereum 2.0 Deposit Contract. The process relies on parameters like the BLS Public Key. An attacker, acting as a privileged node operator for the staking pool, could observe a pending legitimate deposit transaction initiated by a user intending to become a validator through the pool. Before the legitimate transaction is confirmed, the attacker submits their own deposit transaction using the victim's Public Key but linking it to the attacker's own account withdrawal credentials.
The deposit contract logic is flawed: if the Public Key is already present in the system (i.e., the user is initialized), the funds are added to that existing record (the `else` clause). By frontrunning the victim's transaction, the attacker ensures their transaction is processed first, associating the funds with their account, causing the victim's subsequent, successful deposit to credit the attacker instead of the intended new user account.
## Exploitation
- Status: Successfully identified and reported (Whitehat disclosure). Not explicitly stated if exploited prior to disclosure, but the mechanism was demonstrable.
- Complexity: Medium to High. Requires the attacker to be a **rogue node operator** within one of the staking pools, which is a privileged position. Exploitation requires precise timing (frontrunning) based on observed incoming deposit transactions.
- Attack Vector: Local/Transaction (Requires privileged role within the protocol ecosystem, leveraging knowledge of pending transactions).
## Impact
- Confidentiality: Low (No sensitive data theft implied).
- Integrity: High (User deposits intended for one validator are incorrectly credited to an attacker's account, resulting in fund loss for the legitimate user).
- Availability: Low (The staking service itself remains available, but user capital could be compromised).
## Remediation
### Patches
- Patches were deployed by both RocketPool and Lido Finance following disclosure. The fix involved correcting the logic within the internal staking pool contracts to ensure user identity verification was robust and not susceptible to frontrunning using externally visible (but spoofable) parameters like the Public Key in a way that allowed unauthorized reassignment.
- Payouts for this critical issue ($100K for each project) were issued on October 5th (RocketPool) and October 9th (Lido).
### Workarounds
- The primary underlying issue stemmed from the identification mechanism being observable and manipulable via transaction ordering. A potential (but likely infeasible for the end-user) workaround cited by the authors involves mitigating frontrunning attacks in general, although the core fix was in the contract logic itself. The vulnerability required a **rogue node operator**; removing or strictly monitoring such actors would be a procedural workaround until the contract fix was implemented.
## Detection
- Detection involves monitoring for unexpected fund consolidations to existing validator entries following the submission of what should have been a new user deposit.
- Specific indicators would be transactions that correctly execute the "add funds" logic (`else` clause in the description) when the accompanying data structure implies a *new* user creation should have occurred.
## References
- Vendor Advisories: Implied through the Bug Bounty reports on Immunefi.
- Relevant Links:
- Immunefi platform (General context for the report): hxxps://medium.com/immunefi/rocketpool-and-lido-frontrunning-bugfix-review-e701f26d7971