@@ -66,6 +66,9 @@ abstract contract NodesManager is
6666 /// @inheritdoc INodesManager
6767 mapping (address operator = > uint256 penaltyAssets ) public override pendingPenaltyAssets;
6868
69+ /// @inheritdoc INodesManager
70+ mapping (address operator = > address manager ) public override validatorsManagers;
71+
6972 mapping (uint256 positionTicket = > address operator ) private _exitPositions;
7073
7174 /**
@@ -128,6 +131,13 @@ abstract contract NodesManager is
128131 emit WithdrawalsManagerUpdated (newWithdrawalsManager);
129132 }
130133
134+ /// @inheritdoc INodesManager
135+ function setValidatorsManager (address validatorsManager ) external override {
136+ if (validatorsManagers[msg .sender ] == validatorsManager) revert Errors.ValueNotChanged ();
137+ validatorsManagers[msg .sender ] = validatorsManager;
138+ emit ValidatorsManagerUpdated (msg .sender , validatorsManager);
139+ }
140+
131141 /// @inheritdoc INodesManager
132142 function canUpdateState () external view override returns (bool ) {
133143 // SLOAD to memory
@@ -182,17 +192,19 @@ abstract contract NodesManager is
182192 }
183193
184194 /// @inheritdoc INodesManager
185- function updateOperatorState (OperatorStateUpdateParams calldata params ) external override {
195+ function updateOperatorState (address operator , OperatorStateUpdateParams calldata params ) external override {
196+ if (operator == address (0 )) revert Errors.ZeroAddress ();
197+
186198 // check whether the vault is harvested
187199 if (_keeper.isHarvestRequired (vault)) revert Errors.NotHarvested ();
188200
189201 // SLOAD to memory
190- OperatorState memory operatorState = operatorStates[msg . sender ];
202+ OperatorState memory operatorState = operatorStates[operator ];
191203 StateData memory _stateData = stateData;
192204 uint128 currentNonce = _stateData.currentNonce;
193205
194206 // skip update if the state is already up to date
195- if (operatorNonces[msg . sender ][OperatorNonceType.LastStateUpdate] == currentNonce) return ;
207+ if (operatorNonces[operator ][OperatorNonceType.LastStateUpdate] == currentNonce) return ;
196208
197209 // verify merkle proof against current state root
198210 if (! MerkleProof.verifyCalldata (
@@ -201,9 +213,7 @@ abstract contract NodesManager is
201213 keccak256 (
202214 bytes .concat (
203215 keccak256 (
204- abi.encode (
205- msg .sender , params.totalAssets, params.cumPenaltyAssets, params.cumEarnedFeeShares
206- )
216+ abi.encode (operator, params.totalAssets, params.cumPenaltyAssets, params.cumEarnedFeeShares)
207217 )
208218 )
209219 )
@@ -218,7 +228,7 @@ abstract contract NodesManager is
218228 // calculate total penalty including any pending penalty from previous updates
219229 uint256 totalPenaltyShares;
220230 uint256 penaltyAssetsDelta = params.cumPenaltyAssets - operatorState.cumPenaltyAssets;
221- uint256 totalPenaltyAssets = penaltyAssetsDelta + pendingPenaltyAssets[msg . sender ];
231+ uint256 totalPenaltyAssets = penaltyAssetsDelta + pendingPenaltyAssets[operator ];
222232 if (totalPenaltyAssets > 0 ) {
223233 totalPenaltyShares = IVaultState (vault).convertToShares (totalPenaltyAssets);
224234 }
@@ -227,11 +237,11 @@ abstract contract NodesManager is
227237 uint256 penaltySharesToDonate;
228238 if (totalPenaltyShares <= availableShares) {
229239 operatorState.balanceShares = SafeCast.toUint128 (availableShares - totalPenaltyShares);
230- pendingPenaltyAssets[msg . sender ] = 0 ;
240+ pendingPenaltyAssets[operator ] = 0 ;
231241 penaltySharesToDonate = totalPenaltyShares;
232242 } else {
233243 uint256 coveredPenaltyAssets = IVaultState (vault).convertToAssets (availableShares);
234- pendingPenaltyAssets[msg . sender ] = totalPenaltyAssets - coveredPenaltyAssets;
244+ pendingPenaltyAssets[operator ] = totalPenaltyAssets - coveredPenaltyAssets;
235245 operatorState.balanceShares = 0 ;
236246 penaltySharesToDonate = availableShares;
237247 }
@@ -240,27 +250,32 @@ abstract contract NodesManager is
240250 operatorState.totalAssets = params.totalAssets;
241251 operatorState.cumPenaltyAssets = params.cumPenaltyAssets;
242252 operatorState.cumEarnedFeeShares = params.cumEarnedFeeShares;
243- operatorStates[msg . sender ] = operatorState;
244- operatorNonces[msg . sender ][OperatorNonceType.LastStateUpdate] = currentNonce;
253+ operatorStates[operator ] = operatorState;
254+ operatorNonces[operator ][OperatorNonceType.LastStateUpdate] = currentNonce;
245255
246256 // donate penalty shares to the vault
247257 if (penaltySharesToDonate > 0 ) {
248258 IVaultState (vault).donateShares (penaltySharesToDonate);
249259 }
250260
251- emit OperatorStateUpdated (msg . sender , params.totalAssets, params.cumPenaltyAssets, params.cumEarnedFeeShares);
261+ emit OperatorStateUpdated (operator , params.totalAssets, params.cumPenaltyAssets, params.cumEarnedFeeShares);
252262 }
253263
254264 /// @inheritdoc INodesManager
255- function registerValidators (IKeeperValidators.ApprovalParams calldata keeperParams , bytes calldata signatures )
256- external
257- override
258- {
265+ function registerValidators (
266+ address operator ,
267+ IKeeperValidators.ApprovalParams calldata keeperParams ,
268+ bytes calldata signatures
269+ ) external override {
270+ if (validatorsManagers[operator] != msg .sender ) {
271+ revert Errors.AccessDenied ();
272+ }
273+
259274 // verify oracles approved registering these validators
260- uint256 nonce = _useOperatorNonce (msg . sender , OperatorNonceType.RegisterValidatorsSig);
275+ uint256 nonce = _useOperatorNonce (operator , OperatorNonceType.RegisterValidatorsSig);
261276 bytes32 digest = _hashTypedDataV4 (
262277 keccak256 (
263- abi.encode (_registerValidatorsTypeHash, msg . sender , nonce, vault, keccak256 (keeperParams.validators))
278+ abi.encode (_registerValidatorsTypeHash, operator , nonce, vault, keccak256 (keeperParams.validators))
264279 )
265280 );
266281 _verifySignatures (digest, signatures);
@@ -269,35 +284,37 @@ abstract contract NodesManager is
269284 IVaultValidators (vault).registerValidators (keeperParams, bytes ("" ));
270285
271286 // save state nonce at validator change
272- operatorNonces[msg . sender ][OperatorNonceType.LastValidatorChange] = stateData.currentNonce;
287+ operatorNonces[operator ][OperatorNonceType.LastValidatorChange] = stateData.currentNonce;
273288
274289 // extract public keys from validators data
275290 bytes memory publicKeys = _getValidatorsPublicKeys (keeperParams.validators);
276291
277292 // emit event
278- emit ValidatorsRegistered (msg . sender , nonce, publicKeys);
293+ emit ValidatorsRegistered (operator , nonce, publicKeys);
279294 }
280295
281296 /// @inheritdoc INodesManager
282- function fundValidators (bytes calldata validators , bytes calldata signatures ) external override {
297+ function fundValidators (address operator , bytes calldata validators , bytes calldata signatures ) external override {
298+ if (validatorsManagers[operator] != msg .sender ) revert Errors.AccessDenied ();
299+
283300 // verify oracles approved funding these validators
284- uint256 nonce = _useOperatorNonce (msg . sender , OperatorNonceType.FundValidatorsSig);
301+ uint256 nonce = _useOperatorNonce (operator , OperatorNonceType.FundValidatorsSig);
285302 bytes32 digest = _hashTypedDataV4 (
286- keccak256 (abi.encode (_fundValidatorsTypeHash, msg . sender , nonce, vault, keccak256 (validators)))
303+ keccak256 (abi.encode (_fundValidatorsTypeHash, operator , nonce, vault, keccak256 (validators)))
287304 );
288305 _verifySignatures (digest, signatures);
289306
290307 // fund validators in the vault
291308 IVaultValidators (vault).fundValidators (validators, bytes ("" ));
292309
293310 // save state nonce at validator change
294- operatorNonces[msg . sender ][OperatorNonceType.LastValidatorChange] = stateData.currentNonce;
311+ operatorNonces[operator ][OperatorNonceType.LastValidatorChange] = stateData.currentNonce;
295312
296313 // extract public keys from validators data
297314 bytes memory publicKeys = _getValidatorsPublicKeys (validators);
298315
299316 // emit event
300- emit ValidatorsFunded (msg . sender , nonce, publicKeys);
317+ emit ValidatorsFunded (operator , nonce, publicKeys);
301318 }
302319
303320 /// @inheritdoc INodesManager
0 commit comments