Skip to content

Conversation

@juliaaschmidt
Copy link
Contributor

@juliaaschmidt juliaaschmidt commented Feb 5, 2026

This pull request introduces a significant refactor to the validator allocation and selection logic across the OperatorsRegistryV1, RiverV1, and ConsensusLayerDepositManagerV1 contracts. The main change is moving from a simple count-based approach for validator selection to an explicit operator allocation model, where allocations specify how many validators each operator should provide. This enhances flexibility and control over validator distribution and includes new validation checks and error handling.

The most important changes are:

Operator Allocation Refactor

  • Introduced the OperatorAllocation struct to represent explicit allocations of validators per operator, and updated all relevant interfaces and methods to use this model instead of a single count parameter. (IOperatorsRegistryV1, OperatorsRegistryV1, RiverV1, ConsensusLayerDepositManagerV1) [1] [2] [3] [4] [5] [6] [7] [8] [9]

  • Updated the internal selection logic in OperatorsRegistryV1 to process and validate operator allocations, ensuring allocations are ordered, non-zero, and do not exceed available keys. Removed the previous round-robin and max-attribution logic, replacing it with direct allocation checks. [1] [2] [3] [4]

Validation and Error Handling

  • Added new error types for invalid allocations, including unordered operator lists, allocations with zero validator count, and requests exceeding available keys. These errors are now thrown during allocation processing. [1] [2] [3]

  • In ConsensusLayerDepositManagerV1, added validation to ensure the sum of all allocations does not exceed the committed balance and that the number of provided public keys matches the requested allocations.

Interface and Import Updates

  • Updated all relevant interfaces (IOperatorsRegistryV1, IConsensusLayerDepositManagerV1) and imports to support the new allocation-based logic. [1] [2] [3] [4]

These changes collectively provide a more robust and flexible system for validator selection and attribution, improving both control and safety in validator management.## Description

Notice

  • Have you checked to ensure there aren't other open Pull Requests for the same update/change?
  • Have you assigned this PR to yourself?
  • Have you added at least 1 reviewer?
  • Have you updated the official documentation?
  • Have you added sufficient documentation in your code?
  • Have you added relevant tests to the official test suite?

Pull Request Type

  • 💫 New Feature (Breaking Change)
  • 💫 New Feature (Non-breaking Change)
  • 🛠️ Bug fix (Non-breaking Change: Fixes an issue)
  • 🕹️ Chore (Non-breaking Change: Doc updates, pkg upgrades, typos, etc..)

Breaking changes (if applicable)

Testing

  • Have you tested this code with the official test suite?
  • Have you tested this code manually?

Manual tests (if applicable)

Additional comments

Summary by CodeRabbit

Release Notes

  • New Features

    • Deposit operations now accept per-operator validator allocations instead of a single count, enabling more granular validator distribution control.
    • Added comprehensive validation for allocations, including operator ordering, non-zero validator counts, and capacity verification.
  • Bug Fixes

    • Enhanced error handling with specific messages for allocation-related validation failures.

…it loop

- Validate allocation operator indices are in ascending order
- Use unchecked increment in deposit loop for gas savings
- Update natspec for getNextValidatorsToDepositFromActiveOperators
Add scenario 6 to mock that returns half of requested keys and
test that InvalidPublicKeyCount() is thrown when registry returns
fewer keys than requested.
Test that OperatorAllocationsExceedCommittedBalance() is thrown when
total requested validators exceed the maximum that can be funded.
… requested

Add scenario 7 to mock that returns 4 keys regardless of request and
test that InvalidPublicKeyCount() is thrown when registry returns
more keys than requested but within maxDepositableCount.
@coderabbitai
Copy link

coderabbitai bot commented Feb 5, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR refactors the validator allocation system from accepting single count parameters to accepting arrays of operator-specific allocations, enabling per-operator distribution control. The change affects core registry functions, consensus layer deposits, River protocol, and their corresponding tests and Certora verification specs.

Changes

