Skip to content

feat: stake cap - #860

Draft
vgorkavenko wants to merge 6 commits into
phase-2from
feat/stake-limit
Draft

feat: stake cap#860
vgorkavenko wants to merge 6 commits into
phase-2from
feat/stake-limit

Conversation

@vgorkavenko

@vgorkavenko vgorkavenko commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Description

Stake cap per Node Operator (initial deposit, Top-Up)

Checklist

  • Appropriate PR labels applied
  • Test coverage maintained (just coverage)
    • Tests are added/updated
  • Documentation maintained
    • Updated

@vgorkavenko
vgorkavenko force-pushed the feat/stake-limit branch 2 times, most recently from afdfb97 to f03ba6d Compare July 29, 2026 13:12
@vgorkavenko
vgorkavenko changed the base branch from feat/custom-fees to phase-2 July 29, 2026 13:12
@vgorkavenko
vgorkavenko marked this pull request as ready for review July 30, 2026 08:22
@vgorkavenko
vgorkavenko requested a review from a team as a code owner July 30, 2026 08:22

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f43ab09068

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread script/curated/DeployBase.s.sol Outdated
Comment thread src/interfaces/IMetaRegistry.sol

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 25a79842d0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/MetaRegistry.sol
Comment thread src/MetaRegistry.sol Outdated
currentStakeByOperatorId = new uint256[](operatorsCount);

IMetaRegistry metaRegistry = ICuratedModule(address(this)).META_REGISTRY();
uint256 stakeCap = metaRegistry.maximumStakeCapPerNodeOperator();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maximum and cap have similar meaning

Suggested change
uint256 stakeCap = metaRegistry.maximumStakeCapPerNodeOperator();
uint256 stakeCap = metaRegistry.maximumStakePerNodeOperator();

Comment thread src/interfaces/IMetaRegistry.sol Outdated
event GroupWeightsRefreshed(uint256 indexed groupId);
event OperatorMetadataSet(uint256 indexed nodeOperatorId, OperatorMetadata metadata);
event NodeOperatorEffectiveWeightChanged(uint256 indexed nodeOperatorId, uint256 oldWeight, uint256 newWeight);
event MaximumStakeCapPerNodeOperatorSet(uint256 previousCap, uint256 newCap);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'per node operator' sounds like it's related to a specific node operator, and I don't get why we need Maximum if it's a cap already, so I'd suggest just StakeCapSet here and update the method names as well.

Comment thread src/CuratedModule.sol
Comment on lines 233 to 247
if (newCount > 0) {
uint256 weight = _metaRegistry().getNodeOperatorWeight(nodeOperatorId);
IMetaRegistry metaRegistry = _metaRegistry();
uint256 weight = metaRegistry.getNodeOperatorWeight(nodeOperatorId);
if (weight == 0) newCount = 0;

if (newCount > 0) {
uint256 cap = metaRegistry.maximumStakeCapPerNodeOperator();
uint256 currentStake = StakeTracker.getOperatorBalance(_baseStorage(), nodeOperatorId);
uint256 capCapacity;
if (currentStake < cap) {
capCapacity = (cap - currentStake) / ValidatorBalanceLimits.MIN_ACTIVATION_BALANCE;
}
if (newCount > capCapacity) newCount = capCapacity;
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels like it can be a separate function, might be a bit cleaner then.

Comment thread src/CuratedModule.sol Outdated
uint256 currentStake = StakeTracker.getOperatorBalance(_baseStorage(), nodeOperatorId);
uint256 capCapacity;
if (currentStake < cap) {
capCapacity = (cap - currentStake) / ValidatorBalanceLimits.MIN_ACTIVATION_BALANCE;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it should be MAX_EB instead? But the granularity might be off and we need ceil div.

Comment thread src/MetaRegistry.sol Outdated
}

function _setMaximumStakeCapPerNodeOperator(uint256 newCap) internal {
if (newCap == 0 || newCap % 1 ether != 0) revert InvalidStakeCap();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's make it a multiple of MEB.

Comment thread src/CuratedModule.sol Outdated
}

/// @inheritdoc IBaseModule
function reportValidatorBalance(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be tricky when the method is gone, we might have some unaccounted diff <2 ether. I think it's another argument to consider validator count approach suggested below.

Comment thread src/CuratedModule.sol Outdated

if (newCount > 0) {
uint256 cap = metaRegistry.maximumStakeCapPerNodeOperator();
uint256 currentStake = StakeTracker.getOperatorBalance(_baseStorage(), nodeOperatorId);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can compare validators instead. Like cap / MEB - deposited. And we would not need to update depositable validators every time the operator balance changes.

@vgorkavenko
vgorkavenko marked this pull request as draft July 31, 2026 09:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants