Skip to content

Clement/foundry migration#2848

Draft
clement-ux wants to merge 94 commits intomasterfrom
clement/foundry-migration
Draft

Clement/foundry migration#2848
clement-ux wants to merge 94 commits intomasterfrom
clement/foundry-migration

Conversation

@clement-ux
Copy link
Collaborator

Code Change Checklist

To be completed before internal review begins:

  • The contract code is complete
  • Executable deployment file
  • Fork tests that test after the deployment file runs
  • Unit tests *if needed
  • The owner has done a full checklist review of the code + tests

Internal review:

  • Two approvals by internal reviewers

Deploy checklist

Two reviewers complete the following checklist:

- [ ] All deployed contracts are listed in the deploy PR's description
- [ ] Deployed contract's verified code (and all dependencies) match the code in master
- [ ] Contract constructors have correct arguments
- [ ] The transactions that interacted with the newly deployed contract match the deploy script.
- [ ] Governance proposal matches the deploy script
- [ ] Smoke tests pass after fork test execution of the governance proposal

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 23 commits March 17, 2026 16:00
The conditional deal could silently skip funding when the vault already
held enough token balance — but that balance was fully allocated to prior
claimable withdrawal requests, leaving nothing for the new request and
causing claimWithdrawal to revert with "Queue pending liquidity".

Switch to an additive deal (currentBalance + needed) so the shortfall is
always covered on top of whatever is already in the vault. Applied to
OUSD, OETH, and OETHBase shared helpers (OSonic was authored correctly
from the start).
Demonstrates the three-phase lifecycle (execute → governance proposal →
fork verification) as a template for future mainnet deployments.
Also tracks deployment registry JSON files and refines .gitignore to
include deployments-*.json while excluding fork variants.
These property-based fuzzing contracts were failing when run under
Forge's test runner (constructor reverts with "Caller is not the
Governor") and are not part of the Foundry test suite.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…p tolerance

Move wrapped token smoke tests from tests/smoke/wrappedToken/ to
tests/smoke/token/ to consolidate all token smoke tests under a single
directory, matching the OSonic layout.

Also fix test_convertToShares_roundtrip tolerance from 1 to 2 wei in
WOSonic to account for ERC4626 rounding in the convertToShares →
convertToAssets roundtrip.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add `script = "scripts"` to foundry.toml so Forge compiles all
  deploy scripts into out/, which DeployManager requires to load them
  at runtime via vm.deployCode()
- Add missing `using GovHelper for GovProposal` in AbstractDeployScript
  (documented in ARCHITECTURE.md but absent from the code)
- Fix 000_Example.s.sol: add GovHelper/GovProposal imports, add
  `using GovHelper for GovProposal`, and add missing payable cast on
  proxy address

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Migrates the Hardhat deploy/sonic/026_vault_upgrade.js to Foundry.

_execute() deploys a new OSVault implementation with wS as the base
asset. _buildGovernanceProposal() is intentionally empty because Sonic
uses a Timelock Controller rather than the mainnet Governor. _fork()
pranks the Sonic timelock to upgrade the vault proxy and set
SonicStakingStrategy as the default strategy, then asserts the
implementation was updated.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The OSonic smoke tests were blocked behind vm.skip(true) pending the
026_VaultUpgrade deploy script, which upgrades the on-chain OSVault to
an implementation that exposes mint(uint256), asset(), and oToken().

- Remove vm.skip(true) now that 026_VaultUpgrade.s.sol is in place
- Fix _ensureVaultLiquidity to use additive deal (add on top of existing
  balance rather than replace it), matching the OETH/OETHBase pattern.
  The existing vault balance may already be fully allocated to prior
  claimable requests and must not be overwritten.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…oke tests

- Add CurvePoolBoosterFactory and CurvePoolBoosterPlainOETH address
  constants to Mainnet library in Addresses.sol
- Add shared setup forking mainnet and instantiating live contracts
- Add 11 factory tests: view functions (governor, strategist, registry,
  pool booster list/mapping, address computation, salt encoding) and
  mutative ops (create booster, remove booster)
- Add 13 plain booster tests: view functions (rewardToken, gauge, fee,
  campaignRemoteManager, votemarket, targetChainId) and mutative ops
  (createCampaign, manageCampaign, closeCampaign)
…oyment JSONs

Add contract addresses for automation safe modules (Base and mainnet),
BRIDGED_WOETH, BRIDGED_WOETH_STRATEGY_PROXY, and pool booster contracts
to the deployment registry so smoke tests can resolve them via the
DeployManager resolver instead of hardcoded addresses.

Remove CurvePoolBoosterFactory and CurvePoolBoosterPlainOETH from
Addresses.sol since they now live in the deployment registry.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add smoke tests for BaseBridgeHelperModule, EthereumBridgeHelperModule,
and ClaimBribesSafeModule covering both view functions and mutative flows.

BaseBridgeHelperModule (14 tests): depositWOETH, depositWOETHAndClaimWithdrawal,
depositWETHAndRedeemWOETH, bridgeWETHToEthereum, bridgeWOETHToEthereum,
depositWETHAndBridgeWOETH, claimAndBridgeWETH.

