Skip to content

EIP-7002 Fee Mechanism Analysis for RPIP-44

Overview

EIP-7002 (Execution Layer Triggerable Withdrawals) introduces a system contract that allows the execution layer to trigger validator exits. The contract uses an EIP-1559-style exponential fee mechanism to rate-limit withdrawal requests. This document analyses the fee dynamics and their ramifications for Rocket Pool's RPIP-44 (EL Triggerable Exits).

How the fee mechanism works

The system contract

EIP-7002 deploys a system contract at 0x00000961Ef480Eb55e80D19ad83579A64c007002. The contract accepts withdrawal requests from any caller — it does not validate withdrawal credentials on the execution layer. Instead, the consensus layer validates that the source_address (recorded as msg.sender) matches the validator's 0x01 withdrawal credential. Requests that fail this check are silently dropped.

For Rocket Pool, the megapool contract holds the withdrawal credentials and must therefore be the msg.sender.

The contract exposes two operations:

  • fee() — returns the current fee in wei (triggered by zero-length calldata)
  • addWithdrawalRequest(pubkey, amount) — submits a withdrawal request (56-byte calldata), requires msg.value >= fee()

Fee formula

The fee is computed using fake_exponential, a Taylor series integer approximation of the natural exponential:

fee = 1 wei × e^(excess / 17)

Where:

  • excess is a running counter of how much withdrawal request volume exceeds the target rate
  • 17 is the WITHDRAWAL_REQUEST_FEE_UPDATE_FRACTION — controls how aggressively fees respond to demand

Excess accumulation

The excess counter is updated once per block via a system call at block end:

new_excess = max(0, previous_excess + requests_this_block - 2)

The target rate is 2 requests per block. When usage exceeds 2, excess grows. When usage drops below 2, excess shrinks. The maximum number of requests dequeued per block is 16, but there is no cap on the number of requests that can be submitted in a single block — the gas limit is the only constraint.

Anti-griefing design

The system contract does not validate withdrawal credentials — anyone can submit requests for any pubkey, and the count (which feeds excess) increments regardless. Invalid requests are filtered later by the consensus layer but still contribute to the fee.

EIP-7002 deliberately chose this design over credential validation (which would have required cross-layer proof via EIP-4788). Instead, the exponential fee mechanism itself serves as the anti-griefing measure: an attacker who spams the queue must pay the same escalating fees as everyone else. Sustained griefing becomes exponentially expensive, making the mechanism self-correcting.

Critical property: all requests in the same block pay the same fee

The fee is based on excess, which only updates at block boundaries. All withdrawal requests submitted within a single block read the same excess value and therefore pay the same fee. There is no within-block fee escalation.

Fee escalation occurs between blocks as excess accumulates.

Requests required to reach fee levels

The excess needed for a given fee level is excess = 17 × ln(fee_in_wei). The minimum number of requests to reach that excess depends on how they are distributed over time, since 2 requests per block are absorbed by the target rate.

Fee level Excess needed Min requests (1 block) Over 10 blocks (2 min) Over 100 blocks (20 min) Over 1 hour (300 blocks)
0.001 ETH 588 590 608 788 1,188
0.01 ETH 627 629 647 827 1,227
0.1 ETH 666 668 686 866 1,266
0.2 ETH 678 680 698 878 1,278
1 ETH 705 707 725 905 1,305
10 ETH 744 746 764 944 1,344

A single block can hold approximately 780 requests (via individual EOA transactions at ~46K gas each) or ~1,285 requests (via a batching contract at ~28K gas each), given a 36M gas block limit. A burst of ~680 requests in a single block would spike the fee to 0.2 ETH in the following block — but the attacker pays only 1 wei per request (the pre-spike fee) plus ~1 ETH in gas costs.

However, this spike is self-correcting: with no further above-target submissions, excess decays at 2 per block and the fee drops below 0.01 ETH within ~7 minutes. Validator exits operate on epoch timescales (6.4 minutes), so a brief fee spike can be waited out. The fee mechanism is designed to make sustained elevation expensive, not to prevent momentary spikes.

Fee dynamics under sustained load

Sustained max throughput (16 requests/block)

Starting from excess = 0 (no prior congestion), with every block containing 16 withdrawal requests:

Block Excess (start) Fee per request Block cost (16 requests) Cumulative cost
1 0 1 wei 16 wei 16 wei
2 14 2 wei 32 wei 48 wei
5 56 26 wei 416 wei 720 wei
10 126 1,649 wei 26,384 wei 46,880 wei
20 266 6.2M wei 99.9M wei 178M wei
30 406 23.6 Gwei 376.8 Gwei 671.4 Gwei
40 546 88.8 mETH 0.0014 ETH 0.0025 ETH
45 616 0.0055 ETH 0.087 ETH 0.156 ETH
50 686 0.335 ETH 5.36 ETH 9.55 ETH
55 756 20.57 ETH 329.18 ETH 586.65 ETH
60 826 1,263.52 ETH 20,216 ETH 36,029 ETH

