Skip to content

Feature/fuzz tests#1737

Open
grGred wants to merge 2 commits intolidofinance:developfrom
grGred:feature/fuzz-tests
Open

Feature/fuzz tests#1737
grGred wants to merge 2 commits intolidofinance:developfrom
grGred:feature/fuzz-tests

Conversation

@grGred
Copy link
Copy Markdown

@grGred grGred commented Mar 20, 2026

Summary

  • add fuzz tests and invariants under test/fuzz
  • include integration, vault, and library fuzz targets

Included files

  • test/fuzz/integration/*
  • test/fuzz/lib/*
  • test/fuzz/vaults/*

@grGred grGred requested a review from a team as a code owner March 20, 2026 13:40
@tamtamchik tamtamchik requested a review from Copilot March 23, 2026 17:14
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new Foundry fuzz/invariant testing suite under test/fuzz to broaden coverage of vault components (StakingVault/Dashboard/VaultHub), PDG accounting, and several shared libraries.

Changes:

  • Added invariant suites for RefSlotCache and PredepositGuarantee accounting.
  • Added fuzz suites for StakingVault (direct + Dashboard integration) and CLProofVerifier.
  • Added fuzz/property suites for multiple shared libraries plus VaultHub/LazyOracle and Lido share-accounting integrations.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
test/fuzz/vaults/refSlotCache.invariant.t.sol Extended invariant coverage for DoubleRefSlotCache with multi-slot jumps and revert conditions.
test/fuzz/vaults/refSlotCache.fuzz.t.sol Baseline invariant fuzzing for DoubleRefSlotCache behaviors.
test/fuzz/vaults/predepositGuarantee.invariant.t.sol Invariant suite for PDG bond/accounting conservation with ghost tracking.
test/fuzz/vaults/clProofVerifier.fuzz.t.sol Fuzz tests for CLProofVerifier gindex selection and revert behavior.
test/fuzz/vaults/StakingVaultDirect.fuzz.t.sol Fuzz tests for direct (no Dashboard/VaultHub) StakingVault access control + accounting.
test/fuzz/vaults/StakingVaultDashboard.fuzz.t.sol Integration fuzz tests for Dashboard → VaultHub → StakingVault call paths using local mocks.
test/fuzz/lib/TriggerableWithdrawals.fuzz.t.sol Property/fuzz tests for TriggerableWithdrawals validation and mock-precompile happy paths.
test/fuzz/lib/MinFirstAllocationStrategy.fuzz.t.sol Property/fuzz tests for allocation invariants (budget conservation, caps, monotonicity).
test/fuzz/lib/MeIfNobodyElse.fuzz.t.sol Property/fuzz tests for mapping-default behavior used by PDG.
test/fuzz/lib/Math256.fuzz.t.sol Property/fuzz tests for Math256 helpers (min/max/ceilDiv/absDiff).
test/fuzz/lib/GIndex.fuzz.t.sol Property/fuzz tests for GIndex arithmetic + bounds/reverts and concat behavior.
test/fuzz/lib/BLS.fuzz.t.sol Extensive fuzz/edge-case tests around BLS12-381 deposit verification and flag validation.
test/fuzz/integration/VaultHubLazyOracle.fuzz.t.sol Integration fuzz tests for VaultHub lifecycle + report freshness/quarantine timestamp semantics.
test/fuzz/integration/LidoIntegration.fuzz.t.sol Integration fuzz tests for Lido external-shares accounting vs VaultHub liability shares.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +206 to +208
function vaultRecord(address) external pure returns (VaultHub.VaultRecord memory) {}

function latestReport(address) external pure returns (VaultHub.Report memory) {}
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

vaultRecord() and latestReport() have empty bodies but declare non-void return types. As written this won’t compile (functions must return a value unless using named return variables). Implement minimal stub returns (e.g., return zero-initialized structs via named return vars) or remove these functions if they are not needed for the Dashboard code paths exercised in this test.

Suggested change
function vaultRecord(address) external pure returns (VaultHub.VaultRecord memory) {}
function latestReport(address) external pure returns (VaultHub.Report memory) {}
function vaultRecord(address) external pure returns (VaultHub.VaultRecord memory record) {}
function latestReport(address) external pure returns (VaultHub.Report memory report) {}

Copilot uses AI. Check for mistakes.
Comment on lines +24 to +30
function testFuzz_getValidatorGI_UsesPrevBeforePivot(uint64 provenSlot, uint32 offset) external view {
vm.assume(provenSlot < pivotSlot);

// Bound offsets to avoid expected IndexOutOfRange reverts from GIndex.shr().
uint256 boundedOffset = bound(uint256(offset), 0, 1_000_000);

GIndex expected = giPrev.shr(boundedOffset);
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

This test is marked external view but calls vm.assume(...), which is a cheatcode call and not view-compatible. This will fail to compile due to calling a non-view function from a view function. Drop the view mutability on this test (and keep it external) so it can use vm.assume/cheatcodes.

Copilot uses AI. Check for mistakes.
Comment on lines +36 to +41
function testFuzz_getValidatorGI_UsesCurrAtOrAfterPivot(uint64 provenSlot, uint32 offset) external view {
vm.assume(provenSlot >= pivotSlot);

uint256 boundedOffset = bound(uint256(offset), 0, 1_000_000);

GIndex expected = giCurr.shr(boundedOffset);
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

This test is marked external view but uses vm.assume(...) (cheatcode), which cannot be invoked from a view function and will cause a compile-time error. Remove view from the function signature.

Copilot uses AI. Check for mistakes.
Comment on lines +450 to +458
function testFuzz_LI6_sharePriceRoundTrip(uint96 ethAmount) external view {
vm.assume(ethAmount > 0 && ethAmount < 1_000_000 ether);

uint256 shares = lido.getSharesByPooledEth(ethAmount);
uint256 ethBack = lido.getPooledEthByShares(shares);

// Due to floor division, ethBack may be 1 wei less than ethAmount
assertGe(uint256(ethAmount) + 1, ethBack, "LI-6: round-trip lost too much");
assertGe(ethBack + 1, uint256(ethAmount), "LI-6: round-trip gained too much");
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

testFuzz_LI6_sharePriceRoundTrip is declared external view but calls vm.assume(...). Cheatcode calls are not view-compatible, so this will not compile. Remove view from the function signature.

Copilot uses AI. Check for mistakes.
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