EthereumBridgeHelperModule (11 tests): mintAndWrap, bridgeWOETHToBase,
bridgeWETHToBase, mintWrapAndBridgeToBase. Three functions not yet in the
deployed bytecode (unwrapAndRequestWithdrawal, claimWithdrawal,
claimAndBridgeToBase) are omitted until the contract is redeployed.

ClaimBribesSafeModule: tests skip gracefully if the contract is not yet
deployed at the registered address.

All contracts resolved via DeployManager resolver, not hardcoded addresses.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…lver

Replace hardcoded Mainnet.CurvePoolBoosterFactory and
Mainnet.CurvePoolBoosterPlainOETH addresses with resolver.resolve() calls,
consistent with the pattern used across all smoke tests.

Also clean up the unused CrossChain import and the aliased import of
CurvePoolBoosterFactory, and replace Mainnet.CurvePoolBoosterPlainOETH
references in assertions with address(curvePoolBoosterPlain).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…e, Metropolis, Merkl, and CentralRegistry

Add smoke tests across Sonic, Mainnet, and Base for all non-Curve pool booster
contracts. Register factory, registry, and representative booster addresses in
deployment JSONs for each chain.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add smoke test coverage for the AerodromeAMOStrategy on Base chain,
verifying that the live deployment (strategy + pool + gauge) is healthy.

- ViewFunctions (23 tests): immutables, configuration, position state, gauge staking
- Deposit (6 tests): checkBalance increases, auto-rebalance when in range, access control
- Rebalance (8 tests): no-swap/quoter-based rebalance, LP restaked, no residual tokens
- Withdraw (8 tests): partial withdraw, withdrawAll, full lifecycle, access control
- CollectRewards (2 tests): harvester can collect, access control

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Validate deployment health of CrossChainMasterStrategy via DeployManager/Resolver
with view function checks, deposit, withdraw, balance check, and token received tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Validate deployment health of the remote strategy on Base chain (counterpart
to the existing CrossChainMasterStrategy smoke tests on mainnet). Covers view
functions, deposit/withdraw relay flows, balance updates, and relay validation
guards.

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

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add smoke test suites for three CurveAMO strategy deployments:
- OETH Curve AMO (mainnet) — CurveAMOStrategy at 0xba0e352
- OUSD Curve AMO (mainnet) — CurveAMOStrategy at 0x26a02ec
- superOETHb Curve AMO (Base) — BaseCurveAMOStrategy at 0x9cfcAF8

Each suite covers ViewFunctions, Deposit, Withdraw, Rebalance
(mintAndAddOTokens, removeAndBurnOTokens, removeOnlyAssets), and
CollectRewards. Rebalance tests use dynamic pool tilting helpers
that read current pool state to ensure correct preconditions.

Also adds resolver entries to deployments-1.json and deployments-8453.json.

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

Add smoke tests for SonicSwapXAMOStrategy (Deposit, Withdraw, Rebalance,
CollectRewards, ViewFunctions) and register the strategy proxy in
deployments-146.json. Remove all RevertWhen tests from AerodromeAMO and
SwapXAMO smoke suites since access control and input validation belong
in unit tests, not smoke tests. Update the smoke-test skill to enforce
this rule.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Lodestar API client (v1.38.0) Accept header allows JSON fallback,
causing ERR_ENCODING_INVALID_DATA when the beacon node returns binary
SSZ data with a JSON content-type. Use direct HTTP fetch with SSZ-only
Accept header and ArrayBuffer reading to avoid text decoding issues.
Add a standalone Foundry CI pipeline (fmt, build, unit-tests, coverage,
fork-tests and smoke-tests per chain). Fork/smoke jobs dynamically
discover test directories by grepping for chain-specific fork functions,
requiring zero maintenance as new tests are added. Scheduled daily cron
runs fork/smoke tests to catch on-chain state changes.

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

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@clement-ux clement-ux self-assigned this Mar 20, 2026
clement-ux and others added 6 commits March 20, 2026 16:17
- PoolBoosterMerkl → PoolBoosterMerklV2 (BeaconProxy pattern with initialize)
- SonicSwapXAMOStrategy constructor reduced to 2 params (oToken/asset from vault)
- CompoundingStakingSSVStrategy constructor removed _ssvToken param
- registerSsvValidators/registerSsvValidator removed ssvAmount param
- depositSSV/withdrawSSV replaced by migrateClusterToETH
- manageBribes now requires selectedPoolBoosters array
- ISwapXPair/ISwapXGauge renamed to IAlgebraPair/IAlgebraGauge
- snapBalances/verifyBalances now onlyRegistrator
- CCTPMessageTransmitterMock2 constructor takes peerDomainId
- MockERC4626Vault/MockSSVNetwork extended for new interfaces
- Smoke tests use low-level calls for V1/V2 compatibility
…rom mocha

- soldeer is now a forge subcommand, not a standalone binary
- beaconProofsFixture.js ran main() when loaded by mocha during coverage
- Skip aerodrome strategy in coverage to avoid stack-too-deep errors
- Replace /bin/zsh with /bin/bash in BeaconRoots FFI calls for Ubuntu runners
- Add forge build to foundry-setup action so deploy script artifacts exist for smoke tests
- Add .gitkeep to scripts/deploy/base/ so the directory is tracked in git

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

1 participant