Skip to content

Migrate test suite from Hardhat to Foundry#2848

Open
clement-ux wants to merge 154 commits into
masterfrom
clement/foundry-migration
Open

Migrate test suite from Hardhat to Foundry#2848
clement-ux wants to merge 154 commits into
masterfrom
clement/foundry-migration

Conversation

@clement-ux

@clement-ux clement-ux commented Mar 20, 2026

Copy link
Copy Markdown
Collaborator

Summary

Migrates the smart contract test and deployment validation workflow from Hardhat to Foundry.

Changes

  • Adds Foundry unit, fork, and smoke tests.
  • Adds DeployManager and Resolver to test deployed contracts with pending governance applied.
  • Adds Foundry CI, Makefile targets, environment helpers, and test-generation skills.
  • Removes obsolete Hardhat, Echidna, oracle, and documentation files.

Test plan

  • make test
  • Fork tests
  • make test-smoke
  • Foundry CI

clement-ux and others added 30 commits March 2, 2026 09:52
Set up forge compilation for all 302 Solidity files alongside existing
Hardhat config. Add foundry.toml with Soldeer deps (forge-std, OZ 4.4.2,
Chainlink CCIP, LayerZero v2, solidity-bytes-utils) and transitive
remappings for LZ dependency chain. Replace hardhat/console.sol import
with forge-std/console2.sol in MockRebornMinter.
Add MockStrategy and MockNonRebasing state variables and imports
to the shared Base contract so they are available to all test suites.
Shared.sol deploys OUSD + OUSDVault behind proxies, configures the
vault with withdrawal delay, rebase rate max, and drip duration,
then funds matt and josh with 100 OUSD each.

Mint.t.sol covers mint, deprecated mint overload, mintForStrategy,
burnForStrategy, and auto-allocate on mint (13 tests).
Cover governor(), isGovernor(), two-step transferGovernance +
claimGovernance flow, and access control reverts (9 tests).
Cover totalValue, checkBalance, getAssetCount, getAllAssets,
getStrategyCount, getAllStrategies, isSupportedAsset, and the
deprecated oUSD() accessor (18 tests).
Cover all VaultAdmin setters, pause functions, strategy management,
and token rescue. Includes revert paths for unauthorized callers,
invalid values, and edge cases like "Asset not supported by Strategy",
"Strategy has funds", and "Parameter length mismatch" (98 tests).
Cover rebase pausing, yield distribution to rebasing accounts,
non-rebasing exclusion, trustee fee accrual, previewYield,
drip duration smoothing, _nextYield early-return branches, and
the defensive fee >= yield check (19 tests).
Cover allocate to default strategy, vault buffer, withdrawal queue
reserves, depositToStrategy, withdrawFromStrategy,
withdrawAllFromStrategy, withdrawAllFromStrategies, capital-paused
revert, and early return when no asset available (23 tests).
Cover requestWithdrawal, claimWithdrawal, claimWithdrawals,
addWithdrawalQueueLiquidity, strategy-queue interactions,
mint-covers-outstanding scenarios, full drain edge cases,
insolvency and slash scenarios, solvency at 3%/10%
maxSupplyDiff, rebase-on-redeem, and capital-paused claims
(55 tests).
Add test directory, solmate dependency, and remappings to
foundry.toml. Add .gitkeep placeholders for the test directory
structure. Add lcov.info to .gitignore.
Captures the established test conventions (directory layout, inheritance
chain, naming patterns, helper idioms, fuzz config) so future contract
test suites follow the same structure as OUSDVault.
Add fuzz tests for mint, rebase, and withdraw covering key properties
(scaling, round-trip recovery, yield distribution, queue invariants).
Configure foundry.toml with 1024 runs and deterministic seed.
…to 96%

- Add Burn.t.sol and Initialize.t.sol for previously untested functions
- Add missing revert tests to Mint, TransferFrom, Transfer, YieldDelegation
- Fix truncated assertion in Mint.t.sol
- Update unit-test skill to enforce one file per function rule
Enforce minimum coverage thresholds: 100% functions, 90% branches/lines/statements.
Includes iterative improvement workflow and requires explanation for uncovered paths.
…onic, WrappedOusd)

Add Foundry unit tests for remaining wrapped token variants and declare
their state variables in Base.sol for shared test infrastructure.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…r contracts

Add comprehensive unit tests for OETHZapper, OETHBaseZapper, OSonicZapper,
and WOETHCCIPZapper. Tests cover all public functions, revert conditions,
event emissions, and edge cases. Uses vm.mockCall for CCIP router and
vm.etch for hardcoded addresses (wS, Base WETH).

35 tests across 9 test suites — 100% line/statement/branch/function coverage.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…% coverage

Add 120 tests across 22 files covering CurvePoolBooster, CurvePoolBoosterPlain,
and CurvePoolBoosterFactory. Includes concrete tests for all public/external
functions and fuzz tests for fee handling and salt encoding.