The exponential nature means fees are negligible for ~40 blocks, then rapidly become catastrophic. The transition from 0.01 ETH to 10 ETH per request takes only 9 blocks (~108 seconds).

Time to reach fee milestones at different sustained rates

Requests/block Net excess/block 0.001 ETH 0.01 ETH 0.1 ETH 0.2 ETH 1 ETH 10 ETH
3 1 117.8 min 125.6 min 133.4 min 135.8 min 141.2 min 149.0 min
4 2 59.0 min 63.0 min 66.8 min 68.0 min 70.8 min 74.6 min
6 4 29.6 min 31.6 min 33.6 min 34.2 min 35.6 min 37.4 min
8 6 19.8 min 21.2 min 22.4 min 22.8 min 23.8 min 25.0 min
10 8 15.0 min 16.0 min 17.0 min 17.2 min 18.0 min 18.8 min
16 14 8.6 min 9.2 min 9.8 min 10.0 min 10.4 min 11.0 min

At modest sustained rates (3-4 requests/block), it takes over an hour to reach meaningful fee levels. Dangerous fees require sustained high throughput — a genuine market-wide exit event, not a brief spike.

Realistic Rocket Pool scenarios

Isolated operation (RP is the only user)

Starting from excess = 0, with Rocket Pool as the sole user of the withdrawal request queue:

Validators to exit Blocks needed Time Total cost Max fee per request
10 1 12s 10 wei 1 wei
50 4 48s 150 wei 11 wei
100 7 84s 2,200 wei 138 wei
500 32 6.4 min 0.002 ETH 122 Gwei

Finding: When acting alone from a cold start, fees are economically irrelevant even for large exit batches. Exiting 500 validators costs 0.002 ETH total.

Entering a congested queue

The real risk is Rocket Pool needing to trigger exits when other operators have already been saturating the queue. If excess has built up from prior activity:

Pre-existing excess Fee per exit Cost for 10 exits Fee next block
0 1 wei 10 wei 2 wei
300 46K wei 461K wei 118K wei
500 5.9 mETH 59.3 mETH 15.2 mETH
600 0.002 ETH 0.021 ETH 0.005 ETH
625 0.009 ETH 0.093 ETH 0.024 ETH
650 0.040 ETH 0.403 ETH 0.103 ETH
675 0.175 ETH 1.754 ETH 0.450 ETH
700 0.763 ETH 7.633 ETH 1.956 ETH

RPIP-44 threshold breach

At excess 675, a single forced exit costs 0.175 ETH — nearly the entire RPIP-44 exit_deficit threshold of 0.2 ETH. At excess 700, it exceeds the threshold by 3.8×.

Fee cooldown

After a spike, excess decays by 2 per block (the target rate) when no new requests are submitted:

Starting excess Starting fee Blocks to < 0.01 ETH Blocks to baseline (1 wei) Time to baseline
300 46K wei 1 150 30 min
500 5.9 mETH 1 250 50 min
600 0.002 ETH 1 300 60 min
700 0.763 ETH 37 350 70 min
800 273.76 ETH 87 400 80 min

Fee cooldown is slow. From excess 700, it takes 70 minutes to return to baseline and 7.4 minutes to drop below 0.01 ETH. A fee spike is a sustained window, not a momentary blip.

Ramifications for RPIP-44

1. Fee payment source is unspecified

EIP-7002 requires msg.sender to match the 0x01 withdrawal credential — which is the megapool contract. The megapool must hold or receive ETH to pay the fee. RPIP-44 does not specify:

  • Who bears the EIP-7002 fee
  • Whether the fee is deducted from the node operator's bond/rewards
  • How the fee ETH reaches the megapool at the time of the call

2. The debt mechanism is a natural fit

The megapool already tracks a debt variable — a running balance the node operator owes the protocol. Today it covers dissolution penalties, late notification fines, shortfalls, and MEV penalties. Debt has real enforcement:

  • Blocks new validator creation (debt > 0 check in newValidator())
  • Blocks bond reduction (debt > 0 check in reduceBond())
  • Auto-deducted from the node operator's share during distributeRewards() and notifyFinalBalance()
  • Can be explicitly repaid via repayDebt()

EIP-7002 fees for forced exits could be added to debt, recovered from future rewards or exit proceeds. The open question is who provides the ETH to pay the system contract immediately — debt is a future claim, but the fee must be paid in the transaction.

3. The 0.2 ETH exit deficit threshold may be insufficient

RPIP-44 defines exit_deficit = 0.2 ETH as the threshold for permissionless forced exits. During a congested withdrawal request queue (excess >= 675), the EIP-7002 fee alone approaches or exceeds this threshold, making forced exits economically irrational for the caller.

