MetaRegistry
MetaRegistry is a supplementary contract that stores Node Operator metadata and defines operator groups used by CuratedModule for weighted stake allocation. A group assigns shares to its module Node Operators and can reference operators in external staking modules. The registry calculates each grouped Node Operator's effective allocation weight from its Accounting bond curve and its share within the group. Operators outside a group have zero allocation weight.
The contract also stores each Node Operator's name and description and can restrict further metadata edits by the operator owner.
State Variables
MANAGE_OPERATOR_GROUPS_ROLE
bytes32 public constant MANAGE_OPERATOR_GROUPS_ROLE = keccak256("MANAGE_OPERATOR_GROUPS_ROLE")
SET_OPERATOR_INFO_ROLE
bytes32 public constant SET_OPERATOR_INFO_ROLE = keccak256("SET_OPERATOR_INFO_ROLE")
SET_BOND_CURVE_WEIGHT_ROLE
bytes32 public constant SET_BOND_CURVE_WEIGHT_ROLE = keccak256("SET_BOND_CURVE_WEIGHT_ROLE")
NO_GROUP_ID
uint256 public constant NO_GROUP_ID = 0
MODULE
ICuratedModule public immutable MODULE
ACCOUNTING
IAccounting public immutable ACCOUNTING
STAKING_ROUTER
IStakingRouter public immutable STAKING_ROUTER
MAX_BP
uint256 internal constant MAX_BP = 10000
EXTERNAL_STAKE_PER_VALIDATOR
uint256 internal constant EXTERNAL_STAKE_PER_VALIDATOR = 32 ether
MAX_NAME_LENGTH
uint256 internal constant MAX_NAME_LENGTH = 256
MAX_DESCRIPTION_LENGTH
uint256 internal constant MAX_DESCRIPTION_LENGTH = 1024
META_REGISTRY_STORAGE_LOCATION
bytes32 private constant META_REGISTRY_STORAGE_LOCATION =
0xa7ec41e1a061c67796a04fcd9cc7cab9545b0a750beebc54139d9ed9d2251c00
Functions
constructor
constructor(address module) ;
initialize
Initialize the registry.
function initialize(address admin) external initializer;
Parameters
| Name | Type | Description |
|---|---|---|
admin | address | Address to receive DEFAULT_ADMIN_ROLE. |
getInitializedVersion
Returns the initialized version of the contract.
function getInitializedVersion() external view returns (uint64);
setOperatorMetadataAsAdmin
Set or update metadata for a node operator (callable by SET_OPERATOR_INFO_ROLE).
function setOperatorMetadataAsAdmin(uint256 nodeOperatorId, OperatorMetadata calldata metadata)
external
onlyRole(SET_OPERATOR_INFO_ROLE);
Parameters
| Name | Type | Description |
|---|---|---|
nodeOperatorId | uint256 | Node operator ID. |
metadata | OperatorMetadata | Metadata payload to persist. |
setOperatorMetadataAsOwner
Set or update metadata by the node operator owner.
Reverts if module does not support IBaseModule interface.
function setOperatorMetadataAsOwner(uint256 nodeOperatorId, string calldata name, string calldata description)
external;
Parameters
| Name | Type | Description |
|---|---|---|
nodeOperatorId | uint256 | Node operator ID. |
name | string | Display name. |
description | string | Long description. |
createOrUpdateOperatorGroup
Create a new operator group or update an existing one.
Creating is allowed only when groupId == NO_GROUP_ID.
function createOrUpdateOperatorGroup(uint256 groupId, OperatorGroup calldata groupInfo)
external
onlyRole(MANAGE_OPERATOR_GROUPS_ROLE);
Parameters
| Name | Type | Description |
|---|---|---|
groupId | uint256 | Group ID to update, or NO_GROUP_ID to create. |
groupInfo | OperatorGroup | Group definition. |
setBondCurveWeight
Set base weight for the bond curve ID (callable by SET_BOND_CURVE_WEIGHT_ROLE).
Effective weights for operators using the curve will not be updated automatically. refreshOperatorWeight() must be called for the affected operators to update their effective weights.
function setBondCurveWeight(uint256 curveId, uint256 weight) external onlyRole(SET_BOND_CURVE_WEIGHT_ROLE);
Parameters
| Name | Type | Description |
|---|---|---|
curveId | uint256 | Bond curve ID. |
weight | uint256 | Base allocation weight. |
refreshOperatorWeight
Trigger the operator weight update routine in the registry.
function refreshOperatorWeight(uint256 nodeOperatorId) external;
Parameters
| Name | Type | Description |
|---|---|---|
nodeOperatorId | uint256 | Node operator ID to trigger the update for. |
getOperatorMetadata
Get metadata for a node operator.
function getOperatorMetadata(uint256 nodeOperatorId) external view returns (OperatorMetadata memory metadata);
Parameters
| Name | Type | Description |
|---|---|---|
nodeOperatorId | uint256 | Node operator ID. |
Returns
| Name | Type | Description |
|---|---|---|
metadata | OperatorMetadata | Stored metadata struct. |
getOperatorGroup
Fetch an operator group by ID.
function getOperatorGroup(uint256 groupId) external view returns (OperatorGroup memory groupInfo);
Parameters
| Name | Type | Description |
|---|---|---|
groupId | uint256 | Group ID to fetch. |
Returns
| Name | Type | Description |
|---|---|---|
groupInfo | OperatorGroup | Group definition. |
getOperatorGroupsCount
Returns total operator groups count.
function getOperatorGroupsCount() external view returns (uint256 count);
getNodeOperatorGroupId
Get Node Operator group ID (returns NO_GROUP_ID if the operator is not in any group).
function getNodeOperatorGroupId(uint256 nodeOperatorId) external view returns (uint256 operatorGroupId);
Parameters
| Name | Type | Description |
|---|---|---|
nodeOperatorId | uint256 | Node operator ID to query. |
Returns
| Name | Type | Description |
|---|---|---|
operatorGroupId | uint256 | Group ID. |
getExternalOperatorGroupId
Get External Operator group ID (returns NO_GROUP_ID if the operator is not in any group).
function getExternalOperatorGroupId(ExternalOperator calldata op) external view returns (uint256 operatorGroupId);
Parameters
| Name | Type | Description |
|---|---|---|
op | ExternalOperator | External operator. |
Returns
| Name | Type | Description |
|---|---|---|
operatorGroupId | uint256 | Group ID. |
getBondCurveWeight
Returns base weight for the bond curve ID.
function getBondCurveWeight(uint256 curveId) external view returns (uint256 weight);
Parameters
| Name | Type | Description |
|---|---|---|
curveId | uint256 | Bond curve ID. |
Returns
| Name | Type | Description |
|---|---|---|
weight | uint256 | Base allocation weight. |
getNodeOperatorWeight
Returns effective weight for the node operator.
Returns the cached effective weight.
function getNodeOperatorWeight(uint256 nodeOperatorId) external view returns (uint256 weight);
Parameters
| Name | Type | Description |
|---|---|---|
nodeOperatorId | uint256 | Node operator ID to query. |
Returns
| Name | Type | Description |
|---|---|---|
weight | uint256 | Effective allocation weight. |
getNodeOperatorWeightAndExternalStake
Returns effective weight and external stake for the node operator.
Returns (0, 0) if the operator is not in a group.
function getNodeOperatorWeightAndExternalStake(uint256 nodeOperatorId)
external
view
returns (uint256 weight, uint256 externalStake);
Parameters
| Name | Type | Description |
|---|---|---|
nodeOperatorId | uint256 | Node operator ID to query. |
Returns
| Name | Type | Description |
|---|---|---|
weight | uint256 | Effective allocation weight. |
externalStake | uint256 | External stake amount in wei. |
getOperatorWeights
Returns allocation weights for the given node operators.
function getOperatorWeights(uint256[] calldata nodeOperatorIds)
external
view
returns (uint256[] memory operatorWeights);
Parameters
| Name | Type | Description |
|---|---|---|
nodeOperatorIds | uint256[] | Node operator IDs to query. |
Returns
| Name | Type | Description |
|---|---|---|
operatorWeights | uint256[] | Weights aligned with nodeOperatorIds. |
_createGroup
function _createGroup(OperatorGroup calldata groupInfo) internal;
_updateGroup
function _updateGroup(uint256 groupId, OperatorGroup calldata groupInfo) internal;
_storeGroupData
function _storeGroupData(uint256 groupId, OperatorGroup calldata groupInfo) internal;
_resetGroup
function _resetGroup(uint256 groupId) internal;
_setGroupName
function _setGroupName(uint256 groupId, string calldata name) internal;
_storeSubOperators
function _storeSubOperators(uint256 groupId, SubNodeOperator[] calldata subNodeOperators) internal;
_storeExternalOperators
function _storeExternalOperators(uint256 groupId, ExternalOperator[] calldata externalOperators) internal;
_refreshOperatorWeight
noId should be a part of group with groupId.
function _refreshOperatorWeight(uint256 groupId, uint256 noId) internal;
_setEffectiveWeight
function _setEffectiveWeight(uint256 nodeOperatorId, uint256 newWeight) internal returns (uint256 oldWeight);
_storeOperatorMetadata
function _storeOperatorMetadata(uint256 nodeOperatorId, OperatorMetadata memory metadata) internal;
_checkExternalOperatorExistsTypeNOR
function _checkExternalOperatorExistsTypeNOR(ExternalOperator memory op) internal;
_getOrCacheModuleAddress
Returns the module address for moduleId, resolving from
STAKING_ROUTER on cache miss.
function _getOrCacheModuleAddress(uint8 moduleId) internal returns (address addr);
_getLatestEffectiveWeight
function _getLatestEffectiveWeight(uint256 nodeOperatorId, uint256 share) internal view returns (uint256);
_getOperatorBaseWeight
function _getOperatorBaseWeight(uint256 nodeOperatorId) internal view returns (uint256);
_getCachedModuleAddress
Returns the cached module address. Reverts if the address was
never resolved via _getOrCacheModuleAddress.
function _getCachedModuleAddress(uint8 moduleId) internal view returns (address addr);
_onlyExistingOperator
function _onlyExistingOperator(address module, uint256 nodeOperatorId) internal view;
_nodeOperatorExists
function _nodeOperatorExists(address module, uint256 nodeOperatorId) internal view returns (bool);
_nodeOperatorOwner
function _nodeOperatorOwner(address module, uint256 nodeOperatorId) internal view returns (address);
_totalExternalStake
function _totalExternalStake(ExternalOperator[] storage externalOperators)
internal
view
returns (uint256 totalExternalStake);
_getOperatorExternalStakeTypeNOR
function _getOperatorExternalStakeTypeNOR(ExternalOperator memory op) internal view returns (uint256 stake);
_storage
function _storage() internal pure returns (MetaRegistryStorage storage $);
Structs
CachedOperatorGroup
struct CachedOperatorGroup {
string name;
uint64[] subNodeOperatorIds;
ExternalOperator[] externalOperators;
}
GroupIndex
struct GroupIndex {
mapping(uint256 nodeOperatorId => uint256 groupId) groupIdByOperatorId;
mapping(bytes32 externalKey => uint256 groupId) groupIdByExternalKey;
mapping(uint256 nodeOperatorId => uint16 share) shareByOperatorId;
}
EffectiveWeightCache
struct EffectiveWeightCache {
// Invariant: operators outside any group must have zero cached effective weight.
mapping(uint256 nodeOperatorId => uint256 weight) operatorEffectiveWeight;
mapping(uint256 groupId => uint256 weight) groupEffectiveWeightSum;
}
MetaRegistryStorage
Note: storage-location: erc7201:MetaRegistry
struct MetaRegistryStorage {
mapping(uint256 curveId => uint256 weight) bondCurveWeight;
mapping(uint256 groupId => CachedOperatorGroup) groups;
GroupIndex groupIndex;
EffectiveWeightCache effectiveWeightCache;
mapping(uint256 nodeOperatorId => OperatorMetadata) operatorMetadata;
mapping(uint256 moduleId => address moduleAddress) moduleAddressCache;
uint256 groupsCount;
}