Also adds shared test infrastructure: Base.sol pool booster state vars,
MockCreateX for deterministic CREATE2 testing, and naming convention rules.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add unit tests for PoolBoosterMerkl and PoolBoosterFactoryMerkl covering
constructor, bribe, isValidSignature, getNextPeriodStartTime, factory
create/compute, and setMerklDistributor. Includes fuzz test for period timing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add unit tests for PoolBoosterSwapxSingle, PoolBoosterSwapxDouble, and their
factories. Covers constructor validation, bribe mechanics, split calculations,
factory create/compute, and abstract factory functions (bribeAll, removePoolBooster).
Includes fuzz test for double bribe split amounts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add unit tests for PoolBoosterMetropolis and PoolBoosterFactoryMetropolis
covering constructor, bribe mechanics with rewarder/voter mocking, and
factory create/compute functions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…overage

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Ensures forge excludes test helper files from coverage reports.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…h 100% coverage

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
clement-ux and others added 11 commits March 26, 2026 16:00
- Add --json flag to forge inspect and strip tracing logs from stdout
- Install soldeer dependencies before building in worktrees
- Make forge build non-fatal (partial builds can still inspect some contracts)
- Handle the "carve from gap" upgrade pattern: new variables replacing
  the start of a __gap array are valid if the gap shrinks by the exact
  number of slots used
…hecker

- Use install-deps.sh instead of forge soldeer install (handles npm tgz packages)
- Run forge clean before building to avoid stale cache issues
- Add extra_output_files = ["storageLayout"] to foundry.toml
Only compiles the target contract and its dependencies, not the entire
repo. Reduces runtime from ~3min to ~10s per contract check.
…uced backing drift

- _ensureVaultLiquidity now sets maxSupplyDiff to 10% so that
  artificially dealt WETH (which inflates totalValue beyond what the
  drip-limited rebase can match) doesn't trip the _postRedeem check.
- Add _ensureAssetAvailable helper to cover outstanding withdrawal
  queue obligations before depositToStrategy calls.
- Fixes Smoke_Concrete_OETHBase_Redeem_Test and unblocks the previously
  hidden Smoke_Concrete_OETHBaseVault_Allocate_Test failures.
* refactor(test): use interfaces instead of concrete imports in OUSDVault tests

Replace concrete contract imports (OUSDVault, OUSD, VaultStorage, Proxies)
with interface-only imports (IVault, IOToken, IProxy) and vm.deployCode.
This keeps test compilation units small for better Forge caching.

- Add IOToken and IProxy interfaces
- Add isGovernor() to IVault interface
- Update Shared.t.sol to deploy via vm.deployCode and cast to interfaces
- Replace all VaultStorage.Event with IVault.Event references
- Use struct field access instead of tuple destructuring
- Document interface-only testing pattern in tests/README.md

* refactor(test): use interfaces instead of concrete imports in OETHVault tests

Same migration as OUSDVault: replace concrete contract imports
(OETHVault, OETH, VaultStorage, Proxies) with interface-only imports
(IVault, IOToken, IProxy) and vm.deployCode for better Forge caching.

- Update Shared.t.sol to deploy via vm.deployCode and cast to interfaces
- Replace all VaultStorage.Event with IVault.Event references
- Use struct field access instead of tuple destructuring

* refactor(test): use interfaces instead of concrete imports in OUSD token tests

Replace concrete contract imports (OUSD, OUSDVault, Proxies) with
interface-only imports (IOToken, IVault, IProxy) and vm.deployCode
for better Forge caching.

- Update Shared.t.sol to deploy via vm.deployCode and cast to interfaces
- Replace all OUSD.Event with IOToken.Event references
- Update Initialize.t.sol to use vm.deployCode for fresh deployments
- Update Transfer.t.sol MockNonRebasingTwo helper to use IOToken

* refactor(test): use interfaces instead of concrete imports in OETH/OETHBase/OSonic token tests

Replace concrete token imports with IOToken interface and vm.deployCode
for better Forge caching.

* refactor(test): use interfaces instead of concrete imports in wrapped token tests

Add IWOToken interface for WOETH/WOETHBase/WOETHPlume/WOSonic/WrappedOusd.
Replace concrete contract imports with interface-only imports (IWOToken,
IOToken, IVault, IProxy) and vm.deployCode across all wrapped token tests.

* docs: update test docs and unit-test skill for interface-only testing

- Fix vm.deployCode path typo in README
- Add proxy, token, and wrapped token deployment examples
- Add available interfaces reference table
- Update unit-test skill: interface types, vm.deployCode, checklist

* refactor(test): use interfaces instead of concrete imports in all strategy tests

Add 15 per-strategy interfaces in contracts/interfaces/strategies/ and
migrate all 15 strategy test suites to interface-only imports with
vm.deployCode for better Forge caching.

