From b8e43c79844c55521ef7ee87c949c04bf958ac75 Mon Sep 17 00:00:00 2001 From: Joe Clapis Date: Fri, 10 Feb 2023 16:22:26 -0500 Subject: [PATCH] Added getAggregatedEffectiveRPLStake --- contracts/contract/node/RocketNodeStaking.sol | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/contracts/contract/node/RocketNodeStaking.sol b/contracts/contract/node/RocketNodeStaking.sol index aa2ec940d..934cc9560 100644 --- a/contracts/contract/node/RocketNodeStaking.sol +++ b/contracts/contract/node/RocketNodeStaking.sol @@ -283,4 +283,52 @@ contract RocketNodeStaking is RocketBase, RocketNodeStakingInterface { emit RPLSlashed(_nodeAddress, rplSlashAmount, _ethSlashAmount, block.timestamp); } + /// @notice Get the combined effective RPL stake for all nodes in the provided range. + /// @param _offset The offset into the node set to start + /// @param _limit The maximum number of nodes to iterate + function getAggregatedEffectiveRPLStake (uint256 _offset, uint256 _limit) override external view + returns (uint256 aggregatedStake) { + // Load contracts + RocketNetworkPricesInterface rocketNetworkPrices = RocketNetworkPricesInterface(getContractAddress("rocketNetworkPrices")); + RocketDAOProtocolSettingsNodeInterface rocketDAOProtocolSettingsNode = RocketDAOProtocolSettingsNodeInterface(getContractAddress("rocketDAOProtocolSettingsNode")); + AddressSetStorageInterface addressSetStorage = AddressSetStorageInterface(getContractAddress("addressSetStorage")); + + // Get min and max + uint256 rplPrice = rocketNetworkPrices.getRPLPrice(); + uint256 minimumStakePercent = rocketDAOProtocolSettingsNode.getMinimumPerMinipoolStake(); + uint256 maximumStakePercent = rocketDAOProtocolSettingsNode.getMaximumPerMinipoolStake(); + + // Precompute node key + bytes32 nodeKey = keccak256(abi.encodePacked("nodes.index")); + + // Iterate over the requested node range + uint256 totalNodes = addressSetStorage.getCount(keccak256(abi.encodePacked("nodes.index"))); + uint256 max = _offset.add(_limit); + if (max > totalNodes || _limit == 0) { max = totalNodes; } + for (uint256 i = _offset; i < max; i++) { + // Get the node at index i + address _nodeAddress = addressSetStorage.getItem(nodeKey, i); + + // Get node's current RPL stake + uint256 rplStake = getNodeRPLStake(_nodeAddress); + + // Retrieve variables for calculations + uint256 matchedETH = getNodeETHMatched(_nodeAddress); + uint256 providedETH = getNodeETHProvided(_nodeAddress); + uint256 minimumStake = matchedETH.mul(minimumStakePercent).div(rplPrice); + uint256 maximumStake = providedETH.mul(maximumStakePercent).div(rplPrice); + + if (rplStake > maximumStake) { + // RPL stake cannot exceed maximum + aggregatedStake += maximumStake; + } + else if (rplStake < minimumStake) { + // If RPL stake is lower than minimum, node has no effective stake + } + else { + aggregatedStake += rplStake + } + } + } + }