@@ -23,6 +23,7 @@ import "../../interface/token/RocketTokenRETHInterface.sol";
23
23
import "../../types/MinipoolDeposit.sol " ;
24
24
import "../../types/MinipoolStatus.sol " ;
25
25
import "../../interface/node/RocketNodeDepositInterface.sol " ;
26
+ import "../../interface/minipool/RocketMinipoolBondReducerInterface.sol " ;
26
27
27
28
/// @notice Provides the logic for each individual minipool in the Rocket Pool network
28
29
/// @dev Minipools exclusively DELEGATECALL into this contract it is never called directly
@@ -41,9 +42,6 @@ contract RocketMinipoolDelegate is RocketMinipoolStorageLayout, RocketMinipoolIn
41
42
// Events
42
43
event StatusUpdated (uint8 indexed status , uint256 time );
43
44
event ScrubVoted (address indexed member , uint256 time );
44
- event BeginBondReduction (uint256 time );
45
- event CancelReductionVoted (address indexed member , uint256 time );
46
- event ReductionCancelled (uint256 time );
47
45
event BondReduced (uint256 previousBondAmount , uint256 newBondAmount , uint256 time );
48
46
event MinipoolScrubbed (uint256 time );
49
47
event MinipoolPrestaked (bytes validatorPubkey , bytes validatorSignature , bytes32 depositDataRoot , uint256 amount , bytes withdrawalCredentials , uint256 time );
@@ -270,8 +268,13 @@ contract RocketMinipoolDelegate is RocketMinipoolStorageLayout, RocketMinipoolIn
270
268
/// @dev Sets the bond value and vacancy flag on this minipool
271
269
/// @param _bondAmount The bond amount selected by the node operator
272
270
function prepareVacancy (uint256 _bondAmount ) override external onlyLatestContract ("rocketMinipoolManager " , msg .sender ) onlyInitialised {
271
+ // Get contracts
272
+ RocketDAOProtocolSettingsMinipoolInterface rocketDAOProtocolSettingsMinipool = RocketDAOProtocolSettingsMinipoolInterface (getContractAddress ("rocketDAOProtocolSettingsMinipool " ));
273
273
// Store bond amount
274
274
nodeDepositBalance = _bondAmount;
275
+ // Calculate user amount from launch amount
276
+ uint256 launchAmount = rocketDAOProtocolSettingsMinipool.getLaunchBalance ();
277
+ userDepositBalance = uint256 (32 ether).sub (nodeDepositBalance);
275
278
// Flag as vacant
276
279
vacant = true ;
277
280
// Set status to preLaunch
@@ -284,7 +287,6 @@ contract RocketMinipoolDelegate is RocketMinipoolStorageLayout, RocketMinipoolIn
284
287
require (status == MinipoolStatus.Prelaunch, "The minipool can only promote while in prelaunch " );
285
288
require (vacant, "Cannot promote a non-vacant minipool " );
286
289
// Get contracts
287
- RocketDAOProtocolSettingsMinipoolInterface rocketDAOProtocolSettingsMinipool = RocketDAOProtocolSettingsMinipoolInterface (getContractAddress ("rocketDAOProtocolSettingsMinipool " ));
288
290
RocketDAONodeTrustedSettingsMinipoolInterface rocketDAONodeTrustedSettingsMinipool = RocketDAONodeTrustedSettingsMinipoolInterface (getContractAddress ("rocketDAONodeTrustedSettingsMinipool " ));
289
291
// Clear vacant flag
290
292
vacant = false ;
@@ -293,9 +295,6 @@ contract RocketMinipoolDelegate is RocketMinipoolStorageLayout, RocketMinipoolIn
293
295
require (block .timestamp > statusTime + scrubPeriod, "Not enough time has passed to promote " );
294
296
// Progress to staking
295
297
setStatus (MinipoolStatus.Staking);
296
- // Calculate user amount from launch amount
297
- uint256 launchAmount = rocketDAOProtocolSettingsMinipool.getLaunchBalance ();
298
- userDepositBalance = uint256 (32 ether).sub (nodeDepositBalance);
299
298
// Increment node's number of staking minipools
300
299
RocketMinipoolManagerInterface rocketMinipoolManager = RocketMinipoolManagerInterface (getContractAddress ("rocketMinipoolManager " ));
301
300
rocketMinipoolManager.incrementNodeStakingMinipoolCount (nodeAddress);
@@ -528,10 +527,7 @@ contract RocketMinipoolDelegate is RocketMinipoolStorageLayout, RocketMinipoolIn
528
527
// Load contracts
529
528
RocketDAOProtocolSettingsMinipoolInterface rocketDAOProtocolSettingsMinipool = RocketDAOProtocolSettingsMinipoolInterface (getContractAddress ("rocketDAOProtocolSettingsMinipool " ));
530
529
// Check if being dissolved by minipool owner or minipool is timed out
531
- require (
532
- (status == MinipoolStatus.Prelaunch && block .timestamp .sub (statusTime) >= rocketDAOProtocolSettingsMinipool.getLaunchTimeout ()),
533
- "The minipool can only be dissolved once it has timed out "
534
- );
530
+ require (block .timestamp .sub (statusTime) >= rocketDAOProtocolSettingsMinipool.getLaunchTimeout (), "The minipool can only be dissolved once it has timed out " );
535
531
// Perform the dissolution
536
532
_dissolve ();
537
533
}
@@ -547,6 +543,8 @@ contract RocketMinipoolDelegate is RocketMinipoolStorageLayout, RocketMinipoolIn
547
543
require (rocketMinipoolManager.getMinipoolExists (address (this )), "Minipool already closed " );
548
544
rocketMinipoolManager.destroyMinipool ();
549
545
// Clear state
546
+ nodeDepositBalance = 0 ;
547
+ nodeRefundBalance = 0 ;
550
548
userDepositBalance = 0 ;
551
549
userDepositBalanceLegacy = 0 ;
552
550
userDepositAssignedTime = 0 ;
@@ -594,70 +592,23 @@ contract RocketMinipoolDelegate is RocketMinipoolStorageLayout, RocketMinipoolIn
594
592
}
595
593
}
596
594
597
- /// @notice Flags this minipool as wanting to reduce collateral, owner can then call `reduceBondAmount` once waiting
598
- /// period has elapsed
599
- function beginReduceBondAmount () override external onlyMinipoolOwner (msg .sender ) onlyInitialised {
600
- require (! reductionCancelled, "This minipool is allowed to reduce bond " );
601
- require (status == MinipoolStatus.Staking, "Minipool must be staking " );
602
- reduceBondTime = block .timestamp ;
603
- emit BeginBondReduction (block .timestamp );
604
- }
605
-
606
- /// @notice Returns whether owner can reduce bond amount given the waiting period constraint
607
- function canReduceBondAmount () override public view returns (bool ) {
608
- RocketDAONodeTrustedSettingsMinipoolInterface rocketDAONodeTrustedSettingsMinipool = RocketDAONodeTrustedSettingsMinipoolInterface (getContractAddress ("rocketDAONodeTrustedSettingsMinipool " ));
609
- return rocketDAONodeTrustedSettingsMinipool.isWithinBondReductionWindow (block .timestamp .sub (reduceBondTime));
610
- }
611
-
612
- /// @notice Can be called by trusted nodes to cancel a reduction in bond if the validator has too low of a balance
613
- function voteCancelReduction () override external onlyInitialised {
614
- require (! memberCancelVotes[msg .sender ], "Member has already voted to cancel " );
615
- // Must be a trusted member
616
- RocketDAONodeTrustedInterface rocketDAONode = RocketDAONodeTrustedInterface (getContractAddress ("rocketDAONodeTrusted " ));
617
- require (rocketDAONode.getMemberIsValid (msg .sender ), "Not a trusted member " );
618
- memberCancelVotes[msg .sender ] = true ;
619
- // Emit event
620
- emit CancelReductionVoted (msg .sender , block .timestamp );
621
- // Check if required quorum has voted
622
- RocketDAONodeTrustedSettingsMinipoolInterface rocketDAONodeTrustedSettingsMinipool = RocketDAONodeTrustedSettingsMinipoolInterface (getContractAddress ("rocketDAONodeTrustedSettingsMinipool " ));
623
- uint256 quorum = rocketDAONode.getMemberCount ().mul (rocketDAONodeTrustedSettingsMinipool.getCancelBondReductionQuorum ()).div (calcBase);
624
- if (totalCancelVotes.add (1 ) > quorum) {
625
- // Emit event
626
- emit ReductionCancelled (block .timestamp );
627
- reductionCancelled = true ;
628
- reduceBondTime = 0 ;
629
- } else {
630
- // Increment total
631
- totalCancelVotes = totalCancelVotes.add (1 );
632
- }
633
- }
634
-
635
595
/// @notice Reduces the ETH bond amount and credits the owner the difference
636
596
/// @param _amount The amount to reduce the bond to (e.g. 8 ether)
637
- function reduceBondAmount (uint256 _amount ) external onlyMinipoolOwner (msg .sender ) onlyInitialised {
597
+ function reduceBondAmount (uint256 _amount ) override external onlyMinipoolOwner (msg .sender ) onlyInitialised {
638
598
uint256 previousBond = nodeDepositBalance;
639
- require (canReduceBondAmount (), "Wait period not satisfied " );
640
- require (! reductionCancelled, "This minipool is allowed to reduce bond " );
641
599
require (_amount < previousBond, "Bond must be lower than current amount " );
642
600
require (status == MinipoolStatus.Staking, "Minipool must be staking " );
643
- // Get contracts
644
- RocketNodeDepositInterface rocketNodeDeposit = RocketNodeDepositInterface (getContractAddress ("rocketNodeDeposit " ));
645
- // Check the new bond amount is valid
646
- require (rocketNodeDeposit.isValidDepositAmount (_amount), "Invalid bond amount " );
647
601
// Distribute any skimmed rewards
648
602
distributeSkimmedRewards ();
649
- // Calculate bond difference
650
- uint256 delta = previousBond.sub (_amount);
651
- // Increase ETH matched or revert if exceeds limit based on current RPL stake
652
- rocketNodeDeposit.increaseEthMatched (nodeAddress, delta);
603
+ // Approve reduction and handle external state changes
604
+ RocketMinipoolBondReducerInterface rocketBondReducer = RocketMinipoolBondReducerInterface (getContractAddress ("rocketMinipoolBondReducer " ));
605
+ rocketBondReducer.reduceBondAmount (previousBond, _amount);
653
606
// Update user/node balances
654
- userDepositBalance = getUserDepositBalance ().add (delta );
607
+ userDepositBalance = getUserDepositBalance ().add (previousBond. sub (_amount) );
655
608
nodeDepositBalance = _amount;
656
609
// Reset node fee to current network rate
657
610
RocketNetworkFeesInterface rocketNetworkFees = RocketNetworkFeesInterface (getContractAddress ("rocketNetworkFees " ));
658
611
nodeFee = rocketNetworkFees.getNodeFee ();
659
- // Increase node operator's deposit credit
660
- rocketNodeDeposit.increaseDepositCreditBalance (nodeAddress, delta);
661
612
// Break state to prevent rollback exploit
662
613
if (depositType != MinipoolDeposit.Variable) {
663
614
userDepositBalanceLegacy = 2 ** 256-1 ;
@@ -724,14 +675,16 @@ contract RocketMinipoolDelegate is RocketMinipoolStorageLayout, RocketMinipoolIn
724
675
RocketMinipoolManagerInterface rocketMinipoolManager = RocketMinipoolManagerInterface (getContractAddress ("rocketMinipoolManager " ));
725
676
rocketMinipoolManager.removeVacantMinipool ();
726
677
} else {
727
- // Transfer user balance to deposit pool
728
- uint256 userCapital = getUserDepositBalance ();
729
- rocketDepositPool.recycleDissolvedDeposit {value : userCapital}();
730
- // Emit ether withdrawn event
731
- emit EtherWithdrawn (address (rocketDepositPool), userCapital, block .timestamp );
678
+ if (depositType == MinipoolDeposit.Full) {
679
+ // Handle legacy Full type minipool
680
+ rocketMinipoolQueue.removeMinipool (MinipoolDeposit.full);
681
+ } else {
682
+ // Transfer user balance to deposit pool
683
+ uint256 userCapital = getUserDepositBalance ();
684
+ rocketDepositPool.recycleDissolvedDeposit {value : userCapital}();
685
+ // Emit ether withdrawn event
686
+ emit EtherWithdrawn (address (rocketDepositPool), userCapital, block .timestamp );
687
+ }
732
688
}
733
- // Clear storage
734
- nodeDepositBalance = 0 ;
735
- nodeRefundBalance = 0 ;
736
689
}
737
690
}
0 commit comments