Skip to content

Commit 9ac0ef8

Browse files
authored
feat: track active validator count in pods (#474)
1 parent e12b03f commit 9ac0ef8

File tree

3 files changed

+36
-4
lines changed

3 files changed

+36
-4
lines changed

src/contracts/pods/EigenPod.sol

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,12 @@ contract EigenPod is IEigenPod, Initializable, ReentrancyGuardUpgradeable, Eigen
9191
/// @notice This variable tracks any ETH deposited into this contract via the `receive` fallback function
9292
uint256 public nonBeaconChainETHBalanceWei;
9393

94-
/// @notice This variable tracks the total amount of partial withdrawals claimed via merkle proofs prior to a switch to ZK proofs for claiming partial withdrawals
94+
/// @notice This variable tracks the total amount of partial withdrawals claimed via merkle proofs prior to a switch to ZK proofs for claiming partial withdrawals
9595
uint64 public sumOfPartialWithdrawalsClaimedGwei;
9696

97+
/// @notice Number of validators with proven withdrawal credentials, who do not have proven full withdrawals
98+
uint256 activeValidatorCount;
99+
97100
modifier onlyEigenPodManager() {
98101
require(msg.sender == address(eigenPodManager), "EigenPod.onlyEigenPodManager: not eigenPodManager");
99102
_;
@@ -479,6 +482,7 @@ contract EigenPod is IEigenPod, Initializable, ReentrancyGuardUpgradeable, Eigen
479482
});
480483

481484
// Proofs complete - update this validator's status, record its proven balance, and save in state:
485+
activeValidatorCount++;
482486
validatorInfo.status = VALIDATOR_STATUS.ACTIVE;
483487
validatorInfo.validatorIndex = validatorIndex;
484488
validatorInfo.mostRecentBalanceUpdateTimestamp = oracleTimestamp;
@@ -697,9 +701,12 @@ contract EigenPod is IEigenPod, Initializable, ReentrancyGuardUpgradeable, Eigen
697701
* Finally, the validator is fully withdrawn. Update their status and place in state:
698702
*/
699703

700-
validatorInfo.restakedBalanceGwei = 0;
701-
validatorInfo.status = VALIDATOR_STATUS.WITHDRAWN;
704+
if (validatorInfo.status != VALIDATOR_STATUS.WITHDRAWN) {
705+
activeValidatorCount--;
706+
validatorInfo.status = VALIDATOR_STATUS.WITHDRAWN;
707+
}
702708

709+
validatorInfo.restakedBalanceGwei = 0;
703710
_validatorPubkeyHashToInfo[validatorPubkeyHash] = validatorInfo;
704711

705712
emit FullWithdrawalRedeemed(validatorIndex, withdrawalTimestamp, recipient, withdrawalAmountGwei);

src/test/harnesses/EigenPodHarness.sol

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ contract EPInternalFunctions is EigenPod, Test {
2020
_GENESIS_TIME
2121
) {}
2222

23+
function getActiveValidatorCount() public view returns (uint256) {
24+
return activeValidatorCount;
25+
}
26+
27+
function setActiveValidatorCount(uint _count) public {
28+
activeValidatorCount = _count;
29+
}
30+
2331
function verifyWithdrawalCredentials(
2432
uint64 oracleTimestamp,
2533
bytes32 beaconStateRoot,

src/test/unit/EigenPodUnit.t.sol

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,8 @@ contract EigenPodUnitTests_VerifyWithdrawalCredentialsTests is EigenPodHarnessSe
453453
uint64 effectiveBalanceGwei = validatorFields.getEffectiveBalanceGwei();
454454
assertGt(effectiveBalanceGwei, MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, "Proof file has an effective balance less than 32 ETH");
455455

456+
uint activeValidatorCountBefore = eigenPodHarness.getActiveValidatorCount();
457+
456458
// Verify withdrawal credentials
457459
vm.expectEmit(true, true, true, true);
458460
emit ValidatorRestaked(validatorIndex);
@@ -467,6 +469,8 @@ contract EigenPodUnitTests_VerifyWithdrawalCredentialsTests is EigenPodHarnessSe
467469
);
468470

469471
// Checks
472+
uint activeValidatorCountAfter = eigenPodHarness.getActiveValidatorCount();
473+
assertEq(activeValidatorCountAfter, activeValidatorCountBefore + 1, "active validator count should increase when proving withdrawal credentials");
470474
assertEq(restakedBalanceWei, uint256(MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR) * uint256(1e9), "Returned restaked balance gwei should be max");
471475
_assertWithdrawalCredentialsSet(MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR);
472476
}
@@ -480,6 +484,8 @@ contract EigenPodUnitTests_VerifyWithdrawalCredentialsTests is EigenPodHarnessSe
480484
uint64 effectiveBalanceGwei = validatorFields.getEffectiveBalanceGwei();
481485
assertLt(effectiveBalanceGwei, MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, "Proof file has an effective balance greater than 32 ETH");
482486

487+
uint activeValidatorCountBefore = eigenPodHarness.getActiveValidatorCount();
488+
483489
// Verify withdrawal credentials
484490
vm.expectEmit(true, true, true, true);
485491
emit ValidatorRestaked(validatorIndex);
@@ -494,6 +500,8 @@ contract EigenPodUnitTests_VerifyWithdrawalCredentialsTests is EigenPodHarnessSe
494500
);
495501

496502
// Checks
503+
uint activeValidatorCountAfter = eigenPodHarness.getActiveValidatorCount();
504+
assertEq(activeValidatorCountAfter, activeValidatorCountBefore + 1, "active validator count should increase when proving withdrawal credentials");
497505
assertEq(restakedBalanceWei, uint256(effectiveBalanceGwei) * uint256(1e9), "Returned restaked balance gwei incorrect");
498506
_assertWithdrawalCredentialsSet(effectiveBalanceGwei);
499507
}
@@ -920,10 +928,19 @@ contract EigenPodUnitTests_WithdrawalTests is EigenPodHarnessSetup, ProofParsing
920928
mostRecentBalanceUpdateTimestamp: 0,
921929
status: IEigenPod.VALIDATOR_STATUS.ACTIVE
922930
});
931+
932+
// Since we're withdrawing using an ACTIVE validator, ensure we have
933+
// a validator count to decrement
934+
uint activeValidatorCountBefore = 1 + eigenPodHarness.getActiveValidatorCount();
935+
eigenPodHarness.setActiveValidatorCount(activeValidatorCountBefore);
923936

924-
// Process full withdrawal
937+
// Process full withdrawal.
925938
IEigenPod.VerifiedWithdrawal memory vw = eigenPodHarness.processFullWithdrawal(0, pubkeyHash, 0, podOwner, withdrawalAmount, validatorInfo);
926939

940+
// Validate that our activeValidatorCount decreased
941+
uint activeValidatorCountAfter = eigenPodHarness.getActiveValidatorCount();
942+
assertEq(activeValidatorCountAfter, activeValidatorCountBefore - 1, "active validator count should decrease when withdrawing active validator");
943+
927944
// Get expected amounts based on withdrawalAmount
928945
uint64 amountETHToQueue;
929946
uint64 amountETHToSend;

0 commit comments

Comments
 (0)