- ICurveAMOStrategy, IBaseCurveAMOStrategy, IOETHSupernovaAMOStrategy
- IAerodromeAMOStrategy, ISonicSwapXAMOStrategy, ISonicStakingStrategy
- IBridgedWOETHStrategy, IGeneralized4626Strategy, IMorphoV2Strategy
- INativeStakingSSVStrategy, ICompoundingStakingSSVStrategy
- IConsolidationController, ICrossChainMaster/RemoteStrategy
- IVaultValueChecker

* docs(skill): sync codex unit-test skill with interface-only testing rules

* refactor(test): migrate proxy unit tests to iProxy

* test: migrate poolbooster unit tests to interfaces

* test: migrate automation unit tests to interfaces

* prettier

* docs(skill): update fork-test skills with interface-only testing rules

* test(zapper): migrate zapper unit tests to interfaces

* test(origin): migrate base automation fork tests to interfaces

* test(base): migrate aerodrome amo fork tests to interfaces

* test(origin): finish base strategy fork migrations

* test(origin): migrate mainnet automation fork tests to interfaces

* test(origin): migrate pool booster fork tests to interfaces

* test(origin): migrate mainnet strategy fork suites

* test(sonic): migrate sonic fork suites

* docs(skill): update smoke-test skills with interface-only testing rules

* test(origin): migrate mainnet vault smoke tests

* test(origin): migrate smoke suites and unify staking interfaces

* test(origin): migrate smoke suites to interfaces

* test(origin): use make targets in foundry workflow

* chore(zapper): format zapper interfaces

* chore(origin): format strategy interface imports

* test(origin): fix abstract safe module constructor setup

* chore(origin): simplify forge test make targets

* feat(skill): add organize-test skill and apply to OUSDVault tests

Add a new Claude/Codex skill for reorganizing Foundry test files
structurally without semantic changes. Apply it to OUSDVault unit tests:
- Sort imports into named groups (Test base, External libraries, Project imports)
- Reorder state variables (CONSTANTS before CONTRACTS & MOCKS)
- Consolidate revert tests next to their parent function sections

* ci(origin): add unused import lint check to CI

Add `make lint-imports` step to the Formatting & Lint job in the Foundry
workflow so PRs introducing unused Solidity imports fail CI.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore(origin): remove 88 unused Solidity imports

Clean up unused imports across scripts, unit tests, fork tests, smoke
tests, and mocks flagged by `forge lint --only-lint unused-import`.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fmt

* chore: upgrade forge-std from 1.9.7 to 1.15.0

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(skill): require referencing artifact paths through tests/utils/Artifacts.sol

Update unit-test and fork-test skills (Claude + Codex) to instruct that
vm.deployCode calls must use sub-library references like Vaults.OUSD or
Proxies.IG_PROXY instead of inline "contracts/...sol:Name" strings, and
to add missing entries to tests/utils/Artifacts.sol when needed.

* refactor(test): centralize Foundry artifact paths in tests/utils/Artifacts.sol

Introduce a single Artifacts.sol containing per-category sub-libraries
(Tokens, Vaults, Proxies) to replace inline "contracts/...sol:Name"
strings passed to vm.deployCode. Migrate OUSDVault unit test Shared.t.sol
as the first consumer; other test directories will be migrated incrementally.

* refactor(test): centralize foundry artifact paths

* chore: remove artifacts migration plan

* docs(test): document split artifact libraries

* refactor(test): organize foundry test imports

* lint
…gist modifier

Align test expectations with master's PR #2853 which allows strategist
to call collectRewardTokens.
Comment thread .github/workflows/foundry.yml
Comment thread .gitignore Outdated
Comment thread contracts/package.json
clement-ux and others added 18 commits April 17, 2026 10:33
Resolves:
- .github/workflows/defi.yml: keep deleted (replaced by foundry.yml)
- contracts/dev.env: keep Foundry-oriented structure, preserve master's
  Automaton/nonce-queue vars and the still-live Hardhat vars, and document
  both the Foundry (FORK_BLOCK_NUMBER_*) and Hardhat (BLOCK_NUMBER) fork-block
  conventions.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KQTR6rq3bhucMHXFoNXxJT
…s for WOETHPlume and WOSonic

- Deleted unit tests for WOETHPlume: Deposit, ViewFunctions, and Shared utilities.
- Deleted unit tests for WOSonic: Deposit, ViewFunctions, and Shared utilities.
- Removed unused artifacts and references related to OSonic and WOETH in Proxies, Tokens, Vaults, Strategies, and Zappers.
- Cleaned up PoolBoosters artifacts by removing obsolete factory references.
- Deleted OSonicOracleRouter.sol and OracleRouter.sol as they are no longer needed.
- Removed related README.md files and SVG diagrams for OETH and Oracle routers.
- Updated generate.sh script to exclude Oracle-related UML generation.
- Cleaned up PlantUML files by removing references to obsolete Oracle components.
…vailable and add isModuleAvailable flag in shared test
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