Cohort / File(s) Summary
Interface Definitions
contracts/src/interfaces/IOperatorRegistry.1.sol, contracts/src/interfaces/components/IConsensusLayerDepositManager.1.sol
Introduced OperatorAllocation struct and new error types (OperatorDoesNotHaveEnoughFundableKeys, AllocationWithZeroValidatorCount, OperatorAllocationsExceedCommittedBalance). Updated function signatures to accept OperatorAllocation[] instead of uint256 count parameters for validator distribution.
Core Implementation
contracts/src/OperatorsRegistry.1.sol, contracts/src/River.1.sol, contracts/src/components/ConsensusLayerDepositManager.1.sol
Changed getNextValidatorsToDepositFromActiveOperators, pickNextValidatorsToDeposit, and _getNextValidators to accept OperatorAllocation[] arrays. Added per-allocation validation (ordering, non-zero counts, availability checks). Updated deposit flow to compute allocations from per-operator specifications and enforced committed balance constraints.
Test Scaffolding & Helpers
contracts/test/Firewall.t.sol, contracts/test/OperatorsRegistry.1.t.sol, contracts/test/River.1.t.sol, contracts/test/components/ConsensusLayerDepositManager.1.t.sol
Added allocation helper functions (_createAllocation, _createMultiAllocation) and refactored all test cases to use the new allocation-based API. Expanded test coverage for edge cases: empty/zero allocations, inactive operators, duplicated/unordered indices, and per-operator limits.
Library Test Coverage
contracts/test/state/operatorsRegistry/Operators.1.t.sol
New comprehensive test suite for OperatorsV1 library with public harness exposing internal functions (push, get, setKeys, getAllFundable, hasFundableKeys) and extensive validation tests for fundability logic and error conditions.
Certora Configuration
certora/conf/OperatorRegistryV1.conf, certora/conf/RedeemManagerV1.conf, certora/conf/RiverV1.conf, certora/conf/SharesManagerV1.conf, certora/confs_for_CI/RedeemManagerV1.conf
Added solc_via_ir: true and solc_optimize: "200" compiler settings. Replaced OperatorsRegistry contract references with OperatorsRegistryV1Harness in verification configs.
Certora Specifications
certora/specs/Base.spec, certora/specs/OperatorRegistryV1.spec, certora/specs/OperatorRegistryV1_base.spec, certora/specs/OperatorRegistryV1_finishedRules.spec, certora/specs/OperatorRegistryV1_orig.spec, certora/specs/SharesManagerV1.spec, certora/specs_for_CI/OperatorRegistryV1_for_CI_3.spec, certora/specs_for_CI/River_base.spec
Updated function signatures to reflect new OperatorAllocation[] parameters. Replaced scalar count constraints with .length\-based array bounds in preserved clauses and invariants. Adjusted method selectors and dispatcher rules to match new signatures.
Harness
certora/harness/OperatorsRegistryV1Harness.sol
Removed getMaxValidatorAttributionPerRound() function; refactored loop increments to pre\-increment style.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • mischat
  • iamsahu

Poem

🐰 Hop skip jump, allocations now flow,
Per-operator wisdom in arrays we sow,
From counts we bounded, to distributions precise,
Validators find homes—a reallocation so nice!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(BS-2349) BYOV Deposit Flow' is concise and directly describes the main change—a refactor introducing a BYOV (Bring Your Own Validator) deposit flow. It clearly indicates a new feature related to BS-2349.
Description check ✅ Passed The PR description comprehensively covers the operator allocation refactor, validation changes, and interface updates. It includes checked items for testing and PR requirements, though 'official documentation' update remains unchecked.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/byov-v1-clean

Comment @coderabbitai help to get the list of available commands and usage tips.

@juliaaschmidt juliaaschmidt self-assigned this Feb 5, 2026
@codecov
Copy link

codecov bot commented Feb 5, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.43%. Comparing base (8979802) to head (19c9f43).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #339   +/-   ##
=======================================
  Coverage   97.42%   97.43%           
=======================================
  Files          78       78           
  Lines        2327     2336    +9     
  Branches      255      261    +6     
=======================================
+ Hits         2267     2276    +9     
  Misses         59       59           
  Partials        1        1           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@juliaaschmidt
Copy link
Contributor Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Feb 5, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@juliaaschmidt juliaaschmidt added enhancement New feature or request and removed enhancement New feature or request labels Feb 5, 2026
Add tests for UnorderedOperatorList and AllocationWithZeroValidatorCount
error cases in depositToConsensusLayerWithDepositRoot to ensure invalid
operator allocations are properly rejected.
Add tests for AllocationWithZeroValidatorCount and InactiveOperator
error cases in getNextValidatorsToDepositFromActiveOperators and
pickNextValidatorsToDeposit functions.
Add test that triggers the early return path in
getNextValidatorsToDepositFromActiveOperators when fundableOperatorCount
is zero, ensuring empty arrays are returned correctly.
Add tests that allocate validators to non-first operators in the fundable
array, ensuring the _updateCountOfPickedValidatorsForEachOperator loop
iterates past non-matching operators before finding the target. This improves
branch coverage for line 738's condition check.
@juliaaschmidt juliaaschmidt marked this pull request as ready for review February 5, 2026 23:38
…tiple fundable operators