Recommendation: Add a fee ceiling check. If the current EIP-7002 fee exceeds a configurable threshold (e.g., 0.05 ETH), defer the forced exit. This prevents burning value during fee spikes while preserving the mechanism for normal conditions.

4. Batch exits compound cross-block costs

Each validator requires a separate EIP-7002 withdrawal request. If Rocket Pool needs to exit multiple validators across several blocks, each block's requests increase excess, raising fees for subsequent blocks. This cross-block escalation is modest when RP acts alone (excess grows by 14 per block at max rate) but compounds with background demand from other protocols.

5. Overpaid fees are not refunded

EIP-7002 explicitly states that overpaid fees are not returned. The megapool implementation must read fee() immediately before each addWithdrawalRequest call and send exactly that amount. The EIP provides a reference Solidity pattern:

uint256 fee = IWithdrawalRequest(WITHDRAWAL_REQUEST_ADDRESS).fee();
IWithdrawalRequest(WITHDRAWAL_REQUEST_ADDRESS).addWithdrawalRequest{value: fee}(pubkey);

6. Griefing vector

The system contract does not validate withdrawal credentials on the execution layer — any address can submit requests for any pubkey, incrementing the count and thus the excess. An attacker can spike fees with a single block of ~680 junk requests for approximately 1 ETH in gas and negligible EIP-7002 fees (all requests in the same block pay the pre-spike fee).

The EIP-7002 fee mechanism is designed to counter this through self-correction: the exponential fee makes sustained griefing prohibitively expensive (the attacker must keep paying the escalating fee), and brief spikes decay naturally. From excess 680, the fee drops below 0.01 ETH within ~37 blocks (~7.4 minutes) and returns to baseline within ~340 blocks (~68 minutes). Since validator exits operate on epoch timescales, a brief spike can be waited out by delaying the exit transaction.

Recommendations

  1. Specify fee payment in RPIP-44: For voluntary exits, the node operator funds the fee via msg.value. For permissionless forced exits, the caller fronts the fee, which is added to the node operator's debt and repaid from future rewards/exit proceeds.

  2. Implement a fee ceiling: The megapool's exit function should read fee() and revert if it exceeds a configurable maximum (e.g., 0.05 ETH). This prevents economically irrational forced exits during fee spikes.

  3. Document cross-protocol risk: The primary fee risk to Rocket Pool is not self-inflicted but comes from market-wide exit events. Monitoring the EIP-7002 excess counter should be part of operational awareness.

  4. Consider fee-aware deficit accounting: If the EIP-7002 fee is deducted from the node operator's debt, the exit_deficit threshold effectively shrinks. RPIP-44 could specify that the deficit threshold is net of expected fees: effective_deficit = deficit - estimated_fee.

Empirical data: mainnet fee history

Sampling methodology

The EIP-7002 system contract at 0x00000961Ef480Eb55e80D19ad83579A64c007002 was queried at 12-hour intervals (~3,600 block intervals) across the full period from Pectra activation (May 7, 2025) through to March 12, 2026 using an archive node. The fee was read by calling the contract with empty calldata, which triggers the fee() getter.

Results

181 samples were taken. Every single sample returned 1 wei (the minimum fee).

The excess counter has never risen above 0 at any sampled point since EIP-7002 went live on mainnet. This means withdrawal request throughput has never sustained above the target rate of 2 requests per block for any period long enough to register at 12-hour granularity.

Period Samples Min fee Max fee Above minimum
Dec 2025 31 1 wei 1 wei 0
Jan 2026 31 1 wei 1 wei 0
Feb 2026 28 1 wei 1 wei 0
Mar 2026 (partial) 5 1 wei 1 wei 0
Total 181 1 wei 1 wei 0

Interpretation

The fee mechanism is functioning exactly as designed — negligible cost under normal conditions. The theoretical fee spikes analysed in this document require sustained above-target demand that has not materialised in the ~10 months since Pectra activation.

This is consistent with the current state of the validator exit queue: there has been no market-wide exit event of the scale needed to saturate the EIP-7002 withdrawal request queue. The fee risk for RPIP-44 remains real but is contingent on future black swan events (mass slashings, market crashes triggering coordinated exits, or a major staking operator winding down).

Sampling limitation

12-hour sampling could miss brief intra-day spikes where excess rose and fell back to 0 within the interval. However, given the cooldown rate of 2 per block, even a modest spike to excess 100 takes 50 blocks (10 minutes) to decay — well within detection range of more frequent monitoring. A spike significant enough to affect RPIP-44 economics (excess > 600) would take over an hour to cool down and would be captured by this sampling.

Methodology

Fee calculations use the exact integer fake_exponential function specified in EIP-7002, not floating-point approximations. The integer implementation matches e^(excess/17) to within 0.01% for excess values above 200. Simulations assume no concurrent requests from other protocols unless stated otherwise. Mainnet fee data was collected on March 12, 2026 via archive node RPC queries.

References