NodeOperatorRegistry
Link to NodeOperatorRegistry source code on Ethereum
The NodeOperatorRegistry contract is the core contract that allows node operators to participate in the K9 Finance liquid staking protocol. Node Operators participate on the protocol as validators and get rewarded for their work. A Node Operator gets added to the Registry by the DAO. Validator reward is distributed evenly amongst all active operators. The contract contains a list of operators, their public keys, and the logic for managing their state.
Roles
The NodeOperatorRegistry contract has the following roles
DAO_ROLE
DAO role
PAUSE_ROLE
Allows to pause the contract
UNPAUSE_ROLE
Allows to unpause the contract
ADD_NODE_OPERATOR_ROLE
Allows to add new node operator the contract
REMOVE_NODE_OPERATOR_ROLE
Allows to remove a node operator the contract
Variables
IStakeManager public stakeManager;
- Shibarium stakeManager contract address.
IKnBONE public knBONE;
- knBONE contract address.
bytes32 public constant DAO_ROLE = keccak256("DAO_ROLE");
- dao role identifier.
bytes32 public constant PAUSE_ROLE = keccak256("PAUSE_ROLE");
- pauser role identifier.
bytes32 public constant UNPAUSE_ROLE = keccak256("UNPAUSE_ROLE");
- unpauser role identifier.
bytes32 public constant ADD_NODE_OPERATOR_ROLE =
keccak256("ADD_NODE_OPERATOR_ROLE");
- role identifier of adding node operator authority
bytes32 public constant REMOVE_NODE_OPERATOR_ROLE =
keccak256("REMOVE_NODE_OPERATOR_ROLE");
- role identifier of removing node operator authority.
uint256 public DISTANCE_THRESHOLD_PERCENTS;
- the maximum number (percentage) at which the system considers itself balanced. The distance will be 100 in case where the operator’s minimum stake is equal to the maximum. The distance is calculated as (max * 100) / min
.
uint256 public MAX_WITHDRAW_PERCENTAGE_PER_REBALANCE;
- the maximum percentage that can be withdrawn from the total delegated amount when rebalancing the system.
uint8 public MIN_REQUEST_WITHDRAW_RANGE_PERCENTS;
- a percentage added to the withdrawal percentage when withdrawing from validators. Applicable only when the system is in a balanced state. It is used to “split” the withdrawal between validators.
Does not affect the withdrawal amount.
Example: the total stake of the system is 100 BONE and there are 4 active validators. A user wants to withdraw 10 BONE, i.e. 10%.
totalValidatorToWithdrawFrom =
(((withdrawAmountPercentage + MIN_REQUEST_WITHDRAW_RANGE_PERCENTS) *
length) / 100) +
1;
Without this extra percentage value, user would have withdrawn from one validator:
totalValidatorToWithdrawFrom = (10 + 0) * 4 / 100 + 1 = 1
BUT if this value is applied and suppose it is equal to 15%, then he will withdraw from two validators.
totalValidatorToWithdrawFrom = (10 + 15) * 4 / 100 + 1 = 2
uint256[] public validatorIds;
- IDs of all validators in the protocol
mapping(uint256 => address) public validatorIdToRewardAddress;
- returns rewardAddress for each validator ID
mapping(address => uint256) public validatorRewardAddressToId;
- returns validator ID for each rewardAddress of the validator
Structs
NodeOperatorStatus
Node operator statuses
INACTIVE
When the node operator is INACTIVE
ACTIVE
When the node operator is ACTIVE
JAILED
When the node operator is JAILED
EJECTED
When the node operator is EJECTED
UNSTAKED
When the node operator is UNSTAKED
enum NodeOperatorRegistryStatus {
INACTIVE,
ACTIVE,
JAILED,
EJECTED,
UNSTAKED
}
FullNodeOperatorRegistry
validatorId
Shibarium validator id
commissionRate
The commission rate applied by the validator on Shibarium stakeManager
validatorShare
The validatorShare contract address
rewardAddress
The validator reward address
delegation
The validator delegation status on Shibarium stakeManager
status
The validator status
struct FullNodeOperatorRegistry {
uint256 validatorId;
uint256 commissionRate;
address validatorShare;
address rewardAddress;
bool delegation;
NodeOperatorRegistryStatus status;
}
ValidatorData
The node operator data
validatorShare
The validatorShare contract address of the validator
rewardAddress
The validator reward address
struct ValidatorData {
address validatorShare;
address rewardAddress;
}
Events
event AddNodeOperator(uint256 validatorId, address rewardAddress);
- new validator was added to the protocol
event RemoveNodeOperator(uint256 validatorId, address rewardAddress);
- validator was removed from the protocol
event RemoveInvalidNodeOperator(uint256 validatorId, address rewardAddress);
- an invalid validator was removed from the protocol
event SetKnBONEAddress(address oldKnBONE, address newKnBONE);
- KnBONE contract address is set
event SetRewardAddress(uint256 validatorId, address oldRewardAddress,address newRewardAddress);
- rewardAddress is set for the validator
event SetDistanceThreshold(uint256 oldDistanceThreshold, uint256 newDistanceThreshold);
- DISTANCE_THRESHOLD_PERCENTS is set
event SetMinRequestWithdrawRange(uint8 oldMinRequestWithdrawRange, uint8 newMinRequestWithdrawRange);
- MIN_REQUEST_WITHDRAW_RANGE_PERCENTS is set
event SetMaxWithdrawPercentagePerRebalance(uint256 oldMaxWithdrawPercentagePerRebalance, uint256 newMaxWithdrawPercentagePerRebalance);
- MAX_WITHDRAW_PERCENTAGE_PER_REBALANCE is set
event ExitNodeOperator(uint256 validatorId, address rewardAddress);
- the validator removed himself from the protocol
View functions
listDelegatedNodeOperators
function listDelegatedNodeOperators()
external
view
returns (ValidatorData[] memory)
Returns an array of structures ValidatorData for all validators whose status ACTIVE and whose ValidatorShare.delegation() returns true.
listWithdrawNodeOperators
function listWithdrawNodeOperators()
external
view
returns (ValidatorData[] memory)
Returns an array of ValidatorData structures for all validators whose status is not INACTIVE.
getValidatorsDelegationAmount
function getValidatorsDelegationAmount(uint256 _amountToDelegate)
external
view
returns (
ValidatorData[] memory validators,
uint256[] memory operatorRatiosToDelegate,
uint256 totalRatio
)
Calculate how totalBuffered should be delegated between the active validators, depending on if the system is balanced or not:
If the system is balanced - returns a list of validators with zeros.
If the system is not balanced - returns a list of validators, a list of shares and the total amount of shares, how to delegate these shares to validators.
getValidatorsRebalanceAmount
function getValidatorsRebalanceAmount(uint256 _amountToReDelegate)
external
view
returns (
ValidatorData[] memory validators,
uint256[] memory operatorRatiosToRebalance,
uint256 totalRatio,
uint256 totalToWithdraw
)
Calculate how the system could be rebalanced depending on the current buffered tokens. This function utilizes MAX_WITHDRAW_PERCENTAGE_PER_REBALANCE.
If the system is not balanced, it will return
a list of validators
how many shares to withdraw from them
the sum of shares
the amount to withdraw that corresponds to the sum of shares.
getValidatorsRequestWithdraw
function _getValidatorsRequestWithdraw()
private
view
returns (
ValidatorData[] memory activeValidators,
uint256[] memory stakePerOperator,
uint256 totalDelegated,
uint256 minAmount,
uint256 maxAmount
)
Depending on whether the system is balanced and the amount to withdraw, it returns a list of validators the system can withdraw from:
list of validators
how much is delegated
IDs of those who have delegated more than the average
IDs of those who have delegated less than average
how much can be withdrawn from each validator if the system is not balanced
how many validators can be withdrawn from if the system is balanced
getNodeOperator
function getNodeOperator(uint256 _validatorId)
external
view
returns (FullNodeOperatorRegistry memory nodeOperator)
Returns the validator information by ID.
getNodeOperator
function getNodeOperator(address _rewardAddress)
external
view
returns (FullNodeOperatorRegistry memory nodeOperator)
Returns the validator information by rewardAddress.
getNodeOperatorStatus
function getNodeOperatorStatus(uint256 _validatorId)
external
view
returns (NodeOperatorRegistryStatus operatorStatus)
Returns operator status according to ID.
getValidatorIds
function getValidatorIds()
external
view
returns (uint256[] memory)
Return a list of all validator ids in the system.
getProtocolStats
function getProtocolStats()
external
view
returns (
bool isBalanced,
uint256 distanceMinMaxStake,
uint256 minAmount,
uint256 maxAmount
)
Return the statistics about the protocol as a list:
whether the system is balanced
the distance between the maximum and minimum validator stake
minimum validator stake
maximum validator stake
getStats
function getStats()
external
view
returns (
uint256 inactiveNodeOperator,
uint256 activeNodeOperator,
uint256 jailedNodeOperator,
uint256 ejectedNodeOperator,
uint256 unstakedNodeOperator
)
Returns the number of operators for each status.
Methods
initialize
function initialize(
IStakeManager _stakeManager,
IKnBONE _knBONE,
address _dao
) external initializer
Initializer function, not called after initialization.
exitNodeOperatorRegistry
function exitNodeOperatorRegistry() external nonReentrant
Exit the node operator registry. ONLY the owner of the node operator can call this function.
removeInvalidNodeOperator
function removeInvalidNodeOperator(uint256 _validatorId)
external
whenNotPaused
nonReentrant
Remove a node operator from the system if the Node Operator is either Unstaked or Ejected.
setRewardAddress
function setRewardAddress(address _newRewardAddress)
external
whenNotPaused
Update the reward address of a Node Operator. ONLY Operator owner can call this function
Admin Methods
pause
function pause() external onlyRole(PAUSE_ROLE)
Allows an authorized user with PAUSE ROLE
to pause the NodeOperatorRegistry contract.
unpause
function unpause() external onlyRole(UNPAUSE_ROLE)
Allows an authorized user with UNPAUSE ROLE
to unpause the NodeOperatorRegistry contract.
DAO Methods
addNodeOperator
function addNodeOperator(uint256 _validatorId, address _rewardAddress)
external
onlyRole(ADD_NODE_OPERATOR_ROLE)
nonReentrant
Add a new node operator to the system.
removeNodeOperator
function removeNodeOperator(uint256 _validatorId)
external
onlyRole(REMOVE_NODE_OPERATOR_ROLE)
nonReentrant
Remove a node operator from the system and withdraw total delegated tokens to it. ONLY DAO can execute this function.
setKnBONEAddress
function setKnBONEAddress(address _newKnBONE)
external
onlyRole(DAO_ROLE)
Allows the DAO to set the knBONE contract address.
setDistanceThreshold
function setDistanceThreshold(uint256 _newDistanceThreshold)
external
onlyRole(DAO_ROLE)
Allows the DAO to set the distance threshold for balancing the system.
setMinRequestWithdrawRange
function setMinRequestWithdrawRange(
uint8 _newMinRequestWithdrawRangePercents
) external onlyRole(DAO_ROLE)
Allows the DAO to set the minimum request withdraw range to keep the system balanced
setMaxWithdrawPercentagePerRebalance
setMaxWithdrawPercentagePerRebalance(
uint256 _newMaxWithdrawPercentagePerRebalance
) external onlyRole(DAO_ROLE)
Allows the DAO to set the maximum withdraw percentage per balance of each validator
Last updated