编译器
0.8.18+commit.87f61d96
文件 1 的 21:AddressSetStorageInterface.sol
pragma solidity >0.5.0 <0.9.0;
interface AddressSetStorageInterface {
function getCount(bytes32 _key) external view returns (uint);
function getItem(bytes32 _key, uint _index) external view returns (address);
function getIndexOf(bytes32 _key, address _value) external view returns (int);
function addItem(bytes32 _key, address _value) external;
function removeItem(bytes32 _key, address _value) external;
}
文件 2 的 21:IERC20.sol
pragma solidity >0.5.0 <0.9.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}
文件 3 的 21:MinipoolDeposit.sol
pragma solidity >0.5.0 <0.9.0;
enum MinipoolDeposit {
None,
Full,
Half,
Empty,
Variable
}
文件 4 的 21:MinipoolDetails.sol
pragma solidity >0.5.0 <0.9.0;
import "./MinipoolDeposit.sol";
import "./MinipoolStatus.sol";
struct MinipoolDetails {
bool exists;
address minipoolAddress;
bytes pubkey;
MinipoolStatus status;
uint256 statusBlock;
uint256 statusTime;
bool finalised;
MinipoolDeposit depositType;
uint256 nodeFee;
uint256 nodeDepositBalance;
bool nodeDepositAssigned;
uint256 userDepositBalance;
bool userDepositAssigned;
uint256 userDepositAssignedTime;
bool useLatestDelegate;
address delegate;
address previousDelegate;
address effectiveDelegate;
uint256 penaltyCount;
uint256 penaltyRate;
address nodeAddress;
}
文件 5 的 21:MinipoolStatus.sol
pragma solidity >0.5.0 <0.9.0;
enum MinipoolStatus {
Initialised,
Prelaunch,
Staking,
Withdrawable,
Dissolved
}
文件 6 的 21:NodeDetails.sol
pragma solidity >0.5.0 <0.9.0;
struct NodeDetails {
bool exists;
uint256 registrationTime;
string timezoneLocation;
bool feeDistributorInitialised;
address feeDistributorAddress;
uint256 rewardNetwork;
uint256 rplStake;
uint256 effectiveRPLStake;
uint256 minimumRPLStake;
uint256 maximumRPLStake;
uint256 ethMatched;
uint256 ethMatchedLimit;
uint256 minipoolCount;
uint256 balanceETH;
uint256 balanceRETH;
uint256 balanceRPL;
uint256 balanceOldRPL;
uint256 depositCreditBalance;
uint256 distributorBalanceUserETH;
uint256 distributorBalanceNodeETH;
address withdrawalAddress;
address pendingWithdrawalAddress;
bool smoothingPoolRegistrationState;
uint256 smoothingPoolRegistrationChanged;
address nodeAddress;
}
文件 7 的 21:RocketBase.sol
pragma solidity >0.5.0 <0.9.0;
import "../interface/RocketStorageInterface.sol";
abstract contract RocketBase {
uint256 constant calcBase = 1 ether;
uint8 public version;
RocketStorageInterface rocketStorage = RocketStorageInterface(address(0));
modifier onlyLatestNetworkContract() {
require(getBool(keccak256(abi.encodePacked("contract.exists", msg.sender))), "Invalid or outdated network contract");
_;
}
modifier onlyLatestContract(string memory _contractName, address _contractAddress) {
require(_contractAddress == getAddress(keccak256(abi.encodePacked("contract.address", _contractName))), "Invalid or outdated contract");
_;
}
modifier onlyRegisteredNode(address _nodeAddress) {
require(getBool(keccak256(abi.encodePacked("node.exists", _nodeAddress))), "Invalid node");
_;
}
modifier onlyTrustedNode(address _nodeAddress) {
require(getBool(keccak256(abi.encodePacked("dao.trustednodes.", "member", _nodeAddress))), "Invalid trusted node");
_;
}
modifier onlyRegisteredMinipool(address _minipoolAddress) {
require(getBool(keccak256(abi.encodePacked("minipool.exists", _minipoolAddress))), "Invalid minipool");
_;
}
modifier onlyGuardian() {
require(msg.sender == rocketStorage.getGuardian(), "Account is not a temporary guardian");
_;
}
constructor(RocketStorageInterface _rocketStorageAddress) {
rocketStorage = RocketStorageInterface(_rocketStorageAddress);
}
function getContractAddress(string memory _contractName) internal view returns (address) {
address contractAddress = getAddress(keccak256(abi.encodePacked("contract.address", _contractName)));
require(contractAddress != address(0x0), "Contract not found");
return contractAddress;
}
function getContractAddressUnsafe(string memory _contractName) internal view returns (address) {
address contractAddress = getAddress(keccak256(abi.encodePacked("contract.address", _contractName)));
return contractAddress;
}
function getContractName(address _contractAddress) internal view returns (string memory) {
string memory contractName = getString(keccak256(abi.encodePacked("contract.name", _contractAddress)));
require(bytes(contractName).length > 0, "Contract not found");
return contractName;
}
function getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {
if (_returnData.length < 68) return "Transaction reverted silently";
assembly {
_returnData := add(_returnData, 0x04)
}
return abi.decode(_returnData, (string));
}
function getAddress(bytes32 _key) internal view returns (address) { return rocketStorage.getAddress(_key); }
function getUint(bytes32 _key) internal view returns (uint) { return rocketStorage.getUint(_key); }
function getString(bytes32 _key) internal view returns (string memory) { return rocketStorage.getString(_key); }
function getBytes(bytes32 _key) internal view returns (bytes memory) { return rocketStorage.getBytes(_key); }
function getBool(bytes32 _key) internal view returns (bool) { return rocketStorage.getBool(_key); }
function getInt(bytes32 _key) internal view returns (int) { return rocketStorage.getInt(_key); }
function getBytes32(bytes32 _key) internal view returns (bytes32) { return rocketStorage.getBytes32(_key); }
function setAddress(bytes32 _key, address _value) internal { rocketStorage.setAddress(_key, _value); }
function setUint(bytes32 _key, uint _value) internal { rocketStorage.setUint(_key, _value); }
function setString(bytes32 _key, string memory _value) internal { rocketStorage.setString(_key, _value); }
function setBytes(bytes32 _key, bytes memory _value) internal { rocketStorage.setBytes(_key, _value); }
function setBool(bytes32 _key, bool _value) internal { rocketStorage.setBool(_key, _value); }
function setInt(bytes32 _key, int _value) internal { rocketStorage.setInt(_key, _value); }
function setBytes32(bytes32 _key, bytes32 _value) internal { rocketStorage.setBytes32(_key, _value); }
function deleteAddress(bytes32 _key) internal { rocketStorage.deleteAddress(_key); }
function deleteUint(bytes32 _key) internal { rocketStorage.deleteUint(_key); }
function deleteString(bytes32 _key) internal { rocketStorage.deleteString(_key); }
function deleteBytes(bytes32 _key) internal { rocketStorage.deleteBytes(_key); }
function deleteBool(bytes32 _key) internal { rocketStorage.deleteBool(_key); }
function deleteInt(bytes32 _key) internal { rocketStorage.deleteInt(_key); }
function deleteBytes32(bytes32 _key) internal { rocketStorage.deleteBytes32(_key); }
function addUint(bytes32 _key, uint256 _amount) internal { rocketStorage.addUint(_key, _amount); }
function subUint(bytes32 _key, uint256 _amount) internal { rocketStorage.subUint(_key, _amount); }
}
文件 8 的 21:RocketDAONodeTrustedSettingsRewardsInterface.sol
pragma solidity >0.5.0 <0.9.0;
interface RocketDAONodeTrustedSettingsRewardsInterface {
function getNetworkEnabled(uint256 _network) external view returns (bool);
}
文件 9 的 21:RocketDAOProtocolSettingsMinipoolInterface.sol
pragma solidity >0.5.0 <0.9.0;
import "../../../../types/MinipoolDeposit.sol";
interface RocketDAOProtocolSettingsMinipoolInterface {
function getLaunchBalance() external view returns (uint256);
function getPreLaunchValue() external pure returns (uint256);
function getDepositUserAmount(MinipoolDeposit _depositType) external view returns (uint256);
function getFullDepositUserAmount() external view returns (uint256);
function getHalfDepositUserAmount() external view returns (uint256);
function getVariableDepositAmount() external view returns (uint256);
function getSubmitWithdrawableEnabled() external view returns (bool);
function getBondReductionEnabled() external view returns (bool);
function getLaunchTimeout() external view returns (uint256);
function getMaximumCount() external view returns (uint256);
function isWithinUserDistributeWindow(uint256 _time) external view returns (bool);
function hasUserDistributeWindowPassed(uint256 _time) external view returns (bool);
function getUserDistributeWindowStart() external view returns (uint256);
function getUserDistributeWindowLength() external view returns (uint256);
}
文件 10 的 21:RocketDAOProtocolSettingsNodeInterface.sol
pragma solidity >0.5.0 <0.9.0;
interface RocketDAOProtocolSettingsNodeInterface {
function getRegistrationEnabled() external view returns (bool);
function getSmoothingPoolRegistrationEnabled() external view returns (bool);
function getDepositEnabled() external view returns (bool);
function getVacantMinipoolsEnabled() external view returns (bool);
function getMinimumPerMinipoolStake() external view returns (uint256);
function getMaximumPerMinipoolStake() external view returns (uint256);
function getMaximumStakeForVotingPower() external view returns (uint256);
}
文件 11 的 21:RocketDAOProtocolSettingsRewardsInterface.sol
pragma solidity >0.5.0 <0.9.0;
interface RocketDAOProtocolSettingsRewardsInterface {
function setSettingRewardsClaimers(uint256 _trustedNodePercent, uint256 _protocolPercent, uint256 _nodePercent) external;
function getRewardsClaimerPerc(string memory _contractName) external view returns (uint256);
function getRewardsClaimersPerc() external view returns (uint256 _trustedNodePercent, uint256 _protocolPercent, uint256 _nodePercent);
function getRewardsClaimersTrustedNodePerc() external view returns (uint256);
function getRewardsClaimersProtocolPerc() external view returns (uint256);
function getRewardsClaimersNodePerc() external view returns (uint256);
function getRewardsClaimersTimeUpdated() external view returns (uint256);
function getRewardsClaimIntervalPeriods() external view returns (uint256);
function getRewardsClaimIntervalTime() external view returns (uint256);
}
文件 12 的 21:RocketMinipoolInterface.sol
pragma solidity >0.5.0 <0.9.0;
import "../../types/MinipoolDeposit.sol";
import "../../types/MinipoolStatus.sol";
import "../RocketStorageInterface.sol";
interface RocketMinipoolInterface {
function version() external view returns (uint8);
function initialise(address _nodeAddress) external;
function getStatus() external view returns (MinipoolStatus);
function getFinalised() external view returns (bool);
function getStatusBlock() external view returns (uint256);
function getStatusTime() external view returns (uint256);
function getScrubVoted(address _member) external view returns (bool);
function getDepositType() external view returns (MinipoolDeposit);
function getNodeAddress() external view returns (address);
function getNodeFee() external view returns (uint256);
function getNodeDepositBalance() external view returns (uint256);
function getNodeRefundBalance() external view returns (uint256);
function getNodeDepositAssigned() external view returns (bool);
function getPreLaunchValue() external view returns (uint256);
function getNodeTopUpValue() external view returns (uint256);
function getVacant() external view returns (bool);
function getPreMigrationBalance() external view returns (uint256);
function getUserDistributed() external view returns (bool);
function getUserDepositBalance() external view returns (uint256);
function getUserDepositAssigned() external view returns (bool);
function getUserDepositAssignedTime() external view returns (uint256);
function getTotalScrubVotes() external view returns (uint256);
function calculateNodeShare(uint256 _balance) external view returns (uint256);
function calculateUserShare(uint256 _balance) external view returns (uint256);
function preDeposit(uint256 _bondingValue, bytes calldata _validatorPubkey, bytes calldata _validatorSignature, bytes32 _depositDataRoot) external payable;
function deposit() external payable;
function userDeposit() external payable;
function distributeBalance(bool _rewardsOnly) external;
function beginUserDistribute() external;
function userDistributeAllowed() external view returns (bool);
function refund() external;
function slash() external;
function finalise() external;
function canStake() external view returns (bool);
function canPromote() external view returns (bool);
function stake(bytes calldata _validatorSignature, bytes32 _depositDataRoot) external;
function prepareVacancy(uint256 _bondAmount, uint256 _currentBalance) external;
function promote() external;
function dissolve() external;
function close() external;
function voteScrub() external;
function reduceBondAmount() external;
}
文件 13 的 21:RocketMinipoolManagerInterface.sol
pragma solidity >0.5.0 <0.9.0;
pragma abicoder v2;
import "../../types/MinipoolDeposit.sol";
import "../../types/MinipoolDetails.sol";
import "./RocketMinipoolInterface.sol";
interface RocketMinipoolManagerInterface {
function getMinipoolCount() external view returns (uint256);
function getStakingMinipoolCount() external view returns (uint256);
function getFinalisedMinipoolCount() external view returns (uint256);
function getActiveMinipoolCount() external view returns (uint256);
function getMinipoolRPLSlashed(address _minipoolAddress) external view returns (bool);
function getMinipoolCountPerStatus(uint256 offset, uint256 limit) external view returns (uint256, uint256, uint256, uint256, uint256);
function getPrelaunchMinipools(uint256 offset, uint256 limit) external view returns (address[] memory);
function getMinipoolAt(uint256 _index) external view returns (address);
function getNodeMinipoolCount(address _nodeAddress) external view returns (uint256);
function getNodeActiveMinipoolCount(address _nodeAddress) external view returns (uint256);
function getNodeFinalisedMinipoolCount(address _nodeAddress) external view returns (uint256);
function getNodeStakingMinipoolCount(address _nodeAddress) external view returns (uint256);
function getNodeStakingMinipoolCountBySize(address _nodeAddress, uint256 _depositSize) external view returns (uint256);
function getNodeMinipoolAt(address _nodeAddress, uint256 _index) external view returns (address);
function getNodeValidatingMinipoolCount(address _nodeAddress) external view returns (uint256);
function getNodeValidatingMinipoolAt(address _nodeAddress, uint256 _index) external view returns (address);
function getMinipoolByPubkey(bytes calldata _pubkey) external view returns (address);
function getMinipoolExists(address _minipoolAddress) external view returns (bool);
function getMinipoolDestroyed(address _minipoolAddress) external view returns (bool);
function getMinipoolPubkey(address _minipoolAddress) external view returns (bytes memory);
function updateNodeStakingMinipoolCount(uint256 _previousBond, uint256 _newBond, uint256 _previousFee, uint256 _newFee) external;
function getMinipoolWithdrawalCredentials(address _minipoolAddress) external pure returns (bytes memory);
function createMinipool(address _nodeAddress, uint256 _salt) external returns (RocketMinipoolInterface);
function createVacantMinipool(address _nodeAddress, uint256 _salt, bytes calldata _validatorPubkey, uint256 _bondAmount, uint256 _currentBalance) external returns (RocketMinipoolInterface);
function removeVacantMinipool() external;
function getVacantMinipoolCount() external view returns (uint256);
function getVacantMinipoolAt(uint256 _index) external view returns (address);
function destroyMinipool() external;
function incrementNodeStakingMinipoolCount(address _nodeAddress) external;
function decrementNodeStakingMinipoolCount(address _nodeAddress) external;
function tryDistribute(address _nodeAddress) external;
function incrementNodeFinalisedMinipoolCount(address _nodeAddress) external;
function setMinipoolPubkey(bytes calldata _pubkey) external;
function getMinipoolDepositType(address _minipoolAddress) external view returns (MinipoolDeposit);
}
文件 14 的 21:RocketNetworkSnapshotsInterface.sol
pragma solidity >0.5.0 <0.9.0;
struct Checkpoint224 {
uint32 _block;
uint224 _value;
}
interface RocketNetworkSnapshotsInterface {
function push(bytes32 _key, uint224 _value) external;
function length(bytes32 _key) external view returns (uint256);
function latest(bytes32 _key) external view returns (bool, uint32, uint224);
function latestBlock(bytes32 _key) external view returns (uint32);
function latestValue(bytes32 _key) external view returns (uint224);
function lookup(bytes32 _key, uint32 _block) external view returns (uint224);
function lookupRecent(bytes32 _key, uint32 _block, uint256 _recency) external view returns (uint224);
}
文件 15 的 21:RocketNodeDepositInterface.sol
pragma solidity >0.5.0 <0.9.0;
import "../../types/MinipoolDeposit.sol";
interface RocketNodeDepositInterface {
function getNodeDepositCredit(address _nodeAddress) external view returns (uint256);
function getNodeEthBalance(address _nodeAddress) external view returns (uint256);
function getNodeCreditAndBalance(address _nodeAddress) external view returns (uint256);
function getNodeUsableCreditAndBalance(address _nodeAddress) external view returns (uint256);
function getNodeUsableCredit(address _nodeAddress) external view returns (uint256);
function increaseDepositCreditBalance(address _nodeOperator, uint256 _amount) external;
function depositEthFor(address _nodeAddress) external payable;
function withdrawEth(address _nodeAddress, uint256 _amount) external;
function deposit(uint256 _depositAmount, uint256 _minimumNodeFee, bytes calldata _validatorPubkey, bytes calldata _validatorSignature, bytes32 _depositDataRoot, uint256 _salt, address _expectedMinipoolAddress) external payable;
function depositWithCredit(uint256 _depositAmount, uint256 _minimumNodeFee, bytes calldata _validatorPubkey, bytes calldata _validatorSignature, bytes32 _depositDataRoot, uint256 _salt, address _expectedMinipoolAddress) external payable;
function isValidDepositAmount(uint256 _amount) external pure returns (bool);
function getDepositAmounts() external pure returns (uint256[] memory);
function createVacantMinipool(uint256 _bondAmount, uint256 _minimumNodeFee, bytes calldata _validatorPubkey, uint256 _salt, address _expectedMinipoolAddress, uint256 _currentBalance) external;
function increaseEthMatched(address _nodeAddress, uint256 _amount) external;
}
文件 16 的 21:RocketNodeDistributorFactoryInterface.sol
pragma solidity >0.5.0 <0.9.0;
interface RocketNodeDistributorFactoryInterface {
function getProxyBytecode() external pure returns (bytes memory);
function getProxyAddress(address _nodeAddress) external view returns(address);
function createProxy(address _nodeAddress) external;
}
文件 17 的 21:RocketNodeDistributorInterface.sol
pragma solidity >0.5.0 <0.9.0;
interface RocketNodeDistributorInterface {
function getNodeShare() external view returns (uint256);
function getUserShare() external view returns (uint256);
function distribute() external;
}
文件 18 的 21:RocketNodeManager.sol
pragma solidity 0.8.18;
pragma abicoder v2;
import "../RocketBase.sol";
import "../../types/MinipoolStatus.sol";
import "../../types/NodeDetails.sol";
import "../../interface/node/RocketNodeManagerInterface.sol";
import "../../interface/dao/protocol/settings/RocketDAOProtocolSettingsNodeInterface.sol";
import "../../interface/util/AddressSetStorageInterface.sol";
import "../../interface/node/RocketNodeDistributorFactoryInterface.sol";
import "../../interface/minipool/RocketMinipoolManagerInterface.sol";
import "../../interface/node/RocketNodeDistributorInterface.sol";
import "../../interface/dao/node/settings/RocketDAONodeTrustedSettingsRewardsInterface.sol";
import "../../interface/dao/protocol/settings/RocketDAOProtocolSettingsRewardsInterface.sol";
import "../../interface/node/RocketNodeStakingInterface.sol";
import "../../interface/node/RocketNodeDepositInterface.sol";
import "../../interface/dao/protocol/settings/RocketDAOProtocolSettingsMinipoolInterface.sol";
import "../../interface/util/IERC20.sol";
import "../../interface/network/RocketNetworkSnapshotsInterface.sol";
contract RocketNodeManager is RocketBase, RocketNodeManagerInterface {
event NodeRegistered(address indexed node, uint256 time);
event NodeTimezoneLocationSet(address indexed node, uint256 time);
event NodeRewardNetworkChanged(address indexed node, uint256 network);
event NodeSmoothingPoolStateChanged(address indexed node, bool state);
event NodeRPLWithdrawalAddressSet(address indexed node, address indexed withdrawalAddress, uint256 time);
event NodeRPLWithdrawalAddressUnset(address indexed node, uint256 time);
constructor(RocketStorageInterface _rocketStorageAddress) RocketBase(_rocketStorageAddress) {
version = 4;
}
function getNodeCount() override public view returns (uint256) {
AddressSetStorageInterface addressSetStorage = AddressSetStorageInterface(getContractAddress("addressSetStorage"));
return addressSetStorage.getCount(keccak256(abi.encodePacked("nodes.index")));
}
function getNodeCountPerTimezone(uint256 _offset, uint256 _limit) override external view returns (TimezoneCount[] memory) {
AddressSetStorageInterface addressSetStorage = AddressSetStorageInterface(getContractAddress("addressSetStorage"));
bytes32 nodeKey = keccak256(abi.encodePacked("nodes.index"));
uint256 totalNodes = addressSetStorage.getCount(nodeKey);
uint256 max = _offset + _limit;
if (max > totalNodes || _limit == 0) { max = totalNodes; }
TimezoneCount[] memory counts = new TimezoneCount[](max - _offset);
uint256 uniqueTimezoneCount = 0;
for (uint256 i = _offset; i < max; ++i) {
address nodeAddress = addressSetStorage.getItem(nodeKey, i);
string memory timezone = getString(keccak256(abi.encodePacked("node.timezone.location", nodeAddress)));
bool existing = false;
for (uint256 j = 0; j < uniqueTimezoneCount; ++j) {
if (keccak256(bytes(counts[j].timezone)) == keccak256(bytes(timezone))) {
existing = true;
counts[j].count++;
break;
}
}
if (!existing) {
counts[uniqueTimezoneCount].timezone = timezone;
counts[uniqueTimezoneCount].count = 1;
uniqueTimezoneCount++;
}
}
assembly {
mstore(counts, uniqueTimezoneCount)
}
return counts;
}
function getNodeAt(uint256 _index) override external view returns (address) {
AddressSetStorageInterface addressSetStorage = AddressSetStorageInterface(getContractAddress("addressSetStorage"));
return addressSetStorage.getItem(keccak256(abi.encodePacked("nodes.index")), _index);
}
function getNodeExists(address _nodeAddress) override public view returns (bool) {
return getBool(keccak256(abi.encodePacked("node.exists", _nodeAddress)));
}
function getNodeWithdrawalAddress(address _nodeAddress) override public view returns (address) {
return rocketStorage.getNodeWithdrawalAddress(_nodeAddress);
}
function getNodePendingWithdrawalAddress(address _nodeAddress) override public view returns (address) {
return rocketStorage.getNodePendingWithdrawalAddress(_nodeAddress);
}
function getNodeRPLWithdrawalAddress(address _nodeAddress) override public view returns (address) {
address withdrawalAddress = getAddress(keccak256(abi.encodePacked("node.rpl.withdrawal.address", _nodeAddress)));
if (withdrawalAddress == address(0)) {
return rocketStorage.getNodeWithdrawalAddress(_nodeAddress);
}
return withdrawalAddress;
}
function getNodePendingRPLWithdrawalAddress(address _nodeAddress) override public view returns (address) {
return getAddress(keccak256(abi.encodePacked("node.pending.rpl.withdrawal.address", _nodeAddress)));
}
function getNodeRPLWithdrawalAddressIsSet(address _nodeAddress) override external view returns (bool) {
return(getAddress(keccak256(abi.encodePacked("node.rpl.withdrawal.address", _nodeAddress))) != address(0));
}
function unsetRPLWithdrawalAddress(address _nodeAddress) external override onlyRegisteredNode(_nodeAddress) {
bytes32 addressKey = keccak256(abi.encodePacked("node.rpl.withdrawal.address", _nodeAddress));
require(getAddress(addressKey) == msg.sender, "Only a tx from a node's RPL withdrawal address can unset it");
deleteAddress(addressKey);
emit NodeRPLWithdrawalAddressUnset(_nodeAddress, block.timestamp);
}
function setRPLWithdrawalAddress(address _nodeAddress, address _newRPLWithdrawalAddress, bool _confirm) external override onlyRegisteredNode(_nodeAddress) {
require(_newRPLWithdrawalAddress != address(0x0), "Invalid RPL withdrawal address");
address withdrawalAddress = getNodeRPLWithdrawalAddress(_nodeAddress);
require(withdrawalAddress == msg.sender, "Only a tx from a node's RPL withdrawal address can update it");
if (_confirm) {
deleteAddress(keccak256(abi.encodePacked("node.pending.rpl.withdrawal.address", _nodeAddress)));
updateRPLWithdrawalAddress(_nodeAddress, _newRPLWithdrawalAddress);
}
else {
setAddress(keccak256(abi.encodePacked("node.pending.rpl.withdrawal.address", _nodeAddress)), _newRPLWithdrawalAddress);
}
}
function confirmRPLWithdrawalAddress(address _nodeAddress) external override onlyRegisteredNode(_nodeAddress) {
bytes32 pendingKey = keccak256(abi.encodePacked("node.pending.rpl.withdrawal.address", _nodeAddress));
require(getAddress(pendingKey) == msg.sender, "Confirmation must come from the pending RPL withdrawal address");
deleteAddress(pendingKey);
updateRPLWithdrawalAddress(_nodeAddress, msg.sender);
}
function updateRPLWithdrawalAddress(address _nodeAddress, address _newWithdrawalAddress) private {
setAddress(keccak256(abi.encodePacked("node.rpl.withdrawal.address", _nodeAddress)), _newWithdrawalAddress);
emit NodeRPLWithdrawalAddressSet(_nodeAddress, _newWithdrawalAddress, block.timestamp);
}
function getNodeTimezoneLocation(address _nodeAddress) override public view returns (string memory) {
return getString(keccak256(abi.encodePacked("node.timezone.location", _nodeAddress)));
}
function registerNode(string calldata _timezoneLocation) override external onlyLatestContract("rocketNodeManager", address(this)) {
RocketDAOProtocolSettingsNodeInterface rocketDAOProtocolSettingsNode = RocketDAOProtocolSettingsNodeInterface(getContractAddress("rocketDAOProtocolSettingsNode"));
AddressSetStorageInterface addressSetStorage = AddressSetStorageInterface(getContractAddress("addressSetStorage"));
RocketNetworkSnapshotsInterface rocketNetworkSnapshots = RocketNetworkSnapshotsInterface(getContractAddress("rocketNetworkSnapshots"));
require(rocketDAOProtocolSettingsNode.getRegistrationEnabled(), "Rocket Pool node registrations are currently disabled");
require(bytes(_timezoneLocation).length >= 4, "The timezone location is invalid");
setBool(keccak256(abi.encodePacked("node.exists", msg.sender)), true);
setBool(keccak256(abi.encodePacked("node.voting.enabled", msg.sender)), true);
setString(keccak256(abi.encodePacked("node.timezone.location", msg.sender)), _timezoneLocation);
bytes32 nodeIndexKey = keccak256(abi.encodePacked("nodes.index"));
addressSetStorage.addItem(nodeIndexKey, msg.sender);
_initialiseFeeDistributor(msg.sender);
setUint(keccak256(abi.encodePacked("rewards.pool.claim.contract.registered.time", "rocketClaimNode", msg.sender)), block.timestamp);
rocketNetworkSnapshots.push(keccak256(abi.encodePacked("node.count")), uint224(addressSetStorage.getCount(nodeIndexKey)));
rocketNetworkSnapshots.push(keccak256(abi.encodePacked("node.delegate", msg.sender)), uint224(uint160(msg.sender)));
emit NodeRegistered(msg.sender, block.timestamp);
}
function getNodeRegistrationTime(address _nodeAddress) onlyRegisteredNode(_nodeAddress) override public view returns (uint256) {
return getUint(keccak256(abi.encodePacked("rewards.pool.claim.contract.registered.time", "rocketClaimNode", _nodeAddress)));
}
function setTimezoneLocation(string calldata _timezoneLocation) override external onlyLatestContract("rocketNodeManager", address(this)) onlyRegisteredNode(msg.sender) {
require(bytes(_timezoneLocation).length >= 4, "The timezone location is invalid");
setString(keccak256(abi.encodePacked("node.timezone.location", msg.sender)), _timezoneLocation);
emit NodeTimezoneLocationSet(msg.sender, block.timestamp);
}
function getFeeDistributorInitialised(address _nodeAddress) override public view returns (bool) {
RocketNodeDistributorFactoryInterface rocketNodeDistributorFactory = RocketNodeDistributorFactoryInterface(getContractAddress("rocketNodeDistributorFactory"));
address contractAddress = rocketNodeDistributorFactory.getProxyAddress(_nodeAddress);
uint32 codeSize;
assembly {
codeSize := extcodesize(contractAddress)
}
return codeSize > 0;
}
function initialiseFeeDistributor() override external onlyLatestContract("rocketNodeManager", address(this)) onlyRegisteredNode(msg.sender) {
require(!getFeeDistributorInitialised(msg.sender), "Already initialised");
RocketMinipoolManagerInterface rocketMinipoolManager = RocketMinipoolManagerInterface(getContractAddress("rocketMinipoolManager"));
uint256 count = rocketMinipoolManager.getNodeMinipoolCount(msg.sender);
if (count > 0){
uint256 numerator = 0;
for (uint256 i = 0; i < count; ++i) {
RocketMinipoolInterface minipool = RocketMinipoolInterface(rocketMinipoolManager.getNodeMinipoolAt(msg.sender, i));
if (minipool.getStatus() == MinipoolStatus.Staking){
numerator = numerator + minipool.getNodeFee();
}
}
setUint(keccak256(abi.encodePacked("node.average.fee.numerator", msg.sender)), numerator);
}
_initialiseFeeDistributor(msg.sender);
}
function _initialiseFeeDistributor(address _nodeAddress) internal {
RocketNodeDistributorFactoryInterface rocketNodeDistributorFactory = RocketNodeDistributorFactoryInterface(getContractAddress("rocketNodeDistributorFactory"));
rocketNodeDistributorFactory.createProxy(_nodeAddress);
}
function getAverageNodeFee(address _nodeAddress) override external view returns (uint256) {
RocketMinipoolManagerInterface rocketMinipoolManager = RocketMinipoolManagerInterface(getContractAddress("rocketMinipoolManager"));
RocketNodeDepositInterface rocketNodeDeposit = RocketNodeDepositInterface(getContractAddress("rocketNodeDeposit"));
RocketDAOProtocolSettingsMinipoolInterface rocketDAOProtocolSettingsMinipool = RocketDAOProtocolSettingsMinipoolInterface(getContractAddress("rocketDAOProtocolSettingsMinipool"));
uint256[] memory depositSizes = rocketNodeDeposit.getDepositAmounts();
uint256[] memory depositWeights = new uint256[](depositSizes.length);
uint256[] memory depositCounts = new uint256[](depositSizes.length);
uint256 depositWeightTotal;
uint256 totalCount;
uint256 launchAmount = rocketDAOProtocolSettingsMinipool.getLaunchBalance();
for (uint256 i = 0; i < depositSizes.length; ++i) {
depositCounts[i] = rocketMinipoolManager.getNodeStakingMinipoolCountBySize(_nodeAddress, depositSizes[i]);
totalCount = totalCount + depositCounts[i];
}
if (totalCount == 0) {
return 0;
}
for (uint256 i = 0; i < depositSizes.length; ++i) {
depositWeights[i] = (launchAmount - depositSizes[i]) * depositCounts[i];
depositWeightTotal = depositWeightTotal + depositWeights[i];
}
for (uint256 i = 0; i < depositSizes.length; ++i) {
depositWeights[i] = depositWeights[i] * calcBase / depositWeightTotal;
}
uint256 weightedAverage = 0;
for (uint256 i = 0; i < depositSizes.length; ++i) {
if (depositCounts[i] > 0) {
bytes32 numeratorKey;
if (depositSizes[i] == 16 ether) {
numeratorKey = keccak256(abi.encodePacked("node.average.fee.numerator", _nodeAddress));
} else {
numeratorKey = keccak256(abi.encodePacked("node.average.fee.numerator", _nodeAddress, depositSizes[i]));
}
uint256 numerator = getUint(numeratorKey);
weightedAverage = weightedAverage + (numerator * depositWeights[i] / depositCounts[i]);
}
}
return weightedAverage / calcBase;
}
function setRewardNetwork(address _nodeAddress, uint256 _network) override external onlyLatestContract("rocketNodeManager", address(this)) {
address withdrawalAddress = rocketStorage.getNodeWithdrawalAddress(_nodeAddress);
require(withdrawalAddress == msg.sender, "Only a tx from a node's withdrawal address can change reward network");
RocketDAONodeTrustedSettingsRewardsInterface rocketDAONodeTrustedSettingsRewards = RocketDAONodeTrustedSettingsRewardsInterface(getContractAddress("rocketDAONodeTrustedSettingsRewards"));
require(rocketDAONodeTrustedSettingsRewards.getNetworkEnabled(_network), "Network is not enabled");
setUint(keccak256(abi.encodePacked("node.reward.network", _nodeAddress)), _network);
emit NodeRewardNetworkChanged(_nodeAddress, _network);
}
function getRewardNetwork(address _nodeAddress) override public view onlyLatestContract("rocketNodeManager", address(this)) returns (uint256) {
return getUint(keccak256(abi.encodePacked("node.reward.network", _nodeAddress)));
}
function setSmoothingPoolRegistrationState(bool _state) override external onlyLatestContract("rocketNodeManager", address(this)) onlyRegisteredNode(msg.sender) {
RocketDAOProtocolSettingsNodeInterface daoSettingsNode = RocketDAOProtocolSettingsNodeInterface(getContractAddress("rocketDAOProtocolSettingsNode"));
require(daoSettingsNode.getSmoothingPoolRegistrationEnabled(), "Smoothing pool registrations are not active");
bytes32 changeKey = keccak256(abi.encodePacked("node.smoothing.pool.changed.time", msg.sender));
bytes32 stateKey = keccak256(abi.encodePacked("node.smoothing.pool.state", msg.sender));
RocketDAOProtocolSettingsRewardsInterface daoSettingsRewards = RocketDAOProtocolSettingsRewardsInterface(getContractAddress("rocketDAOProtocolSettingsRewards"));
uint256 rewardInterval = daoSettingsRewards.getRewardsClaimIntervalTime();
uint256 lastChange = getUint(changeKey);
require(block.timestamp >= lastChange + rewardInterval, "Not enough time has passed since changing state");
require(getBool(stateKey) != _state, "Invalid state change");
setUint(changeKey, block.timestamp);
setBool(stateKey, _state);
emit NodeSmoothingPoolStateChanged(msg.sender, _state);
}
function getSmoothingPoolRegistrationState(address _nodeAddress) override public view returns (bool) {
return getBool(keccak256(abi.encodePacked("node.smoothing.pool.state", _nodeAddress)));
}
function getSmoothingPoolRegistrationChanged(address _nodeAddress) override external view returns (uint256) {
return getUint(keccak256(abi.encodePacked("node.smoothing.pool.changed.time", _nodeAddress)));
}
function getSmoothingPoolRegisteredNodeCount(uint256 _offset, uint256 _limit) override external view returns (uint256) {
AddressSetStorageInterface addressSetStorage = AddressSetStorageInterface(getContractAddress("addressSetStorage"));
bytes32 nodeKey = keccak256(abi.encodePacked("nodes.index"));
uint256 totalNodes = getNodeCount();
uint256 max = _offset + _limit;
if (max > totalNodes || _limit == 0) { max = totalNodes; }
uint256 count = 0;
for (uint256 i = _offset; i < max; ++i) {
address nodeAddress = addressSetStorage.getItem(nodeKey, i);
if (getSmoothingPoolRegistrationState(nodeAddress)) {
count++;
}
}
return count;
}
function getNodeDetails(address _nodeAddress) override public view returns (NodeDetails memory nodeDetails) {
RocketNodeStakingInterface rocketNodeStaking = RocketNodeStakingInterface(getContractAddress("rocketNodeStaking"));
RocketNodeDepositInterface rocketNodeDeposit = RocketNodeDepositInterface(getContractAddress("rocketNodeDeposit"));
RocketNodeDistributorFactoryInterface rocketNodeDistributorFactory = RocketNodeDistributorFactoryInterface(getContractAddress("rocketNodeDistributorFactory"));
RocketMinipoolManagerInterface rocketMinipoolManager = RocketMinipoolManagerInterface(getContractAddress("rocketMinipoolManager"));
IERC20 rocketTokenRETH = IERC20(getContractAddress("rocketTokenRETH"));
IERC20 rocketTokenRPL = IERC20(getContractAddress("rocketTokenRPL"));
IERC20 rocketTokenRPLFixedSupply = IERC20(getContractAddress("rocketTokenRPLFixedSupply"));
nodeDetails.nodeAddress = _nodeAddress;
nodeDetails.withdrawalAddress = rocketStorage.getNodeWithdrawalAddress(_nodeAddress);
nodeDetails.pendingWithdrawalAddress = rocketStorage.getNodePendingWithdrawalAddress(_nodeAddress);
nodeDetails.exists = getNodeExists(_nodeAddress);
nodeDetails.registrationTime = getNodeRegistrationTime(_nodeAddress);
nodeDetails.timezoneLocation = getNodeTimezoneLocation(_nodeAddress);
nodeDetails.feeDistributorInitialised = getFeeDistributorInitialised(_nodeAddress);
nodeDetails.rewardNetwork = getRewardNetwork(_nodeAddress);
nodeDetails.rplStake = rocketNodeStaking.getNodeRPLStake(_nodeAddress);
nodeDetails.effectiveRPLStake = rocketNodeStaking.getNodeEffectiveRPLStake(_nodeAddress);
nodeDetails.minimumRPLStake = rocketNodeStaking.getNodeMinimumRPLStake(_nodeAddress);
nodeDetails.maximumRPLStake = rocketNodeStaking.getNodeMaximumRPLStake(_nodeAddress);
nodeDetails.ethMatched = rocketNodeStaking.getNodeETHMatched(_nodeAddress);
nodeDetails.ethMatchedLimit = rocketNodeStaking.getNodeETHMatchedLimit(_nodeAddress);
nodeDetails.feeDistributorAddress = rocketNodeDistributorFactory.getProxyAddress(_nodeAddress);
uint256 distributorBalance = nodeDetails.feeDistributorAddress.balance;
RocketNodeDistributorInterface distributor = RocketNodeDistributorInterface(nodeDetails.feeDistributorAddress);
nodeDetails.distributorBalanceNodeETH = distributor.getNodeShare();
nodeDetails.distributorBalanceUserETH = distributorBalance - nodeDetails.distributorBalanceNodeETH;
nodeDetails.minipoolCount = rocketMinipoolManager.getNodeMinipoolCount(_nodeAddress);
nodeDetails.balanceETH = _nodeAddress.balance;
nodeDetails.balanceRETH = rocketTokenRETH.balanceOf(_nodeAddress);
nodeDetails.balanceRPL = rocketTokenRPL.balanceOf(_nodeAddress);
nodeDetails.balanceOldRPL = rocketTokenRPLFixedSupply.balanceOf(_nodeAddress);
nodeDetails.depositCreditBalance = rocketNodeDeposit.getNodeDepositCredit(_nodeAddress);
return nodeDetails;
}
function getNodeAddresses(uint256 _offset, uint256 _limit) override external view returns (address[] memory) {
AddressSetStorageInterface addressSetStorage = AddressSetStorageInterface(getContractAddress("addressSetStorage"));
bytes32 nodeKey = keccak256(abi.encodePacked("nodes.index"));
uint256 totalNodes = getNodeCount();
uint256 max = _offset + _limit;
if (max > totalNodes || _limit == 0) { max = totalNodes; }
address[] memory nodes = new address[](max - _offset);
uint256 total = 0;
for (uint256 i = _offset; i < max; ++i) {
nodes[total] = addressSetStorage.getItem(nodeKey, i);
total++;
}
assembly {
mstore(nodes, total)
}
return nodes;
}
}
文件 19 的 21:RocketNodeManagerInterface.sol
pragma solidity >0.5.0 <0.9.0;
pragma abicoder v2;
import "../../types/NodeDetails.sol";
interface RocketNodeManagerInterface {
struct TimezoneCount {
string timezone;
uint256 count;
}
function getNodeCount() external view returns (uint256);
function getNodeCountPerTimezone(uint256 offset, uint256 limit) external view returns (TimezoneCount[] memory);
function getNodeAt(uint256 _index) external view returns (address);
function getNodeExists(address _nodeAddress) external view returns (bool);
function getNodeWithdrawalAddress(address _nodeAddress) external view returns (address);
function getNodePendingWithdrawalAddress(address _nodeAddress) external view returns (address);
function getNodeRPLWithdrawalAddress(address _nodeAddress) external view returns (address);
function getNodeRPLWithdrawalAddressIsSet(address _nodeAddress) external view returns (bool);
function unsetRPLWithdrawalAddress(address _nodeAddress) external;
function setRPLWithdrawalAddress(address _nodeAddress, address _newRPLWithdrawalAddress, bool _confirm) external;
function confirmRPLWithdrawalAddress(address _nodeAddress) external;
function getNodePendingRPLWithdrawalAddress(address _nodeAddress) external view returns (address);
function getNodeTimezoneLocation(address _nodeAddress) external view returns (string memory);
function registerNode(string calldata _timezoneLocation) external;
function getNodeRegistrationTime(address _nodeAddress) external view returns (uint256);
function setTimezoneLocation(string calldata _timezoneLocation) external;
function setRewardNetwork(address _nodeAddress, uint256 network) external;
function getRewardNetwork(address _nodeAddress) external view returns (uint256);
function getFeeDistributorInitialised(address _nodeAddress) external view returns (bool);
function initialiseFeeDistributor() external;
function getAverageNodeFee(address _nodeAddress) external view returns (uint256);
function setSmoothingPoolRegistrationState(bool _state) external;
function getSmoothingPoolRegistrationState(address _nodeAddress) external returns (bool);
function getSmoothingPoolRegistrationChanged(address _nodeAddress) external returns (uint256);
function getSmoothingPoolRegisteredNodeCount(uint256 _offset, uint256 _limit) external view returns (uint256);
function getNodeDetails(address _nodeAddress) external view returns (NodeDetails memory);
function getNodeAddresses(uint256 _offset, uint256 _limit) external view returns (address[] memory);
}
文件 20 的 21:RocketNodeStakingInterface.sol
pragma solidity >0.5.0 <0.9.0;
interface RocketNodeStakingInterface {
function getTotalRPLStake() external view returns (uint256);
function getNodeRPLStake(address _nodeAddress) external view returns (uint256);
function getNodeETHMatched(address _nodeAddress) external view returns (uint256);
function getNodeETHProvided(address _nodeAddress) external view returns (uint256);
function getNodeETHCollateralisationRatio(address _nodeAddress) external view returns (uint256);
function getNodeRPLStakedTime(address _nodeAddress) external view returns (uint256);
function getNodeEffectiveRPLStake(address _nodeAddress) external view returns (uint256);
function getNodeMinimumRPLStake(address _nodeAddress) external view returns (uint256);
function getNodeMaximumRPLStake(address _nodeAddress) external view returns (uint256);
function getNodeETHMatchedLimit(address _nodeAddress) external view returns (uint256);
function getRPLLockingAllowed(address _nodeAddress) external view returns (bool);
function stakeRPL(uint256 _amount) external;
function stakeRPLFor(address _nodeAddress, uint256 _amount) external;
function setRPLLockingAllowed(address _nodeAddress, bool _allowed) external;
function setStakeRPLForAllowed(address _caller, bool _allowed) external;
function setStakeRPLForAllowed(address _nodeAddress, address _caller, bool _allowed) external;
function getNodeRPLLocked(address _nodeAddress) external view returns (uint256);
function lockRPL(address _nodeAddress, uint256 _amount) external;
function unlockRPL(address _nodeAddress, uint256 _amount) external;
function transferRPL(address _from, address _to, uint256 _amount) external;
function withdrawRPL(uint256 _amount) external;
function withdrawRPL(address _nodeAddress, uint256 _amount) external;
function slashRPL(address _nodeAddress, uint256 _ethSlashAmount) external;
}
文件 21 的 21:RocketStorageInterface.sol
pragma solidity >0.5.0 <0.9.0;
interface RocketStorageInterface {
function getDeployedStatus() external view returns (bool);
function getGuardian() external view returns(address);
function setGuardian(address _newAddress) external;
function confirmGuardian() external;
function getAddress(bytes32 _key) external view returns (address);
function getUint(bytes32 _key) external view returns (uint);
function getString(bytes32 _key) external view returns (string memory);
function getBytes(bytes32 _key) external view returns (bytes memory);
function getBool(bytes32 _key) external view returns (bool);
function getInt(bytes32 _key) external view returns (int);
function getBytes32(bytes32 _key) external view returns (bytes32);
function setAddress(bytes32 _key, address _value) external;
function setUint(bytes32 _key, uint _value) external;
function setString(bytes32 _key, string calldata _value) external;
function setBytes(bytes32 _key, bytes calldata _value) external;
function setBool(bytes32 _key, bool _value) external;
function setInt(bytes32 _key, int _value) external;
function setBytes32(bytes32 _key, bytes32 _value) external;
function deleteAddress(bytes32 _key) external;
function deleteUint(bytes32 _key) external;
function deleteString(bytes32 _key) external;
function deleteBytes(bytes32 _key) external;
function deleteBool(bytes32 _key) external;
function deleteInt(bytes32 _key) external;
function deleteBytes32(bytes32 _key) external;
function addUint(bytes32 _key, uint256 _amount) external;
function subUint(bytes32 _key, uint256 _amount) external;
function getNodeWithdrawalAddress(address _nodeAddress) external view returns (address);
function getNodePendingWithdrawalAddress(address _nodeAddress) external view returns (address);
function setWithdrawalAddress(address _nodeAddress, address _newWithdrawalAddress, bool _confirm) external;
function confirmWithdrawalAddress(address _nodeAddress) external;
}
{
"compilationTarget": {
"contracts/contract/node/RocketNodeManager.sol": "RocketNodeManager"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 15000
},
"remappings": []
}
[{"inputs":[{"internalType":"contract RocketStorageInterface","name":"_rocketStorageAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"node","type":"address"},{"indexed":true,"internalType":"address","name":"withdrawalAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"NodeRPLWithdrawalAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"node","type":"address"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"NodeRPLWithdrawalAddressUnset","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"node","type":"address"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"NodeRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"node","type":"address"},{"indexed":false,"internalType":"uint256","name":"network","type":"uint256"}],"name":"NodeRewardNetworkChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"node","type":"address"},{"indexed":false,"internalType":"bool","name":"state","type":"bool"}],"name":"NodeSmoothingPoolStateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"node","type":"address"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"NodeTimezoneLocationSet","type":"event"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"}],"name":"confirmRPLWithdrawalAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"}],"name":"getAverageNodeFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"}],"name":"getFeeDistributorInitialised","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_offset","type":"uint256"},{"internalType":"uint256","name":"_limit","type":"uint256"}],"name":"getNodeAddresses","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getNodeAt","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNodeCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_offset","type":"uint256"},{"internalType":"uint256","name":"_limit","type":"uint256"}],"name":"getNodeCountPerTimezone","outputs":[{"components":[{"internalType":"string","name":"timezone","type":"string"},{"internalType":"uint256","name":"count","type":"uint256"}],"internalType":"struct RocketNodeManagerInterface.TimezoneCount[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"}],"name":"getNodeDetails","outputs":[{"components":[{"internalType":"bool","name":"exists","type":"bool"},{"internalType":"uint256","name":"registrationTime","type":"uint256"},{"internalType":"string","name":"timezoneLocation","type":"string"},{"internalType":"bool","name":"feeDistributorInitialised","type":"bool"},{"internalType":"address","name":"feeDistributorAddress","type":"address"},{"internalType":"uint256","name":"rewardNetwork","type":"uint256"},{"internalType":"uint256","name":"rplStake","type":"uint256"},{"internalType":"uint256","name":"effectiveRPLStake","type":"uint256"},{"internalType":"uint256","name":"minimumRPLStake","type":"uint256"},{"internalType":"uint256","name":"maximumRPLStake","type":"uint256"},{"internalType":"uint256","name":"ethMatched","type":"uint256"},{"internalType":"uint256","name":"ethMatchedLimit","type":"uint256"},{"internalType":"uint256","name":"minipoolCount","type":"uint256"},{"internalType":"uint256","name":"balanceETH","type":"uint256"},{"internalType":"uint256","name":"balanceRETH","type":"uint256"},{"internalType":"uint256","name":"balanceRPL","type":"uint256"},{"internalType":"uint256","name":"balanceOldRPL","type":"uint256"},{"internalType":"uint256","name":"depositCreditBalance","type":"uint256"},{"internalType":"uint256","name":"distributorBalanceUserETH","type":"uint256"},{"internalType":"uint256","name":"distributorBalanceNodeETH","type":"uint256"},{"internalType":"address","name":"withdrawalAddress","type":"address"},{"internalType":"address","name":"pendingWithdrawalAddress","type":"address"},{"internalType":"bool","name":"smoothingPoolRegistrationState","type":"bool"},{"internalType":"uint256","name":"smoothingPoolRegistrationChanged","type":"uint256"},{"internalType":"address","name":"nodeAddress","type":"address"}],"internalType":"struct NodeDetails","name":"nodeDetails","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"}],"name":"getNodeExists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"}],"name":"getNodePendingRPLWithdrawalAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"}],"name":"getNodePendingWithdrawalAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"}],"name":"getNodeRPLWithdrawalAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"}],"name":"getNodeRPLWithdrawalAddressIsSet","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"}],"name":"getNodeRegistrationTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"}],"name":"getNodeTimezoneLocation","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"}],"name":"getNodeWithdrawalAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"}],"name":"getRewardNetwork","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_offset","type":"uint256"},{"internalType":"uint256","name":"_limit","type":"uint256"}],"name":"getSmoothingPoolRegisteredNodeCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"}],"name":"getSmoothingPoolRegistrationChanged","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"}],"name":"getSmoothingPoolRegistrationState","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialiseFeeDistributor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_timezoneLocation","type":"string"}],"name":"registerNode","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"},{"internalType":"address","name":"_newRPLWithdrawalAddress","type":"address"},{"internalType":"bool","name":"_confirm","type":"bool"}],"name":"setRPLWithdrawalAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"},{"internalType":"uint256","name":"_network","type":"uint256"}],"name":"setRewardNetwork","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_state","type":"bool"}],"name":"setSmoothingPoolRegistrationState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_timezoneLocation","type":"string"}],"name":"setTimezoneLocation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"}],"name":"unsetRPLWithdrawalAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"}]