Improves branch coverage for _updateCountOfPickedValidatorsForEachOperator
loop by testing the scenario where multiple operators exist in the fundable
array but the requested operator doesn't exist, forcing the loop to iterate
through all operators with false condition before reverting.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@contracts/test/components/ConsensusLayerDepositManager.1.t.sol`:
- Around line 141-147: The test testDepositAllocationFailsWithNotEnoughFunds
uses _createAllocation(0) which will trigger AllocationWithZeroValidatorCount()
before NotEnoughFunds(); update the test to use a non-zero validator allocation
(e.g., _createAllocation(1)) so it exercises the insufficient-funds path and
keeps vm.expectRevert(abi.encodeWithSignature("NotEnoughFunds()")) valid against
depositToConsensusLayerWithDepositRoot on depositManager, or alternatively
change the expected revert to AllocationWithZeroValidatorCount() if the
zero-count case is intended.
🧹 Nitpick comments (3)
contracts/test/OperatorsRegistry.1.t.sol (3)

112-134: Type inconsistency between helper functions.

_createAllocation accepts uint256 count while _createMultiAllocation accepts uint32[] counts. This inconsistency can cause confusion when writing tests. Consider aligning the types:

Suggested improvement
-    function _createAllocation(uint256 opIndex, uint256 count)
+    function _createAllocation(uint256 opIndex, uint32 count)
         internal
         pure
         returns (IOperatorsRegistryV1.OperatorAllocation[] memory)
     {
         IOperatorsRegistryV1.OperatorAllocation[] memory allocations = new IOperatorsRegistryV1.OperatorAllocation[](1);
         allocations[0] = IOperatorsRegistryV1.OperatorAllocation({operatorIndex: opIndex, validatorCount: count});
         return allocations;
     }

122-134: Consider adding array length validation.

If opIndexes and counts have different lengths, the loop will either revert with an unclear out-of-bounds error or silently ignore extra elements. Adding an explicit check improves test debugging.

Suggested improvement
     function _createMultiAllocation(uint256[] memory opIndexes, uint32[] memory counts)
         internal
         pure
         returns (IOperatorsRegistryV1.OperatorAllocation[] memory)
     {
+        require(opIndexes.length == counts.length, "Array length mismatch");
         IOperatorsRegistryV1.OperatorAllocation[] memory allocations =
             new IOperatorsRegistryV1.OperatorAllocation[](opIndexes.length);

1705-1725: Duplicate helper functions with inconsistent naming.

These helpers duplicate the functionality from OperatorsRegistryV1Tests (lines 112-134) but with different semantics:

  • Here, _createAllocation takes arrays (like _createMultiAllocation in the other contract)
  • _createMultiAllocation is just a pass-through wrapper

Consider extracting these helpers into a shared base contract to avoid duplication and naming confusion:

Suggested refactor
abstract contract AllocationTestHelpers {
    function _createSingleAllocation(uint256 opIndex, uint32 count)
        internal
        pure
        returns (IOperatorsRegistryV1.OperatorAllocation[] memory)
    {
        IOperatorsRegistryV1.OperatorAllocation[] memory allocations = new IOperatorsRegistryV1.OperatorAllocation[](1);
        allocations[0] = IOperatorsRegistryV1.OperatorAllocation({operatorIndex: opIndex, validatorCount: count});
        return allocations;
    }

    function _createMultiAllocation(uint256[] memory opIndexes, uint32[] memory counts)
        internal
        pure
        returns (IOperatorsRegistryV1.OperatorAllocation[] memory)
    {
        require(opIndexes.length == counts.length, "Array length mismatch");
        IOperatorsRegistryV1.OperatorAllocation[] memory allocations =
            new IOperatorsRegistryV1.OperatorAllocation[](opIndexes.length);
        for (uint256 i = 0; i < opIndexes.length; ++i) {
            allocations[i] =
                IOperatorsRegistryV1.OperatorAllocation({operatorIndex: opIndexes[i], validatorCount: counts[i]});
        }
        return allocations;
    }
}

Then have both test contracts inherit from AllocationTestHelpers.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
certora/specs/OperatorRegistryV1ValidatorStates.spec (1)

450-462: ⚠️ Potential issue | 🟠 Major

Fix inconsistent validator state accessor and argument type.

getValidatorStateByIndex likely expects (opIndex, valIndex), but this rule passes validatorData (bytes) and still uses getValidatorState for stateBefore, making the before/after comparison inconsistent or ill‑typed. If the intent is index-based, add valIndex with bounds and use the same accessor both times.

🛠️ Proposed fix (index-based, consistent before/after)
 rule validatorStateTransition_4_3_M13(method f, env e, calldataarg args) filtered 
     { f -> isMethodID(f, 13) }
 {
     require isValidState();
-    bytes validatorData;
-    uint opIndex;
+    uint opIndex; uint valIndex;
     require operatorStateIsValid(opIndex);  //key <= limit <= funded <= exited
     require getKeysCount(opIndex) <= 4; //should not be higher than loop_iter 
-    uint stateBefore = getValidatorState(opIndex, validatorData);
+    require isValIndexInBounds(opIndex, valIndex);
+    uint stateBefore = getValidatorStateByIndex(opIndex, valIndex);
     f(e, args);
-    uint stateAfter = getValidatorStateByIndex(opIndex, validatorData);
+    uint stateAfter = getValidatorStateByIndex(opIndex, valIndex);
     assert (stateAfter == 4) =>
         (stateBefore == 3 || stateBefore == 4);
 }

@juliaaschmidt juliaaschmidt changed the title feat: BYOV Core Deposit Changes feat: BYOV Core Deposit Changes [BS-2349] Feb 6, 2026
@juliaaschmidt juliaaschmidt changed the title feat: BYOV Core Deposit Changes [BS-2349] feat(BS-2349) BYOV Core Deposit Changes Feb 6, 2026
…y.1.sol

Add 10 new tests covering BYOV allocation logic:
- OperatorDoesNotHaveEnoughFundableKeys with partial funding
- InactiveOperator when operator exists but deactivated
- FundedValidatorKeys event emission
- Multi-operator allocation key ordering
- Sequential allocations to same operator
- Allocation when operator fully funded
- View vs state-modifying behavior
- Multi-operator with partial funding
- Multi-operator second operator exceeds limit
- Pick returns empty when no fundable operators
@juliaaschmidt juliaaschmidt changed the title feat(BS-2349) BYOV Core Deposit Changes feat(BS-2349) BYOV Deposit Flow Feb 6, 2026
…340)

* fix(certora): update pickNextValidatorsToDeposit signature for BYOV

Update Certora specs to reflect the new function signature that takes
OperatorAllocation[] instead of uint256 count. Also removes the unused
getMaxValidatorAttributionPerRound harness function.

* fix(certora): update depositToConsensusLayerWithDepositRoot signature

Update function signature from (uint256, bytes32) to
(OperatorAllocation[], bytes32) to match the BYOV deposit changes.

* fix(certora): add via-ir compilation and update config for BYOV

Add solc_via_ir and optimizer settings to resolve stack-too-deep errors.
Update configs to use OperatorsRegistryV1Harness for proper type resolution
with the new OperatorAllocation struct parameter types.

* bug-fix: add solc_via_ir to CI config files where needed

* fix(certora): update pickNextValidatorsToDeposit call sites to use OperatorAllocation[]

Update rule call sites in startingValidatorsDecreasesDiscrepancy and
witness4_3StartingValidatorsDecreasesDiscrepancy to pass
IOperatorsRegistryV1.OperatorAllocation[] instead of uint count,
matching the new function signature.

* fix(certora): add missing loop increment in getValidatorState harness

The loop in getValidatorState was missing the valIndex increment,
causing it to only ever check index 0 and potentially infinite loop.

* bug-fix: see if removing via ir fixes rule bug

---------

Co-authored-by: juliaaschmidt <[email protected]>
Co-authored-by: juuliaaschmidt <[email protected]>
Copy link
Member

@mischat mischat left a comment

Choose a reason for hiding this comment

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

Some comments from my initial review ... we will over the operator's registry again tomorrow.

@github-actions
Copy link

github-actions bot commented Feb 11, 2026

Changes to gas cost

Generated at commit: f078743b9aef4c58b7285ce72adb12f3b4dee4ae, compared to commit: 8979802586a4f5d1d86f9667fae99dc173943296

🧾 Summary (99% most significant diffs)

Contract Method Avg (+/-) %
OperatorsRegistryInitializableV1 addOperator
debugGetNextValidatorsToExitFromActiveOperators
getCurrentValidatorExitsDemand
getNextValidatorsToDepositFromActiveOperators
getOperatorCount
getRiver
getTotalStoppedValidatorCount
initOperatorsRegistryV1
pickNextValidatorsToDeposit
removeValidators
reportStoppedValidatorCounts
setOperatorAddress
setOperatorName
sudoSetKeys
version
-454 ✅
-22 ✅
-22 ✅
-391,587 ✅
+22 ❌
-22 ✅
+89 ❌
+201 ❌
-167,801 ✅
+19 ❌
-2,771 ✅
0 ➖
-22 ✅
+22 ❌
-22 ✅
-0.37%
-0.02%
-0.86%
-77.03%
+0.84%
-0.86%
+1.82%
+0.21%
-28.90%
+0.01%
-1.72%
0.00%
-0.06%
+0.07%
-3.57%
ConsensusLayerDepositManagerV1ControllableValidatorKeyRequest depositToConsensusLayerWithDepositRoot
publicConsensusLayerDepositManagerInitializeV1
setKeeper
-29,378 ✅
+22 ❌
-4 ✅
-24.38%
+0.02%
-0.01%
RiverV1ForceCommittable claimRedeemRequests
deposit
depositAndTransfer
depositToConsensusLayerWithDepositRoot
getAllowlist
getOperatorsRegistry
getReportBounds
requestRedeem
resolveRedeemRequests
sendCoverageFunds
setDailyCommittableLimits
setMetadataURI
transfer
+31,013 ❌
+22 ❌
+22 ❌
-157,301 ✅
+24 ❌
+22 ❌
+56 ❌
+18 ❌
-2,573 ✅
+22 ❌
+25 ❌
+133 ❌
+22 ❌
+1.64%
+0.03%
+0.02%
-11.12%
+1.53%
+0.85%
+1.15%
+0.01%
-0.10%
+0.09%
+0.07%
+0.27%
+0.06%
UserFactory _newMulti +241,490 ❌ +4.27%
RedeemManagerV1 claimRedeemRequests(uint32[],uint32[])
requestRedeem(uint256)
requestRedeem(uint256,address)
-28,719 ✅
+26 ❌
0 ➖
-3.86%
+0.01%
0.00%
OperatorsRegistryWithOverridesV1 addOperator
getOperatorCount
getStoppedAndRequestedExitCounts
initOperatorsRegistryV1
+17 ❌
+22 ❌
-22 ✅
-22 ✅
+0.01%
+0.85%
-1.45%
-0.02%
Firewall fallback -980 ✅ -1.54%
OracleV1 addMember
reportConsensusLayerData
-2,490 ✅
-2,362 ✅
-1.00%
-0.97%
OperatorsRegistryV1 getOperatorCount
initOperatorsRegistryV1
initOperatorsRegistryV1_1
+22 ❌
-22 ✅
+22 ❌
+0.86%
-0.02%
+0.01%
ConsensusLayerDepositManagerV1ValidKeys depositToConsensusLayerWithDepositRoot
publicConsensusLayerDepositManagerInitializeV1
+1,076 ❌
+22 ❌
+0.69%
+0.02%
ConsensusLayerDepositManagerV1ExposeInitializer depositToConsensusLayerWithDepositRoot
publicConsensusLayerDepositManagerInitializeV1
+955 ❌
+22 ❌
+0.27%
+0.02%
OracleManagerV1ExposeInitializer setCLSpec 0 ➖ 0.00%
CoverageFundV1 donate
pullCoverageFunds
-17 ✅
+1 ❌
-0.03%
+0.00%
AllowlistV1Sudo setAllower
setDenier
0 ➖
0 ➖
0.00%
0.00%

Full diff report 👇
Contract Deployment Cost (+/-) Method Min (+/-) % Avg (+/-) % Median (+/-) % Max (+/-) % # Calls (+/-)
OperatorsRegistryInitializableV1 4,984,549 (+172,180) addOperator
addValidators
debugGetNextValidatorsToExitFromActiveOperators
getCurrentValidatorExitsDemand
getNextValidatorsToDepositFromActiveOperators
getOperator
getOperatorCount
getRiver
getStoppedValidatorCountPerOperator
getTotalStoppedValidatorCount
initOperatorsRegistryV1
listActiveOperators
pickNextValidatorsToDeposit
removeValidators
reportStoppedValidatorCounts
setOperatorAddress
setOperatorLimits
setOperatorName
setOperatorStatus
sudoSetKeys
sudoStoppedValidatorCounts
version
24,954 (-22)
24,680 (0)
85,194 (-22)
2,523 (-22)
43,377 (+659)
10,921 (0)
2,631 (+22)
2,546 (-22)
5,561 (0)
2,635 (+89)
24,887 (-22)
2,963 (0)
24,515 (+489)
24,501 (+22)
24,636 (-22)
30,964 (0)
24,910 (0)
31,348 (-22)
24,079 (0)
29,398 (+22)
31,652 (0)
595 (-22)
-0.09%
0.00%
-0.03%
-0.86%
+1.54%
0.00%
+0.84%
-0.86%
0.00%
+3.50%
-0.09%
0.00%
+2.04%
+0.09%
-0.09%
0.00%
0.00%
-0.07%
0.00%
+0.07%
0.00%
-3.57%
123,433 (-454)
1,654,298 (-12,418)
115,401 (-22)
2,523 (-22)
116,757 (-391,587)
12,428 (-143)
2,631 (+22)
2,546 (-22)
10,710 (-149)
4,976 (+89)
93,696 (+201)
953,640 (+45,457)
412,743 (-167,801)
172,455 (+19)
158,241 (-2,771)
32,988 (0)
47,417 (+344)
35,705 (-22)
32,913 (+3)
29,425 (+22)
105,864 (-22)
595 (-22)
-0.37%
-0.75%
-0.02%
-0.86%
-77.03%
-1.14%
+0.84%
-0.86%
-1.37%
+1.82%
+0.21%
+5.01%
-28.90%
+0.01%
-1.72%
0.00%
+0.73%
-0.06%
+0.01%
+0.07%
-0.02%
-3.57%
122,898 (-10)
1,422,842 (0)
123,575 (-22)
2,523 (-22)
117,048 (-391,296)
12,981 (0)
2,631 (+22)
2,546 (-22)
10,200 (0)
4,986 (+89)
94,300 (-22)
157,295 (0)
192,365 (+5,366)
143,542 (+22)
114,118 (-22)
32,347 (-6)
35,202 (0)
34,605 (-22)
32,976 (0)
29,422 (+22)
113,772 (0)
595 (-22)
-0.01%
0.00%
-0.02%
-0.86%
-76.97%
0.00%
+0.84%
-0.86%
0.00%
+1.82%
-0.02%
0.00%
+2.87%
+0.02%
-0.02%
-0.02%
0.00%
-0.06%
0.00%
+0.07%
0.00%
-3.57%
140,310 (-22)
17,415,900 (0)
148,665 (-22)
2,523 (-22)
920,205 (-53,765)
12,981 (0)
2,631 (+22)
2,546 (-22)
22,556 (0)
4,986 (+89)
94,300 (-22)
12,744,218 (0)
1,484,262 (+14,038)
360,860 (+18)
552,697 (-22)
36,276 (0)
278,640 (0)
42,245 (-22)
32,988 (0)
29,446 (+22)
167,496 (0)
595 (-22)
-0.02%
0.00%
-0.01%
-0.86%
-5.52%
0.00%
+0.84%
-0.86%
0.00%
+1.82%
-0.02%
0.00%
+0.95%
+0.00%
-0.00%
0.00%
0.00%
-0.05%
0.00%
+0.07%
0.00%
-3.57%
103,060 (+4,199)
21,477 (+2,233)
15 (0)
11 (0)
276 (+274)
17,916 (+1,560)
1,543 (+772)
1 (0)
257 (0)
258 (0)
115 (+31)
514 (0)
2,333 (+789)
2,314 (0)
773 (0)
1,028 (0)
7,498 (+796)
1,028 (0)
34,200 (+1,136)
257 (0)
2,578 (0)
1 (0)
ConsensusLayerDepositManagerV1ControllableValidatorKeyRequest 2,797,108 (+238,773) depositToConsensusLayerWithDepositRoot
publicConsensusLayerDepositManagerInitializeV1
setKeeper
setScenario
32,281 (-2,122)
91,103 (+22)
43,843 (-4)
23,668 (0)
-6.17%
+0.02%
-0.01%
0.00%
91,135 (-29,378)
91,103 (+22)
43,843 (-4)
40,735 (+1,138)
-24.38%
+0.02%
-0.01%
+2.87%
88,743 (-51,475)
91,103 (+22)
43,843 (-4)
43,580 (0)
-36.71%
+0.02%
-0.01%
0.00%
169,462 (+21,935)
91,103 (+22)
43,843 (-4)
43,580 (0)
+14.87%
+0.02%
-0.01%
0.00%
12 (+7)
11 (+7)
1 (0)
7 (+2)
RiverV1ForceCommittable 5,563,902 (+113,526) claimRedeemRequests
deposit
depositAndTransfer
depositToConsensusLayerWithDepositRoot
getAllowlist
getMetadataURI
getOperatorsRegistry
getReportBounds
initRiverV1_2
requestRedeem
resolveRedeemRequests
sendCoverageFunds
setConsensusLayerData
setDailyCommittableLimits
setMetadataURI
transfer
40,131 (+44)
62,146 (+22)
66,177 (+22)
157,894 (+2,068)
568 (+22)
3,195 (0)
2,612 (+22)
4,928 (+56)
37,050 (0)
223,720 (+22)
1,945,863 (0)
23,735 (+22)
25,500 (0)
24,449 (+34)
24,526 (0)
30,317 (+22)
+0.11%
+0.04%
+0.03%
+1.33%
+4.03%
0.00%
+0.85%
+1.15%
0.00%
+0.01%
0.00%
+0.09%
0.00%
+0.14%
0.00%
+0.07%
1,921,105 (+31,013)
83,379 (+22)
95,297 (+22)
1,257,737 (-157,301)
1,589 (+24)
4,426 (+13)
2,612 (+22)
4,928 (+56)
38,431 (-52)
223,856 (+18)
2,611,498 (-2,573)
23,735 (+22)
168,751 (+2)
36,396 (+25)
49,340 (+133)
35,407 (+22)
+1.64%
+0.03%
+0.02%
-11.12%
+1.53%
+0.29%
+0.85%
+1.15%
-0.14%
+0.01%
-0.10%
+0.09%
+0.00%
+0.07%
+0.27%
+0.06%
1,138,259 (-17,576)
81,079 (+22)
95,297 (+22)
876,292 (-1,547)
2,568 (+22)
3,284 (0)
2,612 (+22)
4,928 (+56)
37,850 (0)
223,756 (+22)
2,603,685 (-23,963)
23,735 (+22)
173,283 (0)
36,428 (+28)
25,982 (+156)
33,677 (+22)
-1.52%
+0.03%
+0.02%
-0.18%
+0.86%
0.00%
+0.85%
+1.15%
0.00%
+0.01%
-0.91%
+0.09%
0.00%
+0.08%
+0.60%
+0.07%
8,082,522 (+252,046)
115,132 (+22)
124,417 (+22)
16,829,417 (-7,246,128)
2,568 (+22)
9,752 (0)
2,612 (+22)
4,928 (+56)
42,650 (0)
244,077 (+22)
3,284,157 (0)
23,735 (+22)
375,153 (0)
48,408 (+22)
117,303 (0)
42,229 (+22)
+3.22%
+0.02%
+0.02%
-30.10%
+0.86%
0.00%
+0.85%
+1.15%
0.00%
+0.01%
0.00%
+0.09%
0.00%
+0.05%
0.00%
+0.05%
130 (-5)
57,166 (+3)
2 (0)
3,604 (-5)
54,160 (-7)
514 (0)
1 (0)
2,570 (0)
274 (0)
26,507 (-45)
302 (+3)
257 (0)
5,654 (0)
514 (0)
515 (0)
3 (0)
UserFactory 217,972 (0) _new
_newMulti
71,066 (0)
21,865 (0)
0.00%
0.00%
79,692 (-36)
5,903,307 (+241,490)
-0.05%
+4.27%
71,450 (0)
1,620,516 (+78)
0.00%
+0.00%
88,550 (0)
45,091,735 (0)
0.00%
0.00%
116,727 (+2,020)
514 (0)
RedeemManagerV1 2,183,836 (0) claimRedeemRequests(uint32[],uint32[])
claimRedeemRequests(uint32[],uint32[],bool,uint16)
getRedeemDemand
requestRedeem(uint256)
requestRedeem(uint256,address)
resolveRedeemRequests
35,479 (+22)
23,580 (0)
446 (0)
202,877 (0)
35,264 (-12)
3,273 (0)
+0.06%
0.00%
0.00%
0.00%
-0.03%
0.00%
715,110 (-28,719)
669,179 (-1,140)
1,553 (-1)
211,265 (+26)
185,245 (0)
993,949 (-2,427)
-3.86%
-0.17%
-0.06%
+0.01%
0.00%
-0.24%
95,107 (0)
95,656 (0)
2,446 (0)
211,245 (+22)
185,529 (0)
25,171 (0)
0.00%
0.00%
0.00%
+0.01%
0.00%
0.00%
8,166,339 (-320,393)
34,786,024 (0)
2,446 (0)
231,566 (+22)
215,533 (0)
25,781,330 (0)
-3.78%
0.00%
0.00%
+0.01%
0.00%
0.00%
412 (+3)
7,197 (0)
7,425 (+3)
27,047 (+48)
133,288 (-227)
5,968 (-4)
TestToken 3,628,553 (0) debugPushV1VestingSchedule
releaseVestingSchedule
revokeVestingSchedule
116,081 (0)
26,284 (0)
21,940 (0)
0.00%
0.00%
0.00%
169,518 (-2)
46,375 (+967)
66,129 (-80)
-0.00%
+2.13%
-0.12%
161,793 (0)
35,376 (0)
65,357 (0)
0.00%
0.00%
0.00%
178,905 (0)
104,758 (0)
70,643 (0)
0.00%
0.00%
0.00%
514 (0)
5,781 (-180)
264 (0)
OperatorsRegistryWithOverridesV1 4,911,480 (+170,259) addOperator
addValidators
getOperator
getOperatorCount
getStoppedAndRequestedExitCounts
initOperatorsRegistryV1
100,737 (-22)
176,568 (0)
10,921 (0)
2,609 (+22)
1,499 (-22)
94,300 (-22)
-0.02%
0.00%
0.00%
+0.85%
-1.45%
-0.02%
126,958 (+17)
947,713 (+16,627)
12,966 (-1)
2,609 (+22)
1,499 (-22)
94,300 (-22)
+0.01%
+1.79%
-0.01%
+0.85%
-1.45%
-0.02%
123,210 (-22)
314,958 (0)
12,981 (0)
2,609 (+22)
1,499 (-22)
94,300 (-22)
-0.02%
0.00%
0.00%
+0.85%
-1.45%
-0.02%
140,310 (-22)
18,309,994 (0)
12,981 (0)
2,609 (+22)
1,499 (-22)
94,300 (-22)
-0.02%
0.00%
0.00%
+0.85%
-1.45%
-0.02%
16,123 (-169)
14,170 (-269)
1,407 (-73)
1,425 (-76)
189 (-1)
56 (0)
Firewall 566,843 (0) fallback 26,143 (0) 0.00% 62,651 (-980) -1.54% 42,599 (0) 0.00% 123,069 (-22) -0.02% 51 (+2)
OracleV1 1,615,616 (+12) addMember
removeMember
reportConsensusLayerData
setQuorum
24,344 (0)
24,310 (0)
25,549 (0)
23,898 (0)
0.00%
0.00%
0.00%
0.00%
245,713 (-2,490)
39,665 (-1)
241,483 (-2,362)
101,617 (-564)
-1.00%
-0.00%
-0.97%
-0.55%
196,767 (-2,566)
39,224 (0)
205,778 (-1,583)
26,075 (0)
-1.29%
0.00%
-0.76%
0.00%
717,792 (0)
55,920 (0)
2,078,116 (0)
592,831 (0)
0.00%
0.00%
0.00%
0.00%
42,440 (-285)
1,030 (0)
38,524 (-285)
1,013 (-1)
OperatorsRegistryV1 4,904,989 (+170,199) getOperatorCount
initOperatorsRegistryV1
initOperatorsRegistryV1_1
2,587 (+22)
94,300 (-22)
291,340 (+22)
+0.86%
-0.02%
+0.01%
2,587 (+22)
94,300 (-22)
291,340 (+22)
+0.86%
-0.02%
+0.01%
2,587 (+22)
94,300 (-22)
291,340 (+22)
+0.86%
-0.02%
+0.01%
2,587 (+22)
94,300 (-22)
291,340 (+22)
+0.86%
-0.02%
+0.01%
1 (0)
38 (0)
3 (0)
ConsensusLayerDepositManagerV1ValidKeys 1,352,600 (+124,139) depositToConsensusLayerWithDepositRoot
publicConsensusLayerDepositManagerInitializeV1
24,885 (+520)
91,024 (+22)
+2.13%
+0.02%
157,035 (+1,076)
91,216 (+22)
+0.69%
+0.02%
126,038 (+520)
91,264 (+22)
+0.41%
+0.02%
266,025 (+1,448)
91,264 (+22)
+0.55%
+0.02%
5 (0)
5 (0)
ConsensusLayerDepositManagerV1ExposeInitializer 2,277,880 (+124,139) depositToConsensusLayerWithDepositRoot
publicConsensusLayerDepositManagerInitializeV1
32,095 (+438)
91,081 (+22)
+1.38%
+0.02%
352,150 (+955)
91,081 (+22)
+0.27%
+0.02%
509,778 (+1,209)
91,081 (+22)
+0.24%
+0.02%
514,578 (+1,219)
91,081 (+22)
+0.24%
+0.02%
3 (0)
6 (0)
OracleManagerV1ExposeInitializer 1,914,425 (0) setCLSpec
setConsensusLayerData
setReportBounds
supersedeReportedBalanceSum
supersedeReportedValidatorCount
24,452 (0)
154,309 (0)
24,067 (0)
23,912 (0)
23,933 (0)
0.00%
0.00%
0.00%
0.00%
0.00%
31,542 (0)
198,825 (+163)
30,085 (-1)
43,201 (-78)
43,157 (-77)
0.00%
+0.08%
-0.00%
-0.18%
-0.18%
29,280 (-12)
199,915 (0)
27,839 (0)
43,896 (0)
43,857 (0)
-0.04%
0.00%
0.00%
0.00%
0.00%
38,873 (0)
234,067 (0)
36,411 (0)
43,920 (0)
43,857 (0)
0.00%
0.00%
0.00%
0.00%
0.00%
514 (0)
257 (0)
514 (0)
257 (0)
257 (0)
CoverageFundV1 437,167 (0) donate
pullCoverageFunds
21,289 (0)
23,786 (0)
0.00%
0.00%
52,951 (-17)
23,921 (+1)
-0.03%
+0.00%
58,133 (0)
23,882 (+12)
0.00%
+0.05%
58,411 (+22)
24,158 (0)
+0.04%
0.00%
1,862 (-8)
257 (0)
ELFeeRecipientV1 326,444 (+12) pullELFees 23,774 (0) 0.00% 23,916 (-3) -0.01% 23,870 (0) 0.00% 24,158 (0) 0.00% 257 (0)
RiverDonationMock 125,527 (0) pullELFees 27,351 (0) 0.00% 35,584 (-3) -0.01% 35,658 (0) 0.00% 35,946 (0) 0.00% 1,029 (0)
AllowlistV1Sudo 950,883 (0) setAllower
setDenier
24,294 (-12)
24,183 (-12)
-0.05%
-0.05%
27,434 (0)
27,323 (0)
0.00%
0.00%
27,424 (-6)
27,313 (-6)
-0.02%
-0.02%
30,554 (0)
30,443 (0)
0.00%
0.00%
514 (0)
514 (0)
RiverV1 5,547,742 (+113,590)
TUPProxy 709,034 (-49,431)
WithdrawV1 343,916 (+12)
MockRedeemManagerV1 659,097 (+12)
RedeemManagerV1Mock 2,281,441 (+12)

Copy link
Contributor

@iamsahu iamsahu left a comment

Choose a reason for hiding this comment

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

Great work!

Apart from extracting the createAllocation logic into a contract that could be utilized across multiple test files the rest looks good.

iamsahu
iamsahu previously approved these changes Feb 11, 2026
Copy link
Contributor

@iamsahu iamsahu left a comment

Choose a reason for hiding this comment

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

LGTM! Excellent work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants