diff --git a/contracts/contracts/strategies/NativeStaking/ValidatorRegistrator.sol b/contracts/contracts/strategies/NativeStaking/ValidatorRegistrator.sol index 9a407261e0..9b6455e012 100644 --- a/contracts/contracts/strategies/NativeStaking/ValidatorRegistrator.sol +++ b/contracts/contracts/strategies/NativeStaking/ValidatorRegistrator.sol @@ -55,12 +55,29 @@ abstract contract ValidatorRegistrator is Governable, Pausable { EXIT_COMPLETE // validator has funds withdrawn to the EigenPod and is removed from the SSV } - event RegistratorChanged(address newAddress); - event StakingMonitorChanged(address newAddress); - event ETHStaked(bytes pubkey, uint256 amount, bytes withdrawal_credentials); - event SSVValidatorRegistered(bytes pubkey, uint64[] operatorIds); - event SSVValidatorExitInitiated(bytes pubkey, uint64[] operatorIds); - event SSVValidatorExitCompleted(bytes pubkey, uint64[] operatorIds); + event RegistratorChanged(address indexed newAddress); + event StakingMonitorChanged(address indexed newAddress); + event ETHStaked( + bytes32 indexed pubKeyHash, + bytes pubKey, + uint256 amount, + bytes withdrawal_credentials + ); + event SSVValidatorRegistered( + bytes32 indexed pubKeyHash, + bytes pubKey, + uint64[] operatorIds + ); + event SSVValidatorExitInitiated( + bytes32 indexed pubKeyHash, + bytes pubKey, + uint64[] operatorIds + ); + event SSVValidatorExitCompleted( + bytes32 indexed pubKeyHash, + bytes pubKey, + uint64[] operatorIds + ); event StakeETHThresholdChanged(uint256 amount); event StakeETHTallyReset(); @@ -171,8 +188,8 @@ abstract contract ValidatorRegistrator is Governable, Pausable { uint256 validatorsLength = validators.length; // For each validator for (uint256 i = 0; i < validatorsLength; ) { - bytes32 pubkeyHash = keccak256(validators[i].pubkey); - VALIDATOR_STATE currentState = validatorsStates[pubkeyHash]; + bytes32 pubKeyHash = keccak256(validators[i].pubkey); + VALIDATOR_STATE currentState = validatorsStates[pubKeyHash]; require( currentState == VALIDATOR_STATE.REGISTERED, @@ -189,12 +206,13 @@ abstract contract ValidatorRegistrator is Governable, Pausable { ); emit ETHStaked( + pubKeyHash, validators[i].pubkey, 32 ether, withdrawal_credentials ); - validatorsStates[pubkeyHash] = VALIDATOR_STATE.STAKED; + validatorsStates[pubKeyHash] = VALIDATOR_STATE.STAKED; unchecked { ++i; @@ -216,9 +234,9 @@ abstract contract ValidatorRegistrator is Governable, Pausable { uint256 amount, Cluster calldata cluster ) external onlyRegistrator whenNotPaused { + bytes32 pubKeyHash = keccak256(publicKey); require( - validatorsStates[keccak256(publicKey)] == - VALIDATOR_STATE.NON_REGISTERED, + validatorsStates[pubKeyHash] == VALIDATOR_STATE.NON_REGISTERED, "Validator already registered" ); ISSVNetwork(SSV_NETWORK_ADDRESS).registerValidator( @@ -228,8 +246,9 @@ abstract contract ValidatorRegistrator is Governable, Pausable { amount, cluster ); - validatorsStates[keccak256(publicKey)] = VALIDATOR_STATE.REGISTERED; - emit SSVValidatorRegistered(publicKey, operatorIds); + emit SSVValidatorRegistered(pubKeyHash, publicKey, operatorIds); + + validatorsStates[pubKeyHash] = VALIDATOR_STATE.REGISTERED; } // slither-disable-end reentrancy-no-eth @@ -242,13 +261,14 @@ abstract contract ValidatorRegistrator is Governable, Pausable { bytes calldata publicKey, uint64[] calldata operatorIds ) external onlyRegistrator whenNotPaused { - VALIDATOR_STATE currentState = validatorsStates[keccak256(publicKey)]; + bytes32 pubKeyHash = keccak256(publicKey); + VALIDATOR_STATE currentState = validatorsStates[pubKeyHash]; require(currentState == VALIDATOR_STATE.STAKED, "Validator not staked"); ISSVNetwork(SSV_NETWORK_ADDRESS).exitValidator(publicKey, operatorIds); - emit SSVValidatorExitInitiated(publicKey, operatorIds); + emit SSVValidatorExitInitiated(pubKeyHash, publicKey, operatorIds); - validatorsStates[keccak256(publicKey)] = VALIDATOR_STATE.EXITING; + validatorsStates[pubKeyHash] = VALIDATOR_STATE.EXITING; } // slither-disable-end reentrancy-no-eth @@ -263,7 +283,8 @@ abstract contract ValidatorRegistrator is Governable, Pausable { uint64[] calldata operatorIds, Cluster calldata cluster ) external onlyRegistrator whenNotPaused { - VALIDATOR_STATE currentState = validatorsStates[keccak256(publicKey)]; + bytes32 pubKeyHash = keccak256(publicKey); + VALIDATOR_STATE currentState = validatorsStates[pubKeyHash]; require( currentState == VALIDATOR_STATE.EXITING, "Validator not exiting" @@ -274,9 +295,9 @@ abstract contract ValidatorRegistrator is Governable, Pausable { operatorIds, cluster ); - emit SSVValidatorExitCompleted(publicKey, operatorIds); + emit SSVValidatorExitCompleted(pubKeyHash, publicKey, operatorIds); - validatorsStates[keccak256(publicKey)] = VALIDATOR_STATE.EXIT_COMPLETE; + validatorsStates[pubKeyHash] = VALIDATOR_STATE.EXIT_COMPLETE; } // slither-disable-end reentrancy-no-eth diff --git a/contracts/test/behaviour/ssvStrategy.js b/contracts/test/behaviour/ssvStrategy.js index 0a86594136..b748c0fdfc 100644 --- a/contracts/test/behaviour/ssvStrategy.js +++ b/contracts/test/behaviour/ssvStrategy.js @@ -199,7 +199,11 @@ const shouldBehaveLikeAnSsvStrategy = (context) => { ); await expect(regTx) .to.emit(nativeStakingSSVStrategy, "SSVValidatorRegistered") - .withArgs(testValidator.publicKey, testValidator.operatorIds); + .withArgs( + keccak256(testValidator.publicKey), + testValidator.publicKey, + testValidator.operatorIds + ); expect( await nativeStakingSSVStrategy.validatorsStates( @@ -221,7 +225,8 @@ const shouldBehaveLikeAnSsvStrategy = (context) => { await expect(stakeTx) .to.emit(nativeStakingSSVStrategy, "ETHStaked") .withNamedArgs({ - pubkey: testValidator.publicKey, + pubKeyHash: keccak256(testValidator.publicKey), + pubKey: testValidator.publicKey, amount: oethUnits("32"), }); @@ -397,7 +402,11 @@ const shouldBehaveLikeAnSsvStrategy = (context) => { await expect(exitTx) .to.emit(nativeStakingSSVStrategy, "SSVValidatorExitInitiated") - .withArgs(testValidator.publicKey, testValidator.operatorIds); + .withArgs( + keccak256(testValidator.publicKey), + testValidator.publicKey, + testValidator.operatorIds + ); const removeTx = await nativeStakingSSVStrategy .connect(validatorRegistrator) @@ -409,7 +418,11 @@ const shouldBehaveLikeAnSsvStrategy = (context) => { await expect(removeTx) .to.emit(nativeStakingSSVStrategy, "SSVValidatorExitCompleted") - .withArgs(testValidator.publicKey, testValidator.operatorIds); + .withArgs( + keccak256(testValidator.publicKey), + testValidator.publicKey, + testValidator.operatorIds + ); }); }); diff --git a/contracts/test/strategies/nativeSSVStaking.js b/contracts/test/strategies/nativeSSVStaking.js index 9a116a1fe4..382419ebc2 100644 --- a/contracts/test/strategies/nativeSSVStaking.js +++ b/contracts/test/strategies/nativeSSVStaking.js @@ -1090,7 +1090,7 @@ describe("Unit test: Native SSV Staking Strategy", function () { const stakeAmount = ethUnits("32"); // Register a new validator with the SSV Network - await nativeStakingSSVStrategy + const regTx = await nativeStakingSSVStrategy .connect(validatorRegistrator) .registerSsvValidator( testPublicKeys[i], @@ -1100,6 +1100,14 @@ describe("Unit test: Native SSV Staking Strategy", function () { emptyCluster ); + await expect(regTx) + .to.emit(nativeStakingSSVStrategy, "SSVValidatorRegistered") + .withArgs( + keccak256(testPublicKeys[i]), + testPublicKeys[i], + testValidator.operatorIds + ); + expect( await nativeStakingSSVStrategy.validatorsStates( keccak256(testPublicKeys[i]) @@ -1107,7 +1115,7 @@ describe("Unit test: Native SSV Staking Strategy", function () { ).to.equal(1, "Validator state not 1 (REGISTERED)"); // Stake ETH to the new validator - const tx = nativeStakingSSVStrategy + const stakeTx = nativeStakingSSVStrategy .connect(validatorRegistrator) .stakeEth([ { @@ -1118,9 +1126,19 @@ describe("Unit test: Native SSV Staking Strategy", function () { ]); if (stakeTresholdErrorTriggered && i == validators - 1) { - await expect(tx).to.be.revertedWith("Staking ETH over threshold"); + await expect(stakeTx).to.be.revertedWith( + "Staking ETH over threshold" + ); } else { - await tx; + await stakeTx; + + await expect(stakeTx) + .to.emit(nativeStakingSSVStrategy, "ETHStaked") + .withNamedArgs({ + pubKeyHash: keccak256(testPublicKeys[i]), + pubKey: testPublicKeys[i], + amount: parseEther("32"), + }); expect( await nativeStakingSSVStrategy.validatorsStates(