Files
smom-dbis-138/docs/architecture/FOUNDRY_MONOREPO_SCOPES.md
defiQUG 2b52cc6e32 refactor(archive): move historical contracts and adapters to archive directory
- Archived multiple non-EVM adapters (Algorand, Hedera, Tron, TON, Cosmos, Solana) and compliance contracts (IndyVerifier) to `archive/solidity/contracts/`.
- Updated documentation to reflect the historical status of archived components.
- Adjusted `foundry.toml` and `README.md` for clarity on historical dependencies and configurations.
- Enhanced Makefile and package.json scripts for improved contract testing and building processes.
- Removed obsolete contracts (AlltraCustomBridge, CommodityCCIPBridge, ISO4217WCCIPBridge, VaultBridgeAdapter) from the main directory.
- Updated implementation reports to indicate archived status for various components.
2026-04-12 18:21:05 -07:00

4.2 KiB

Foundry Monorepo Scopes

Why this exists

smom-dbis-138 has grown beyond the shape of a single small Foundry package:

  • 258 Solidity files under contracts/
  • 120 Solidity tests under test/
  • 133 Solidity scripts under script/

In practice that means the root repo-wide forge build is a compatibility path, not a good inner-loop default. A clean full build in this workspace did not finish within 120s, while scoped builds did:

  • treasury scoped build: about 17s
  • flash scoped build: about 44s
  • treasury scoped test compile: 39 files instead of 338

Use the scope runner for day-to-day work:

bash scripts/forge/scope.sh list
bash scripts/forge/scope.sh build treasury
bash scripts/forge/scope.sh test treasury
bash scripts/forge/scope.sh script bridge/trustless script/bridge/trustless/DeployTrustlessBridge.s.sol:DeployTrustlessBridge --rpc-url "$RPC_URL_138"
bash scripts/forge/scope.sh script script/DeployOracle.s.sol:DeployOracle --rpc-url "$RPC_URL_138"

You can also drive it through npm scripts:

FORGE_SCOPE=treasury pnpm run forge:build
FORGE_SCOPE=treasury pnpm run forge:test
pnpm run forge:script -- script/DeployOracle.s.sol:DeployOracle --rpc-url "$RPC_URL_138"
pnpm run forge:scope:list
pnpm run forge:orphans

Or through make:

make contracts SCOPE=treasury
make test SCOPE=bridge/trustless

Many shell deployment scripts in this repo now get scoped Forge automatically through shared shell bootstrap files:

  • scripts/lib/init.sh
  • scripts/lib/deployment/dotenv.sh
  • scripts/load-env.sh

At this point every shell script under scripts/ that invokes forge build, forge test, or forge script is covered by one of those shared paths or calls the scope runner directly.

How scopes work

The scope runner keeps the root foundry.toml for compatibility, but overrides the active package boundary via environment variables:

  • FOUNDRY_SRC=contracts/<scope>
  • FOUNDRY_TEST=test/<scope> when that directory exists
  • FOUNDRY_OUT=out/scopes/<scope>
  • FOUNDRY_CACHE_PATH=cache/scopes/<scope>
  • FOUNDRY_BROADCAST=broadcast/scopes/<scope>

This keeps artifact churn local to the subtree you are editing and prevents unrelated domains from dominating compile time.

When you omit the scope, the runner tries to infer it from:

  • contracts/<scope>/...
  • test/<scope>/...
  • script/<scope>/...
  • script/deploy/<scope>/... where <scope> maps back to contracts/<scope>/...
  • common root-level deployment scripts such as script/DeployOracle.s.sol, script/DeployWETH.s.sol, script/DeployMulticall.s.sol, and script/DeployCCIPRouter.s.sol

Full repo builds

Use the full repo intentionally:

forge build
forge test
pnpm run forge:build:full
pnpm run forge:test:full

That is the right choice for:

  • release validation
  • repo-wide refactors
  • remapping or compiler setting changes
  • compatibility checks before CI changes

Legacy contract archival

Use the reachability report before moving old Solidity out of contracts/:

python3 scripts/forge/report-contract-reachability.py
python3 scripts/forge/report-contract-reachability.py --json

The report highlights contracts that are unreachable from the repo's current Solidity tests or scripts. That is an archival queue, not proof that deletion is safe. Move those files in small batches and re-run the scoped build/test commands for the affected domain.

Archived Solidity that should stay out of the compile graph lives under archive/solidity/.

After the current archive passes, the reachability report is down to 29 unreachable contracts from 35, with the bridge bucket reduced to 5.

Best-practice rules for this repo

  1. Prefer scripts/forge/scope.sh for local work.
  2. Keep root forge build and forge test as explicit full-graph checks.
  3. Add new contracts under an existing domain whenever possible instead of expanding the root package mentally.
  4. When a subtree no longer has active tests or scripts, move it toward archive only after confirming it is not referenced by deployment runbooks or external repos.
  5. Avoid reintroducing broad compile paths in npm scripts, Make targets, or shell wrappers when a narrower scope is known.