@@ -50,6 +50,24 @@ contract Dashboard is NodeOperatorFee {
50
50
bytes32 public constant FUND_ON_RECEIVE_FLAG_SLOT =
51
51
0x7408b7b034fda7051615c19182918ecb91d753231cffd86f81a45d996d63e038 ;
52
52
53
+ /**
54
+ * @notice The PDG policy modes.
55
+ * "STRICT": deposits require the full PDG process.
56
+ * "ALLOW_PROVE": allows the node operator to prove unknown validators to PDG.
57
+ * "ALLOW_DEPOSIT_AND_PROVE": allows the node operator to perform unguaranteed deposits
58
+ * (bypassing the predeposit requirement) and proving unknown validators.
59
+ */
60
+ enum PDGPolicy {
61
+ STRICT,
62
+ ALLOW_PROVE,
63
+ ALLOW_DEPOSIT_AND_PROVE
64
+ }
65
+
66
+ /**
67
+ * @notice Current active PDG policy set by `DEFAULT_ADMIN_ROLE`.
68
+ */
69
+ PDGPolicy public pdgPolicy = PDGPolicy.STRICT;
70
+
53
71
/**
54
72
* @notice Constructor sets the stETH, and WSTETH token addresses,
55
73
* and passes the address of the vault hub up the inheritance chain.
@@ -110,55 +128,13 @@ contract Dashboard is NodeOperatorFee {
110
128
return VAULT_HUB.vaultConnection (address (_stakingVault ()));
111
129
}
112
130
113
- /**
114
- * @notice Returns the stETH share limit of the vault
115
- */
116
- function shareLimit () external view returns (uint256 ) {
117
- return vaultConnection ().shareLimit;
118
- }
119
-
120
131
/**
121
132
* @notice Returns the number of stETH shares minted
122
133
*/
123
134
function liabilityShares () public view returns (uint256 ) {
124
135
return VAULT_HUB.liabilityShares (address (_stakingVault ()));
125
136
}
126
137
127
- /**
128
- * @notice Returns the reserve ratio of the vault in basis points
129
- */
130
- function reserveRatioBP () public view returns (uint16 ) {
131
- return vaultConnection ().reserveRatioBP;
132
- }
133
-
134
- /**
135
- * @notice Returns the rebalance threshold of the vault in basis points.
136
- */
137
- function forcedRebalanceThresholdBP () external view returns (uint16 ) {
138
- return vaultConnection ().forcedRebalanceThresholdBP;
139
- }
140
-
141
- /**
142
- * @notice Returns the infra fee basis points.
143
- */
144
- function infraFeeBP () external view returns (uint16 ) {
145
- return vaultConnection ().infraFeeBP;
146
- }
147
-
148
- /**
149
- * @notice Returns the liquidity fee basis points.
150
- */
151
- function liquidityFeeBP () external view returns (uint16 ) {
152
- return vaultConnection ().liquidityFeeBP;
153
- }
154
-
155
- /**
156
- * @notice Returns the reservation fee basis points.
157
- */
158
- function reservationFeeBP () external view returns (uint16 ) {
159
- return vaultConnection ().reservationFeeBP;
160
- }
161
-
162
138
/**
163
139
* @notice Returns the total value of the vault in ether.
164
140
*/
@@ -418,18 +394,33 @@ contract Dashboard is NodeOperatorFee {
418
394
_rebalanceVault (_getSharesByPooledEth (_ether));
419
395
}
420
396
397
+ /**
398
+ * @notice Changes the PDG policy
399
+ * @param _pdgPolicy new PDG policy
400
+ */
401
+ function setPDGPolicy (PDGPolicy _pdgPolicy ) external onlyRoleMemberOrAdmin (DEFAULT_ADMIN_ROLE) {
402
+ if (_pdgPolicy == pdgPolicy) revert PDGPolicyAlreadyActive ();
403
+
404
+ pdgPolicy = _pdgPolicy;
405
+
406
+ emit PDGPolicyEnacted (_pdgPolicy);
407
+ }
408
+
421
409
/**
422
410
* @notice Withdraws ether from vault and deposits directly to provided validators bypassing the default PDG process,
423
411
* allowing validators to be proven post-factum via `proveUnknownValidatorsToPDG`
424
412
* clearing them for future deposits via `PDG.depositToBeaconChain`
425
413
* @param _deposits array of IStakingVault.Deposit structs containing deposit data
426
414
* @return totalAmount total amount of ether deposited to beacon chain
427
- * @dev requires the caller to have the `UNGUARANTEED_BEACON_CHAIN_DEPOSIT_ROLE`
415
+ * @dev requires the PDG policy set to `ALLOW_DEPOSIT_AND_PROVE`
416
+ * @dev requires the caller to have the `NODE_OPERATOR_UNGUARANTEED_DEPOSIT_ROLE`
428
417
* @dev can be used as PDG shortcut if the node operator is trusted to not frontrun provided deposits
429
418
*/
430
419
function unguaranteedDepositToBeaconChain (
431
420
IStakingVault.Deposit[] calldata _deposits
432
421
) external returns (uint256 totalAmount ) {
422
+ if (pdgPolicy != PDGPolicy.ALLOW_DEPOSIT_AND_PROVE) revert ForbiddenByPDGPolicy ();
423
+
433
424
IStakingVault stakingVault_ = _stakingVault ();
434
425
IDepositContract depositContract = stakingVault_.DEPOSIT_CONTRACT ();
435
426
@@ -468,9 +459,12 @@ contract Dashboard is NodeOperatorFee {
468
459
/**
469
460
* @notice Proves validators with correct vault WC if they are unknown to PDG
470
461
* @param _witnesses array of IPredepositGuarantee.ValidatorWitness structs containing proof data for validators
471
- * @dev requires the caller to have the `PDG_PROVE_VALIDATOR_ROLE`
462
+ * @dev requires the PDG policy set to `ALLOW_PROVE` or `ALLOW_DEPOSIT_AND_PROVE`
463
+ * @dev requires the caller to have the `NODE_OPERATOR_PROVE_UNKNOWN_VALIDATOR_ROLE`
472
464
*/
473
465
function proveUnknownValidatorsToPDG (IPredepositGuarantee.ValidatorWitness[] calldata _witnesses ) external {
466
+ if (pdgPolicy == PDGPolicy.STRICT) revert ForbiddenByPDGPolicy ();
467
+
474
468
_proveUnknownValidatorsToPDG (_witnesses);
475
469
}
476
470
@@ -674,6 +668,28 @@ contract Dashboard is NodeOperatorFee {
674
668
}
675
669
}
676
670
671
+ /**
672
+ * @dev Withdraws ether from vault to this contract for unguaranteed deposit to validators
673
+ * Requires the caller to have the `NODE_OPERATOR_UNGUARANTEED_DEPOSIT_ROLE`.
674
+ */
675
+ function _withdrawForUnguaranteedDepositToBeaconChain (
676
+ uint256 _ether
677
+ ) internal onlyRoleMemberOrAdmin (NODE_OPERATOR_UNGUARANTEED_DEPOSIT_ROLE) {
678
+ VAULT_HUB.withdraw (address (_stakingVault ()), address (this ), _ether);
679
+ }
680
+
681
+ /**
682
+ * @dev Proves validators unknown to PDG that have correct vault WC
683
+ * Requires the caller to have the `NODE_OPERATOR_PROVE_UNKNOWN_VALIDATOR_ROLE`.
684
+ */
685
+ function _proveUnknownValidatorsToPDG (
686
+ IPredepositGuarantee.ValidatorWitness[] calldata _witnesses
687
+ ) internal onlyRoleMemberOrAdmin (NODE_OPERATOR_PROVE_UNKNOWN_VALIDATOR_ROLE) {
688
+ for (uint256 i = 0 ; i < _witnesses.length ; i++ ) {
689
+ VAULT_HUB.proveUnknownValidatorToPDG (address (_stakingVault ()), _witnesses[i]);
690
+ }
691
+ }
692
+
677
693
// ==================== Events ====================
678
694
679
695
/**
@@ -684,6 +700,11 @@ contract Dashboard is NodeOperatorFee {
684
700
*/
685
701
event UnguaranteedDeposits (address indexed stakingVault , uint256 deposits , uint256 totalAmount );
686
702
703
+ /**
704
+ * @notice Emitted when the PDG policy is updated.
705
+ */
706
+ event PDGPolicyEnacted (PDGPolicy pdgPolicy );
707
+
687
708
// ==================== Errors ====================
688
709
689
710
/**
@@ -712,4 +733,15 @@ contract Dashboard is NodeOperatorFee {
712
733
* @notice Error when attempting to abandon the Dashboard contract itself.
713
734
*/
714
735
error DashboardNotAllowed ();
736
+
737
+ /**
738
+ * @notice Error when attempting to set the same PDG policy that is already active.
739
+ */
740
+ error PDGPolicyAlreadyActive ();
741
+
742
+ /**
743
+ * @notice Error when attempting to perform an operation that is not allowed
744
+ * by the current active PDG policy.
745
+ */
746
+ error ForbiddenByPDGPolicy ();
715
747
}
0 commit comments