Skip to content

Commit

Permalink
v1.0.1 (#411)
Browse files Browse the repository at this point in the history
* Add oracle recency requirement for deposits to make frontrun attacks impossible even without admin intervention
* RPL liquidity is now prioritized over stake rebalancing during minipool processing
* Removed timelock requirement for the `maxValidators` parameter (to allow the admin to increase the medium timelock delay without delaying growth responses)
* Optimized revert conditions for `SuperNodeAccount.createMinipool()` to first check the most common reasons for revert to save gas in those cases
* Add an event in `OperatorDistributor.sol` to help with rewards calculations
* xrETH and xRPL now comply with Balancer's `IRateProvider` interface for easier integration
  • Loading branch information
VVander authored Nov 20, 2024
1 parent 7686580 commit cf7788a
Show file tree
Hide file tree
Showing 37 changed files with 1,290 additions and 572 deletions.
71 changes: 39 additions & 32 deletions contracts/Constellation/OperatorDistributor.sol
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
// SPDX-License-Identifier: GPL v3

/**
* /*** /*** /****** /** /** /** /** /**
* /**_/ |_ ** /**__ ** | ** | **| ** | ** |__/
* | ** /** /** | ** | ** \__/ /****** /******* /******* /****** /****** | **| ** /****** /****** /** /****** /*******
* /*** |__/|__/ | *** | ** /**__ **| **__ ** /**_____/|_ **_/ /**__ **| **| ** |____ **|_ **_/ | ** /**__ **| **__ **
* | ** | ** | ** | ** \ **| ** \ **| ****** | ** | ********| **| ** /******* | ** | **| ** \ **| ** \ **
* \ ** /** /** | ** | ** **| ** | **| ** | ** \____ ** | ** /* | **_____/| **| ** /**__ ** | ** /* | **| ** | **| ** | **
* | ***|__/|__/*** | ******|| ****** | ** | ** /******* | **** | *******| **| **| ******** | **** | **| ****** | ** | **
* \___/ |___/ \______/ \______/ |__/ |__/|_______/ \___/ \_______/|__/|__/ \_______/ \___/ |__/ \______/ |__/ |__/
*
* A liquid staking protocol extending Rocket Pool.
* Made w/ <3 by {::}
*
* For more information, visit https://nodeset.io
*
* @author Mike Leach (Wander), Nick Steinhilber (NickS), Theodore Clapp (mryamz), Joe Clapis (jcrtp), Huy Nguyen, Andy Rose (Barbalute)
* @custom:security-info https://docs.nodeset.io/nodeset/security-notice
**/
* /*** /*** /****** /** /** /** /** /**
* /**_/ |_ ** /**__ ** | ** | **| ** | ** |__/
* | ** /** /** | ** | ** \__/ /****** /******* /******* /****** /****** | **| ** /****** /****** /** /****** /*******
* /*** |__/|__/ | *** | ** /**__ **| **__ ** /**_____/|_ **_/ /**__ **| **| ** |____ **|_ **_/ | ** /**__ **| **__ **
* | ** | ** | ** | ** \ **| ** \ **| ****** | ** | ********| **| ** /******* | ** | **| ** \ **| ** \ **
* \ ** /** /** | ** | ** **| ** | **| ** | ** \____ ** | ** /* | **_____/| **| ** /**__ ** | ** /* | **| ** | **| ** | **
* | ***|__/|__/*** | ******|| ****** | ** | ** /******* | **** | *******| **| **| ******** | **** | **| ****** | ** | **
* \___/ |___/ \______/ \______/ |__/ |__/|_______/ \___/ \_______/|__/|__/ \_______/ \___/ |__/ \______/ |__/ |__/
*
* A liquid staking protocol extending Rocket Pool.
* Made w/ <3 by {::}
*
* For more information, visit https://nodeset.io
*
* @author Mike Leach (Wander), Nick Steinhilber (NickS), Theodore Clapp (mryamz), Joe Clapis (jcrtp), Huy Nguyen, Andy Rose (Barbalute)
* @custom:security-info https://docs.nodeset.io/nodeset/security-notice
**/

pragma solidity 0.8.17;

Expand Down Expand Up @@ -57,6 +57,7 @@ contract OperatorDistributor is UpgradeableBase {
event RPLStakeRebalanceEnabledChanged(bool isAllowed);

event MinipoolProcessed(address indexed minipool, uint256 ethRewards, bool indexed finalized);
event EthBeaconRewardsReceived(uint256 ethRewards, uint256 noPortion, uint256 treasuryPortion);

event WarningMinipoolNotStaking(
address indexed _minipoolAddress,
Expand All @@ -71,15 +72,21 @@ contract OperatorDistributor is UpgradeableBase {
bool public rplStakeRebalanceEnabled;

function setRplStakeRebalanceEnabled(bool _newValue) external onlyAdmin {
require(rplStakeRebalanceEnabled != _newValue, 'OperatorDistributor: new rplStakeRebalanceEnabled value must be different than existing value');
require(
rplStakeRebalanceEnabled != _newValue,
'OperatorDistributor: new rplStakeRebalanceEnabled value must be different than existing value'
);
emit RPLStakeRebalanceEnabledChanged(_newValue);
rplStakeRebalanceEnabled = _newValue;
}

bool public minipoolProcessingEnabled;

function setMinipoolProcessingEnabled(bool _newValue) external onlyAdmin {
require(minipoolProcessingEnabled != _newValue, 'OperatorDistributor: new minipoolProcessingEnabled value must be different than existing value');
require(
minipoolProcessingEnabled != _newValue,
'OperatorDistributor: new minipoolProcessingEnabled value must be different than existing value'
);
emit MinipoolProcessingEnabledChanged(_newValue);
minipoolProcessingEnabled = _newValue;
}
Expand All @@ -95,7 +102,10 @@ contract OperatorDistributor is UpgradeableBase {
* @param _targetStakeRatio The new target stake ratio to be set.
*/
function setTargetStakeRatio(uint256 _targetStakeRatio) external onlyAdmin {
require(_targetStakeRatio != targetStakeRatio, 'OperatorDistributor: new targetStakeRatio must be different than existing value');
require(
_targetStakeRatio != targetStakeRatio,
'OperatorDistributor: new targetStakeRatio must be different than existing value'
);
emit TargetStakeRatioUpdated(targetStakeRatio, _targetStakeRatio);
targetStakeRatio = _targetStakeRatio;
}
Expand All @@ -109,7 +119,10 @@ contract OperatorDistributor is UpgradeableBase {
* @param _minimumStakeRatio The new minimum stake ratio to be set.
*/
function setMinimumStakeRatio(uint256 _minimumStakeRatio) external onlyAdmin {
require(_minimumStakeRatio != minimumStakeRatio, 'OperatorDistributor: new minimumStakeRatio must be different than existing value');
require(
_minimumStakeRatio != minimumStakeRatio,
'OperatorDistributor: new minimumStakeRatio must be different than existing value'
);
emit MinStakeRatioUpdated(minimumStakeRatio, _minimumStakeRatio);
minimumStakeRatio = _minimumStakeRatio;
}
Expand Down Expand Up @@ -333,8 +346,8 @@ contract OperatorDistributor is UpgradeableBase {
}

this.rebalanceWethVault();
this.rebalanceRplStake(sna.getEthStaked());
this.rebalanceRplVault();
this.rebalanceRplStake(sna.getEthStaked());

emit MinipoolProcessed(address(minipool), rewards, minipool.getFinalised());
}
Expand Down Expand Up @@ -418,10 +431,7 @@ contract OperatorDistributor is UpgradeableBase {
address rocketNodeStakingAddress = _directory.getRocketNodeStakingAddress();
SafeERC20.safeApprove(rpl, rocketNodeStakingAddress, 0);
SafeERC20.safeApprove(rpl, rocketNodeStakingAddress, _amount);
IRocketNodeStaking(rocketNodeStakingAddress).stakeRPLFor(
getDirectory().getSuperNodeAddress(),
_amount
);
IRocketNodeStaking(rocketNodeStakingAddress).stakeRPLFor(getDirectory().getSuperNodeAddress(), _amount);
}

/// @notice Submits a merkle claim to RP on behalf of the SuperNode
Expand Down Expand Up @@ -517,6 +527,7 @@ contract OperatorDistributor is UpgradeableBase {

uint256 xrETHPortion = rewardAmount - treasuryPortion - nodeOperatorPortion;

emit EthBeaconRewardsReceived(rewardAmount, nodeOperatorPortion, treasuryPortion);
this.onIncreaseOracleError(xrETHPortion);
}

Expand Down Expand Up @@ -573,18 +584,14 @@ contract OperatorDistributor is UpgradeableBase {

function transferMerkleClaimToStreamer(uint256 ethAmount, uint256 rplAmount) external onlyProtocol {
address payable mcsAddress = getDirectory().getMerkleClaimStreamerAddress();

if (ethAmount > 0) {
(bool success, ) = mcsAddress.call{value: ethAmount}('');
require(success, 'ETH transfer to MerkleClaimStreamer failed');
}

if (rplAmount > 0) {
SafeERC20.safeTransfer(
IERC20(_directory.getRPLAddress()),
mcsAddress,
rplAmount
);
SafeERC20.safeTransfer(IERC20(_directory.getRPLAddress()), mcsAddress, rplAmount);
}
}
}
9 changes: 8 additions & 1 deletion contracts/Constellation/RPLVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,15 @@ import './Utils/UpgradeableBase.sol';
import './OperatorDistributor.sol';

import './Utils/PriceFetcher.sol';
import '../Interfaces/IRateProvider.sol';

/**
* @title RPLVault
* @author Theodore Clapp, Mike Leach
* @dev An ERC-4626 vault for staking RPL with a single node run by a decentralized operator set.
* @notice These vault shares will increase or decrease in value according to the rewards or penalties applied to the SuperNodeAccount by Rocket Pool.
*/
contract RPLVault is UpgradeableBase, ERC4626Upgradeable {
contract RPLVault is UpgradeableBase, ERC4626Upgradeable, IRateProvider {
using Math for uint256;

event TreasuryFeeChanged(uint256 indexed oldFee, uint256 indexed newFee);
Expand Down Expand Up @@ -231,6 +232,12 @@ contract RPLVault is UpgradeableBase, ERC4626Upgradeable {
return ((tvlEth * rplPerEth) / minWethRplRatio) - tvlRpl;
}

/// @dev Shortcut for easier defi integration (e.g. Balancer)
/// @return The value of 1 xRPL in terms of RPL
function getRate() public view returns (uint256) {
return convertToAssets(1 ether);
}

/**ADMIN FUNCTIONS */


Expand Down
Loading

0 comments on commit cf7788a

Please sign in to comment.