Skip to content
Draft
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
2a4e501
Implemented flow to trigger validators exit
eladiosch May 13, 2025
d5b1a1e
Added role to trigger validators exit
eladiosch May 14, 2025
607aa38
Removed references to enclave in PufferProtocol and adapted tests (WIP)
eladiosch May 14, 2025
03e6b6d
Changed unused enclave variables to deprecated. Removed unused code
eladiosch May 16, 2025
0a81b7e
Removed getPayload function
eladiosch May 16, 2025
bddc349
Adapted remaining failing tests
eladiosch May 16, 2025
1f7b508
Added tests for new flow
eladiosch May 16, 2025
f5f8a40
forge fmt
eladiosch May 16, 2025
8c82c52
Changed flow from triggerValidatorsExit to requestWithdrawal
eladiosch May 26, 2025
8926347
Added fee to PufferProtocol.requestWithdrawal
eladiosch May 27, 2025
7000731
Refactored fee return to modifier
eladiosch May 27, 2025
01ba5b2
Implemented consolidation flow
eladiosch May 27, 2025
acd617c
Changed withdrawal credentials to type 2
eladiosch May 28, 2025
d6d18be
Changed callStake to deposit directly to beacon chain contract
eladiosch May 28, 2025
a64a585
validator tickets -> validation time
bxmmm1 May 29, 2025
3d7aaae
Added relation pubkey => module+index in storage
eladiosch May 29, 2025
8937e08
provision flow (WIP)
eladiosch May 30, 2025
3d35d5f
forge fmt
eladiosch May 30, 2025
b7e7d56
Removed return excess fee flow
eladiosch May 30, 2025
199b7d2
Use moduleName + indices in withdrawal and consolidation flows
eladiosch May 30, 2025
b0e59aa
Implemented upgrading validators to type2 in PMM
eladiosch May 30, 2025
cb996fa
forge fmt
eladiosch May 30, 2025
4ae75c3
Added accounting to consolidation flow
eladiosch Jun 2, 2025
7f0f5c2
update natspec, remove buggy code
bxmmm1 Jun 4, 2025
8bb6958
Adapted requestWithdrawal and batchHandleWithdrawals
eladiosch Jun 5, 2025
aeed0e2
Adapted some comments and updated ValidatorKeyData
eladiosch Jun 6, 2025
717a387
Fixed oracle call
eladiosch Jun 6, 2025
d162236
Adapted tests and refactor batchHandleWithdrawals
eladiosch Jun 6, 2025
5f3132e
Spell error
eladiosch Jun 6, 2025
8d365bd
Set PufferProtocol as payable to fix provisionNode
eladiosch Jun 9, 2025
d7ccb26
Removed placeholder value from Oracle
eladiosch Jun 9, 2025
28790a0
Fixed failing tests + writing new ones
eladiosch Jun 9, 2025
a76adec
forge fmt
eladiosch Jun 9, 2025
7883612
Added signature check to downsize, and changed burn. Restored old oracle
eladiosch Jun 10, 2025
141628f
forge fmt
eladiosch Jun 10, 2025
40b352c
Added numBatches to ValidatorKeyRegistered event
eladiosch Jun 11, 2025
c6cbc18
forge fmt
eladiosch Jun 11, 2025
7b29240
resolve conflicts + minor changes
bxmmm1 Jun 12, 2025
efb9440
fix validator exits
bxmmm1 Jun 12, 2025
9c42d19
update the test
bxmmm1 Jun 13, 2025
5a9bd38
codespell
bxmmm1 Jun 13, 2025
e2158ec
Merge pull request #116 from PufferFinance/feature/remove-vt
eladiosch Jun 20, 2025
1fca25b
Improved IProtocol natspec and naming. Slight optimization in protocol
eladiosch Jun 23, 2025
8282259
Added comments and small refactor
eladiosch Jun 24, 2025
95811ed
forge fmt
eladiosch Jun 24, 2025
e8cc1a9
Removed duplicated code
eladiosch Jun 24, 2025
c1cdf1e
Fixed wrong comment
eladiosch Jun 24, 2025
991d558
Added numBatches param to relevant events
eladiosch Jun 24, 2025
1f36dca
FIxed param bug in _getVTBurnAmount, added checks to _useVTOrValidati…
eladiosch Jun 26, 2025
079872a
Removed min amount from _getVTBurnAmount
eladiosch Jun 27, 2025
09690ce
Reworked signatures (tests not adapted)
eladiosch Jul 1, 2025
9b62be5
Adapted one script and test handler
eladiosch Jul 1, 2025
6b187f7
Adapted tests to new func sigs
eladiosch Jul 2, 2025
899b73e
Refactors to fix stack too deep
eladiosch Jul 2, 2025
f392b1b
fmt
eladiosch Jul 2, 2025
a71569f
Added min and max for depositVT. Added numBatches when needed
eladiosch Jul 2, 2025
86afa4b
Removed unused function
eladiosch Jul 3, 2025
202c7f1
Created PufferLogic contract and adapted existing ones (WIP)
eladiosch Jul 7, 2025
0b4a2b8
Adapted previous tests and improved signatures
eladiosch Jul 7, 2025
37fff25
Changed ProtocolLogic structure. Moved more logic to ext contract (WIP)
eladiosch Jul 7, 2025
27dea10
Fixed and simplify delegatecalls
eladiosch Jul 8, 2025
50536f7
Refactor delegatecalls and small fixes
eladiosch Jul 8, 2025
7b53076
Refactor PufferConstants to PufferProtocolBase and moved more logic t…
eladiosch Jul 8, 2025
ec3e5fe
forge fmt
eladiosch Jul 8, 2025
9d2251f
Removed flow to deposit VT with Permit
eladiosch Jul 10, 2025
c104f39
Added tests to increase coverage
eladiosch Jul 10, 2025
48c5b53
forge fmt
eladiosch Jul 10, 2025
4e44801
Refactored interfaces and adapted tests (protocol WIP)
eladiosch Jul 14, 2025
eab8cfc
Changed approach of the delegatecall to logic contract
eladiosch Jul 14, 2025
495ac9d
Removed selector constants
eladiosch Jul 15, 2025
bf0c713
Added some natspec to the fallback function
eladiosch Jul 15, 2025
a19d9a0
Moved logic from GuardianModule to Protocol to avoid re-deploying con…
eladiosch Jul 15, 2025
5501856
forge fmt
eladiosch Jul 15, 2025
f3dafab
Added basic checks to withdrawValidationTime and added missing natspec
eladiosch Jul 15, 2025
8d546b1
forge fmt
eladiosch Jul 15, 2025
522f503
Update mainnet-contracts/src/PufferProtocol.sol
eladiosch Jul 16, 2025
e7fb64e
Update mainnet-contracts/src/PufferProtocol.sol
eladiosch Jul 16, 2025
76a3233
Update mainnet-contracts/src/PufferProtocol.sol
eladiosch Jul 16, 2025
c90f5da
Update mainnet-contracts/src/PufferProtocol.sol
eladiosch Jul 16, 2025
e181e10
Update mainnet-contracts/src/PufferProtocolLogic.sol
eladiosch Jul 16, 2025
fad967d
Update mainnet-contracts/src/PufferProtocol.sol
eladiosch Jul 16, 2025
b982b2e
Using modifier (with require) to check deadlines
eladiosch Jul 16, 2025
3c16eb3
Changed reverts to require and refactored to avoid stack too deep
eladiosch Jul 16, 2025
3599a63
Added restricted for the Logic contract and improved natspec
eladiosch Jul 16, 2025
59f2899
Merge pull request #119 from PufferFinance/external-protocol-logic
eladiosch Jul 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ contract DeployPufferModuleImplementation is DeployerHelper {
vm.startBroadcast();

PufferModule newImpl = new PufferModule({
protocol: PufferProtocol(_getPufferProtocol()),
protocol: PufferProtocol(payable(_getPufferProtocol())),
eigenPodManager: _getEigenPodManager(),
delegationManager: IDelegationManager(_getDelegationManager()),
moduleManager: PufferModuleManager(payable(_getPufferModuleManager())),
Expand All @@ -51,7 +51,7 @@ contract DeployPufferModuleImplementation is DeployerHelper {
vm.startPrank(_getPaymaster());

PufferModule newImpl = new PufferModule({
protocol: PufferProtocol(_getPufferProtocol()),
protocol: PufferProtocol(payable(_getPufferProtocol())),
eigenPodManager: _getEigenPodManager(),
delegationManager: IDelegationManager(_getDelegationManager()),
moduleManager: PufferModuleManager(payable(_getPufferModuleManager())),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ contract GenerateBLSKeysAndRegisterValidators is Script {
if (block.chainid == 17000) {
// Holesky
protocolAddress = 0xE00c79408B9De5BaD2FDEbB1688997a68eC988CD;
pufferProtocol = PufferProtocol(protocolAddress);
pufferProtocol = PufferProtocol(payable(protocolAddress));
forkVersion = "0x01017000";
} else if (block.chainid == 1) {
// Mainnet
protocolAddress = 0xf7b6B32492c2e13799D921E84202450131bd238B;
pufferProtocol = PufferProtocol(protocolAddress);
pufferProtocol = PufferProtocol(payable(protocolAddress));
forkVersion = "0x00000000";
}

Expand Down Expand Up @@ -102,9 +102,7 @@ contract GenerateBLSKeysAndRegisterValidators is Script {
blsPubKey: stdJson.readBytes(registrationJson, ".bls_pub_key"),
signature: stdJson.readBytes(registrationJson, ".signature"),
depositDataRoot: stdJson.readBytes32(registrationJson, ".deposit_data_root"),
blsEncryptedPrivKeyShares: blsEncryptedPrivKeyShares,
blsPubKeySet: stdJson.readBytes(registrationJson, ".bls_pub_key_set"),
raveEvidence: ""
numBatches: 1
});

Permit memory pufETHPermit = _signPermit({
Expand Down
1 change: 1 addition & 0 deletions mainnet-contracts/script/Roles.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ uint64 constant ROLE_ID_OPERATIONS_PAYMASTER = 23;
uint64 constant ROLE_ID_OPERATIONS_COORDINATOR = 24;
uint64 constant ROLE_ID_WITHDRAWAL_FINALIZER = 25;
uint64 constant ROLE_ID_REVENUE_DEPOSITOR = 26;
uint64 constant ROLE_ID_VALIDATOR_EXITOR = 27;

// Role assigned to validator ticket price setter
uint64 constant ROLE_ID_VT_PRICER = 25;
Expand Down
22 changes: 20 additions & 2 deletions mainnet-contracts/script/SetupAccess.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ import {
ROLE_ID_PUFFER_PROTOCOL,
ROLE_ID_DAO,
ROLE_ID_OPERATIONS_COORDINATOR,
ROLE_ID_VT_PRICER
ROLE_ID_VT_PRICER,
ROLE_ID_VALIDATOR_EXITOR
} from "../script/Roles.sol";

contract SetupAccess is BaseScript {
Expand Down Expand Up @@ -153,7 +154,7 @@ contract SetupAccess is BaseScript {
}

function _setupPufferModuleManagerAccess() internal view returns (bytes[] memory) {
bytes[] memory calldatas = new bytes[](2);
bytes[] memory calldatas = new bytes[](4);

// Dao selectors
bytes4[] memory selectors = new bytes4[](7);
Expand Down Expand Up @@ -181,6 +182,23 @@ contract SetupAccess is BaseScript {
ROLE_ID_OPERATIONS_PAYMASTER
);

// ValidatorExitor selectors
bytes4[] memory requestWithdrawalSelector = new bytes4[](1);
requestWithdrawalSelector[0] = PufferModuleManager.requestWithdrawal.selector;

calldatas[2] = abi.encodeWithSelector(
AccessManager.setTargetFunctionRole.selector,
pufferDeployment.moduleManager,
requestWithdrawalSelector,
ROLE_ID_VALIDATOR_EXITOR
);

calldatas[3] = abi.encodeWithSelector(
AccessManager.setTargetFunctionRole.selector,
pufferDeployment.moduleManager,
requestWithdrawalSelector,
ROLE_ID_PUFFER_PROTOCOL
);
return calldatas;
}

Expand Down
14 changes: 14 additions & 0 deletions mainnet-contracts/src/GuardianModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { StoppedValidatorInfo } from "./struct/StoppedValidatorInfo.sol";
* @title Guardian module
* @author Puffer Finance
* @dev This contract is responsible for storing enclave keys and validation of guardian's EOA/Enclave signatures
* * @dev Some of these functions are no longer used since enclaves have been deprecated
* @custom:security-contact security@puffer.fi
*/
contract GuardianModule is AccessManaged, IGuardianModule {
Expand All @@ -38,6 +39,7 @@ contract GuardianModule is AccessManaged, IGuardianModule {

/**
* @notice Enclave Verifier smart contract
* @dev DEPRECATED
*/
IEnclaveVerifier public immutable ENCLAVE_VERIFIER;

Expand All @@ -53,11 +55,13 @@ contract GuardianModule is AccessManaged, IGuardianModule {

/**
* @dev MRSIGNER value for SGX
* @dev DEPRECATED
*/
bytes32 internal _mrsigner;

/**
* @dev MRENCLAVE value for SGX
* @dev DEPRECATED
*/
bytes32 internal _mrenclave;

Expand All @@ -77,6 +81,7 @@ contract GuardianModule is AccessManaged, IGuardianModule {

/**
* @dev Mapping of a Guardian's EOA to enclave data
* @dev DEPRECATED
*/
mapping(address guardian => GuardianData data) internal _guardianEnclaves;

Expand Down Expand Up @@ -139,6 +144,7 @@ contract GuardianModule is AccessManaged, IGuardianModule {

/**
* @inheritdoc IGuardianModule
* @dev DEPRECATED
*/
function validateProvisionNode(
uint256 pufferModuleIndex,
Expand Down Expand Up @@ -220,6 +226,7 @@ contract GuardianModule is AccessManaged, IGuardianModule {

/**
* @inheritdoc IGuardianModule
* @dev DEPRECATED
*/
function validateGuardiansEnclaveSignatures(bytes[] calldata enclaveSignatures, bytes32 signedMessageHash)
public
Expand All @@ -240,6 +247,7 @@ contract GuardianModule is AccessManaged, IGuardianModule {
/**
* @inheritdoc IGuardianModule
* @dev Restricted to the DAO
* @dev DEPRECATED
*/
function setGuardianEnclaveMeasurements(bytes32 newMrEnclave, bytes32 newMrSigner) external restricted {
emit MrEnclaveChanged(_mrenclave, newMrEnclave);
Expand Down Expand Up @@ -298,6 +306,7 @@ contract GuardianModule is AccessManaged, IGuardianModule {

/**
* @inheritdoc IGuardianModule
* @dev DEPRECATED
*/
function rotateGuardianKey(uint256 blockNumber, bytes calldata pubKey, RaveEvidence calldata evidence) external {
address guardian = msg.sender;
Expand Down Expand Up @@ -341,13 +350,15 @@ contract GuardianModule is AccessManaged, IGuardianModule {

/**
* @inheritdoc IGuardianModule
* @dev DEPRECATED
*/
function getGuardiansEnclaveAddress(address guardian) external view returns (address) {
return _guardianEnclaves[guardian].enclaveAddress;
}

/**
* @inheritdoc IGuardianModule
* @dev DEPRECATED
*/
function getGuardiansEnclaveAddresses() public view returns (address[] memory) {
uint256 guardiansLength = _guardians.length();
Expand All @@ -367,6 +378,7 @@ contract GuardianModule is AccessManaged, IGuardianModule {

/**
* @inheritdoc IGuardianModule
* @dev DEPRECATED
*/
function getGuardiansEnclavePubkeys() external view returns (bytes[] memory) {
uint256 guardiansLength = _guardians.length();
Expand All @@ -381,13 +393,15 @@ contract GuardianModule is AccessManaged, IGuardianModule {

/**
* @inheritdoc IGuardianModule
* @dev DEPRECATED
*/
function getMrenclave() external view returns (bytes32) {
return _mrenclave;
}

/**
* @inheritdoc IGuardianModule
* @dev DEPRECATED
*/
function getMrsigner() external view returns (bytes32) {
return _mrsigner;
Expand Down
66 changes: 52 additions & 14 deletions mainnet-contracts/src/PufferModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { IEigenPodManager } from "../src/interface/Eigenlayer-Slashing/IEigenPod
import { ISignatureUtils } from "../src/interface/Eigenlayer-Slashing/ISignatureUtils.sol";
import { IStrategy } from "../src/interface/Eigenlayer-Slashing/IStrategy.sol";
import { IPufferProtocol } from "./interface/IPufferProtocol.sol";
import { IEigenPod } from "../src/interface/Eigenlayer-Slashing/IEigenPod.sol";
import { IEigenPod, IEigenPodTypes } from "../src/interface/Eigenlayer-Slashing/IEigenPod.sol";
import { PufferModuleManager } from "./PufferModuleManager.sol";
import { Unauthorized } from "./Errors.sol";
import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
Expand Down Expand Up @@ -96,18 +96,6 @@ contract PufferModule is Initializable, AccessManagedUpgradeable {

receive() external payable { }

/**
* @notice Starts the validator
*/
function callStake(bytes calldata pubKey, bytes calldata signature, bytes32 depositDataRoot)
external
payable
onlyPufferProtocol
{
// EigenPod is deployed in this call
EIGEN_POD_MANAGER.stake{ value: 32 ether }(pubKey, signature, depositDataRoot);
}

/**
* @notice Sets the proof submitter on the EigenPod
*/
Expand Down Expand Up @@ -195,6 +183,56 @@ contract PufferModule is Initializable, AccessManagedUpgradeable {
return EIGEN_DELEGATION_MANAGER.undelegate(address(this));
}

/**
* @notice Requests a consolidation for the given validators. This consolidation consists on merging one validator into another one
* @param srcPubkeys The pubkeys of the validators to consolidate from
* @param targetPubkeys The pubkeys of the validators to consolidate to
* @dev Only callable by the PufferProtocol
* @dev According to EIP-7251 there is a fee for each validator consolidation request (See https://eips.ethereum.org/EIPS/eip-7251#fee-calculation)
* The fee is paid in the msg.value of this function. Since the fee is not fixed and might change, the excess amount is refunded
* to the caller from the EigenPod
*/
function requestConsolidation(bytes[] calldata srcPubkeys, bytes[] calldata targetPubkeys)
external
payable
virtual

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

virtual means this function can be overridden by other contracts, is this intended?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really necessary IMO, but most of the functions in this contracts are virtual, so I followed suit

onlyPufferProtocol
{
ModuleStorage storage $ = _getPufferModuleStorage();

IEigenPod.ConsolidationRequest[] memory requests = new IEigenPodTypes.ConsolidationRequest[](srcPubkeys.length);
for (uint256 i = 0; i < srcPubkeys.length; i++) {
requests[i] =
IEigenPodTypes.ConsolidationRequest({ srcPubkey: srcPubkeys[i], targetPubkey: targetPubkeys[i] });
}
$.eigenPod.requestConsolidation{ value: msg.value }(requests);
}

/**
* @notice Requests a withdrawal for the given validators. This withdrawal can be total or partial.
* If the amount is 0, the withdrawal is total and the validator will be fully exited.
* If it is a partial withdrawal, the validator should not be below 32 ETH or the request will be ignored.
* @param pubkeys The pubkeys of the validators to withdraw
* @param gweiAmounts The amounts of the validators to withdraw, in Gwei
* @dev Only callable by the PufferModuleManager
* @dev According to EIP-7002 there is a fee for each validator withdrawal request (See https://eips.ethereum.org/assets/eip-7002/fee_analysis)
* The fee is paid in the msg.value of this function. Since the fee is not fixed and might change, the excess amount will be kept in the PufferModule
*/
function requestWithdrawal(bytes[] calldata pubkeys, uint64[] calldata gweiAmounts)
external
payable
virtual
onlyPufferModuleManager
{
ModuleStorage storage $ = _getPufferModuleStorage();

IEigenPodTypes.WithdrawalRequest[] memory requests = new IEigenPodTypes.WithdrawalRequest[](pubkeys.length);
for (uint256 i = 0; i < pubkeys.length; i++) {
requests[i] = IEigenPodTypes.WithdrawalRequest({ pubkey: pubkeys[i], amountGwei: gweiAmounts[i] });
}
$.eigenPod.requestWithdrawal{ value: msg.value }(requests);
}

/**
* @notice Sets the rewards claimer to `claimer` for the PufferModule
*/
Expand All @@ -208,7 +246,7 @@ contract PufferModule is Initializable, AccessManagedUpgradeable {
function getWithdrawalCredentials() public view returns (bytes memory) {
// Withdrawal credentials for EigenLayer modules are EigenPods
ModuleStorage storage $ = _getPufferModuleStorage();
return abi.encodePacked(bytes1(uint8(1)), bytes11(0), $.eigenPod);
return abi.encodePacked(bytes1(uint8(2)), bytes11(0), $.eigenPod);
}

/**
Expand Down
52 changes: 52 additions & 0 deletions mainnet-contracts/src/PufferModuleManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { PufferVaultV5 } from "./PufferVaultV5.sol";
import { RestakingOperator } from "./RestakingOperator.sol";
import { IPufferModuleManager } from "./interface/IPufferModuleManager.sol";
import { BeaconProxy } from "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol";
import { Address } from "@openzeppelin/contracts/utils/Address.sol";
import { Create2 } from "@openzeppelin/contracts/utils/Create2.sol";
import { AccessManagedUpgradeable } from
"@openzeppelin/contracts-upgradeable/access/manager/AccessManagedUpgradeable.sol";
Expand All @@ -26,6 +27,9 @@ import { PufferModule } from "./PufferModule.sol";
* @custom:security-contact security@puffer.fi
*/
contract PufferModuleManager is IPufferModuleManager, AccessManagedUpgradeable, UUPSUpgradeable {
using Address for address;
using Address for address payable;

address public immutable PUFFER_MODULE_BEACON;
address public immutable RESTAKING_OPERATOR_BEACON;
address public immutable PUFFER_PROTOCOL;
Expand Down Expand Up @@ -239,6 +243,54 @@ contract PufferModuleManager is IPufferModuleManager, AccessManagedUpgradeable,
emit PufferModuleUndelegated(moduleName);
}

/**
* @notice Upgrades the given validators to consolidating (0x02)
* @param moduleName The name of the module
* @param pubkeys The pubkeys of the validators to upgrade
* @dev The function does not check that the pubkeys belong to the module
* @dev Restricted to the DAO
* @dev According to EIP-7251 there is a fee for each validator consolidation request (See https://eips.ethereum.org/EIPS/eip-7251#fee-calculation)
* The fee is paid in the msg.value of this function. Since the fee is not fixed and might change, the excess amount is refunded
* to the caller from the EigenPod
*/
function upgradeToConsolidating(bytes32 moduleName, bytes[] calldata pubkeys) external payable virtual restricted {
address moduleAddress = IPufferProtocol(PUFFER_PROTOCOL).getModuleAddress(moduleName);

PufferModule(payable(moduleAddress)).requestConsolidation{ value: msg.value }(pubkeys, pubkeys);

emit PufferModuleUpgradedToConsolidating(moduleName, pubkeys);
}

/**
* @notice Requests a withdrawal for the given validators. This withdrawal can be total or partial.
* If the amount is 0, the withdrawal is total and the validator will be fully exited.
* If it is a partial withdrawal, the validator should not be below 32 ETH or the request will be ignored.
* @param moduleName The name of the module
* @param pubkeys The pubkeys of the validators to withdraw
* @param gweiAmounts The amounts of the validators to withdraw, in Gwei
* @dev Restricted to the VALIDATOR_EXITOR role and the PufferProtocol
* @dev According to EIP-7002 there is a fee for each validator withdrawal request (See https://eips.ethereum.org/assets/eip-7002/fee_analysis)
* The fee is paid in the msg.value of this function. Since the fee is not fixed and might change, the excess amount will be kept in the PufferModule
*/
function requestWithdrawal(bytes32 moduleName, bytes[] calldata pubkeys, uint64[] calldata gweiAmounts)
external
payable
virtual
restricted
{
if (pubkeys.length == 0) {
revert InputArrayLengthZero();
}
if (pubkeys.length != gweiAmounts.length) {
revert InputArrayLengthMismatch();
}
Comment on lines +282 to +286
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we are doing the validations here, and we have a very similar validations in PufferProtocol, should we remove the validations from PufferProtocol? The TX reverts either way

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed with explanation from other comment

address moduleAddress = IPufferProtocol(PUFFER_PROTOCOL).getModuleAddress(moduleName);

PufferModule(payable(moduleAddress)).requestWithdrawal{ value: msg.value }(pubkeys, gweiAmounts);

emit WithdrawalRequested(moduleName, pubkeys, gweiAmounts);
}

/**
* @notice Calls the callRegisterOperatorToAVS function on the target restaking operator
* @param restakingOperator is the address of the restaking operator
Expand Down
Loading