Function: batchFullWithdraw(uint256[] _validatorIds)
The function processes the full withdrawal for multiple validators.
Inputs
_validatorIds
Control: Fully controlled.
Constraints: No specific constraints.
Impact: Validator IDs for which full withdrawals need to be executed.
Branches and code coverage
Intended branches
Updates the etherFiNode for the validator ID.
Sets the validator phase to
FULLY_WITHDRAWN
.The function will unregister the validators, distribute the payouts, and burn the TNFT and BNFT related to the validator ID.
Negative behavior
Revert if there are pending withdrawals left.
Revert if the phase is not
EXITED
.
Function call analysis
this.fullWithdraw(_validatorIds[i]) -> this._updateEtherFiNode(_validatorId) -> IEtherFiNode(etherfiNode).version()
What is controllable? Not controllable.
If the return value is controllable, how is it used and how can it go wrong? Retrieves the version of etherFiNode.
What happens if it reverts, reenters, or does other unusual control flow? If this call reverts, it might indicate an issue with the EtherFiNode or an unexpected state.
this.fullWithdraw(_validatorIds[i]) -> this._updateEtherFiNode(_validatorId) -> IEtherFiNode(etherfiNode).DEPRECATED_exitRequestTimestamp()
What is controllable? Not controllable.
If the return value is controllable, how is it used and how can it go wrong? Retrieves the deprecated exit-request timestamp.
What happens if it reverts, reenters, or does other unusual control flow? N/A.
this.fullWithdraw(_validatorIds[i]) -> this._updateEtherFiNode(_validatorId) -> IEtherFiNode(etherfiNode).DEPRECATED_exitTimestamp()
What is controllable? Not controllable.
If the return value is controllable, how is it used and how can it go wrong? Retrieves the deprecated exit timestamp.
What happens if it reverts, reenters, or does other unusual control flow? N/A.
this.fullWithdraw(_validatorIds[i]) -> this._updateEtherFiNode(_validatorId) -> IEtherFiNode(etherfiNode).DEPRECATED_phase()
What is controllable? Not controllable.
If the return value is controllable, how is it used and how can it go wrong? Retrieves the deprecated phase.
What happens if it reverts, reenters, or does other unusual control flow? N/A.
this.fullWithdraw(_validatorIds[i]) -> this._updateEtherFiNode(_validatorId) -> IEtherFiNode(etherfiNode).migrateVersion(_validatorId)
What is controllable?
_validatorId
.If the return value is controllable, how is it used and how can it go wrong? Updates the EtherFiNode version related to each validator ID.
What happens if it reverts, reenters, or does other unusual control flow? If this call reverts, it might indicate an issue with migrating the version — no reentrancy scenario.
this.fullWithdraw(_validatorIds[i]) -> IEtherFiNode(etherfiNode).claimQueuedWithdrawals(this.maxEigenlayerWithdrawals, true)
What is controllable? Not controllable.
If the return value is controllable, how is it used and how can it go wrong? Claims queued withdrawals from the EtherFiNode related to each validator ID.
What happens if it reverts, reenters, or does other unusual control flow? If this call reverts, it might indicate an issue with claiming queued withdrawals — no reentrancy scenario.
this.fullWithdraw(_validatorIds[i]) -> this.getFullWithdrawalPayouts (_validatorId) -> IEtherFiNode(etherfiNode).getFullWithdrawalPayouts (this.getValidatorInfo(_validatorId), this.stakingRewardsSplit)
What is controllable?
_validatorId
.If the return value is controllable, how is it used and how can it go wrong? Calculates full withdrawal payouts and retrieves full withdrawal payouts from the EtherFiNode based on validator info and staking rewards split.
What happens if it reverts, reenters, or does other unusual control flow? If this call reverts, it might indicate an issue with calculating full withdrawal payouts — no reentrancy scenario.
this.fullWithdraw(_validatorIds[i]) -> this._unRegisterValidator(_validatorId) -> this._setValidatorPhase(safeAddress, _validatorId, VALIDATOR_PHASE.FULLY_WITHDRAWN) -> IEtherFiNode(_node).validatePhaseTransition(this.phase(_validatorId), _newPhase)
What is controllable?
_validatorId
.If the return value is controllable, how is it used and how can it go wrong? Sets the validator phase to fully withdrawn and validates the phase transition on the EtherFiNode.
What happens if it reverts, reenters, or does other unusual control flow? If this call reverts, it might indicate an issue the phase transition — no reentrancy scenario.
this.fullWithdraw(_validatorIds[i]) -> this._unRegisterValidator(_validatorId) -> IEtherFiNode(safeAddress).unRegisterValidator(_validatorId, this.validatorInfos[_validatorId])
What is controllable?
_validatorId
.If the return value is controllable, how is it used and how can it go wrong? Unregisters the validator on the EtherFiNode.
What happens if it reverts, reenters, or does other unusual control flow? If this call reverts, it might indicate an issue with unregistering the validator on the EtherFiNode — no reentrancy scenario.
this.fullWithdraw(_validatorIds[i]) -> this._unRegisterValidator(_validatorId) -> IEtherFiNode(safeAddress).numAssociatedValidators()
What is controllable? Not controllable.
If the return value is controllable, how is it used and how can it go wrong? Retrieves the number of associated validators from the EtherFiNode.
What happens if it reverts, reenters, or does other unusual control flow? N/A.
this.fullWithdraw(_validatorIds[i]) -> this._distributePayouts(etherfiNode, _validatorId, toTreasury, toOperator, toTnft, toBnft) -> IEtherFiNode(_etherfiNode).withdrawFunds(this.treasuryContract, _toTreasury, this.auctionManager.getBidOwner(_validatorId), _toOperator, this.tnft.ownerOf(_validatorId), _toTnft, this.bnft.ownerOf(_validatorId), _toBnft)
What is controllable?
_validatorId
.If the return value is controllable, how is it used and how can it go wrong? Distributes payouts from the EtherFiNode to relevant parties.
What happens if it reverts, reenters, or does other unusual control flow? If this call reverts, it might indicate an issue with the reward distribution — no reentrancy scenario.
this.fullWithdraw(_validatorIds[i]) -> this._distributePayouts(etherfiNode, _validatorId, toTreasury, toOperator, toTnft, toBnft) -> this.auctionManager.getBidOwner(_validatorId)
What is controllable?
_validatorId
.If the return value is controllable, how is it used and how can it go wrong? Retrieves the bid owner from the auction manager.
What happens if it reverts, reenters, or does other unusual control flow? N/A.
this.fullWithdraw(_validatorIds[i]) -> this._distributePayouts(etherfiNode, _validatorId, toTreasury, toOperator, toTnft, toBnft) -> this.tnft.ownerOf(_validatorId)
What is controllable?
_validatorId
.If the return value is controllable, how is it used and how can it go wrong? Retrieves the TNFT owner.
What happens if it reverts, reenters, or does other unusual control flow? N/A.
this.fullWithdraw(_validatorIds[i]) -> this._distributePayouts(etherfiNode, _validatorId, toTreasury, toOperator, toTnft, toBnft) -> this.bnft.ownerOf(_validatorId)
What is controllable?
_validatorId
.If the return value is controllable, how is it used and how can it go wrong? Retrieves the BNFT owner.
What happens if it reverts, reenters, or does other unusual control flow? N/A.
this.fullWithdraw(_validatorIds[i]) -> this.tnft.burnFromWithdrawal (_validatorId)
What is controllable?
_validatorId
.If the return value is controllable, how is it used and how can it go wrong? Burns the TNFT from withdrawal.
What happens if it reverts, reenters, or does other unusual control flow? N/A.
this.fullWithdraw(_validatorIds[i]) -> this.bnft.burnFromWithdrawal (_validatorId)
What is controllable?
_validatorId
.If the return value is controllable, how is it used and how can it go wrong? Burns the BNFT from withdrawal.
What happens if it reverts, reenters, or does other unusual control flow? N/A.