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.
This commit is contained in:
defiQUG
2026-04-12 18:21:05 -07:00
parent 8ec6af94d5
commit 2b52cc6e32
146 changed files with 2010 additions and 423 deletions

View File

@@ -0,0 +1,140 @@
#!/usr/bin/env python3
"""Report Solidity contracts that are not reachable from current tests or scripts."""
from __future__ import annotations
import argparse
import json
import re
import sys
from collections import Counter
from pathlib import Path
EXCLUDED_PARTS = {"artifacts", "broadcast", "cache", "lib", "node_modules", "out"}
IMPORT_RE = re.compile(r'^\s*import\s+(?:\{[^}]+\}\s+from\s+)?["\']([^"\']+)["\'];', re.M)
def discover_sources(repo_root: Path) -> dict[str, Path]:
return {
path.relative_to(repo_root).as_posix(): path
for path in repo_root.rglob("*.sol")
if path.is_file() and not any(part in EXCLUDED_PARTS for part in path.parts)
}
def resolve_import(importer: Path, import_path: str, repo_root: Path) -> str | None:
if import_path.startswith(("./", "../")):
target = (importer.parent / import_path).resolve()
try:
return target.relative_to(repo_root).as_posix()
except ValueError:
return None
if import_path.startswith("@emoney/"):
return f"contracts/emoney/{import_path[len('@emoney/'):]}"
return None
def build_graph(repo_root: Path, files: dict[str, Path]) -> tuple[dict[str, list[str]], dict[str, set[str]]]:
imports: dict[str, list[str]] = {}
inbound: dict[str, set[str]] = {rel: set() for rel in files}
for rel_path, file_path in files.items():
text = file_path.read_text(errors="ignore")
resolved_targets: list[str] = []
for import_path in IMPORT_RE.findall(text):
target = resolve_import(file_path, import_path, repo_root)
if target and target in files:
resolved_targets.append(target)
inbound[target].add(rel_path)
imports[rel_path] = resolved_targets
return imports, inbound
def walk_reachable(imports: dict[str, list[str]], roots: list[str]) -> set[str]:
seen: set[str] = set()
stack = list(roots)
while stack:
current = stack.pop()
if current in seen:
continue
seen.add(current)
stack.extend(imports.get(current, []))
return seen
def create_report(repo_root: Path) -> dict[str, object]:
files = discover_sources(repo_root)
imports, inbound = build_graph(repo_root, files)
contract_files = sorted(rel for rel in files if rel.startswith("contracts/"))
root_files = sorted(rel for rel in files if rel.startswith(("test/", "script/")))
reachable = walk_reachable(imports, root_files)
unreachable = [rel for rel in contract_files if rel not in reachable]
no_inbound = [rel for rel in contract_files if not inbound[rel]]
unreachable_by_bucket = Counter(path.split("/")[1] for path in unreachable)
no_inbound_by_bucket = Counter(path.split("/")[1] for path in no_inbound)
return {
"repoRoot": repo_root.as_posix(),
"summary": {
"contractsTotal": len(contract_files),
"rootsTotal": len(root_files),
"contractsReachableFromTestsOrScripts": len(contract_files) - len(unreachable),
"contractsUnreachableFromTestsOrScripts": len(unreachable),
"contractsWithNoLocalInboundRefs": len(no_inbound),
},
"unreachableByBucket": dict(unreachable_by_bucket.most_common()),
"noInboundByBucket": dict(no_inbound_by_bucket.most_common()),
"unreachableContracts": unreachable,
"contractsWithNoLocalInboundRefs": no_inbound,
}
def print_text(report: dict[str, object]) -> None:
summary = report["summary"]
print(f"repo root: {report['repoRoot']}")
print(f"contracts total: {summary['contractsTotal']}")
print(f"tests/scripts roots total: {summary['rootsTotal']}")
print(f"contracts reachable from tests or scripts: {summary['contractsReachableFromTestsOrScripts']}")
print(f"contracts unreachable from tests or scripts: {summary['contractsUnreachableFromTestsOrScripts']}")
print(f"contracts with no local inbound refs: {summary['contractsWithNoLocalInboundRefs']}")
print()
print("Unreachable by top-level bucket:")
for bucket, count in report["unreachableByBucket"].items():
print(f" {bucket}: {count}")
print()
print("Archive candidates (unreachable from current tests/scripts):")
for contract in report["unreachableContracts"]:
print(f" {contract}")
print()
print("Note: unreachable does not prove safe deletion; it only means this repo's current Solidity tests/scripts do not import the file.")
def parse_args(argv: list[str]) -> argparse.Namespace:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--json", action="store_true", help="emit machine-readable JSON")
return parser.parse_args(argv)
def main(argv: list[str]) -> int:
args = parse_args(argv)
repo_root = Path(__file__).resolve().parents[2]
report = create_report(repo_root)
if args.json:
json.dump(report, sys.stdout, indent=2)
sys.stdout.write("\n")
return 0
print_text(report)
return 0
if __name__ == "__main__":
raise SystemExit(main(sys.argv[1:]))

324
scripts/forge/scope.sh Executable file
View File

@@ -0,0 +1,324 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
REPO_ROOT=$(cd "$SCRIPT_DIR/../.." && pwd)
declare -A ROOT_SCRIPT_SCOPE_ALIASES=(
["DeployAddressMapper.s.sol"]="utils"
["DeployAddressMapperOtherChain.s.sol"]="utils"
["DeployCCIPRouter.s.sol"]="ccip"
["DeployCCIPSender.s.sol"]="ccip"
["DeployCCIPSenderMainnet.s.sol"]="ccip"
["DeployCCIPReceiver.s.sol"]="ccip"
["DeployCCIPReceiverMainnet.s.sol"]="ccip"
["DeployCCIPRelay.s.sol"]="relay"
["DeployCCIPWETH9Bridge.s.sol"]="ccip"
["DeployCCIPWETH10Bridge.s.sol"]="ccip"
["DeployComplianceRegistry.s.sol"]="compliance"
["DeployCompliantUSDC.s.sol"]="tokens"
["DeployCompliantUSDT.s.sol"]="tokens"
["DeployCWAssetReserveVerifier.s.sol"]="bridge/integration"
["DeployCWReserveVerifier.s.sol"]="bridge/integration"
["DeployFeeCollector.s.sol"]="utils"
["DeployGenericStateChannelManager.s.sol"]="channels"
["DeployMainnetTether.s.sol"]="tether"
["DeployMirrorManager.s.sol"]="mirror"
["DeployMulticall.s.sol"]="utils"
["DeployMultiSig.s.sol"]="governance"
["DeployOfficialUSDC138.s.sol"]="tokens"
["DeployOfficialUSDT138.s.sol"]="tokens"
["DeployOracle.s.sol"]="oracle"
["DeployPaymentChannelManager.s.sol"]="channels"
["DeployTokenRegistry.s.sol"]="utils"
["DeployTransactionMirror.s.sol"]="mirror"
["DeployWETH.s.sol"]="tokens"
["DeployWETH10.s.sol"]="tokens"
["DeployWETHWithCCIP.s.sol"]="full"
)
usage() {
cat <<'EOF'
Usage:
bash scripts/forge/scope.sh list
bash scripts/forge/scope.sh build [scope] [forge build args...]
bash scripts/forge/scope.sh test [scope] [forge test args...]
bash scripts/forge/scope.sh script [scope] <script-target> [forge script args...]
bash scripts/forge/scope.sh orphans [--json]
Examples:
bash scripts/forge/scope.sh build treasury
bash scripts/forge/scope.sh test flash --match-path 'test/flash/*.t.sol'
bash scripts/forge/scope.sh script bridge/trustless script/bridge/trustless/DeployTrustlessBridge.s.sol:DeployTrustlessBridge --rpc-url "$RPC_URL_138"
FORGE_SCOPE=vault bash scripts/forge/scope.sh test --match-path 'test/vault/*.t.sol'
Notes:
- Omit [scope] to use FORGE_SCOPE, otherwise default to 'full'.
- 'full' preserves the historical repo-wide Forge behavior.
- Any other scope is resolved relative to contracts/, for example:
treasury -> contracts/treasury
bridge/trustless -> contracts/bridge/trustless
- If no explicit scope is given, the runner tries to infer one from
script/test/build paths and common root-level deployment script names.
EOF
}
die() {
echo "error: $*" >&2
exit 1
}
info() {
echo "$*" >&2
}
resolve_scope() {
local raw="${1:-${FORGE_SCOPE:-full}}"
raw="${raw#contracts/}"
raw="${raw#/}"
if [[ -z "$raw" ]]; then
raw="full"
fi
printf '%s\n' "$raw"
}
scope_label() {
printf '%s\n' "${1//\//-}"
}
scope_exists() {
local scope="$1"
[[ "$scope" == "full" || -d "$REPO_ROOT/contracts/$scope" ]]
}
infer_scope_from_script_alias() {
local raw="${1%%:*}"
local base
base=$(basename "$raw")
if [[ -n "${ROOT_SCRIPT_SCOPE_ALIASES[$base]:-}" ]]; then
printf '%s\n' "${ROOT_SCRIPT_SCOPE_ALIASES[$base]}"
return 0
fi
return 1
}
infer_scope_from_script_imports() {
local raw="${1%%:*}"
local script_path="$REPO_ROOT/${raw#./}"
[[ -f "$script_path" ]] || return 1
python3 - "$REPO_ROOT" "$script_path" <<'PY'
from pathlib import Path
import re
import sys
repo_root = Path(sys.argv[1]).resolve()
script_path = Path(sys.argv[2]).resolve()
text = script_path.read_text(errors="ignore")
imports = re.findall(r'^\s*import\s+(?:\{[^}]+\}\s+from\s+)?["\']([^"\']+)["\'];', text, re.M)
for imp in imports:
if not imp.startswith(("./", "../")):
continue
candidate = (script_path.parent / imp).resolve()
try:
rel = candidate.relative_to(repo_root).as_posix()
except ValueError:
continue
if not rel.startswith("contracts/"):
continue
scope = rel[len("contracts/"):]
if candidate.is_file():
scope = str(Path(scope).parent).replace("\\", "/")
scope = scope.strip(".")
while scope:
if (repo_root / "contracts" / scope).is_dir():
print(scope)
raise SystemExit(0)
scope = scope.rsplit("/", 1)[0] if "/" in scope else ""
raise SystemExit(1)
PY
}
extract_scope_from_path() {
local raw="${1%%:*}"
raw="${raw#./}"
case "$raw" in
contracts/*)
raw="${raw#contracts/}"
;;
test/*)
raw="${raw#test/}"
;;
script/*)
raw="${raw#script/}"
;;
*)
return 1
;;
esac
local candidate
for candidate in "$raw" "${raw#deploy/}"; do
[[ -n "$candidate" ]] || continue
if [[ -d "$REPO_ROOT/contracts/$candidate" ]]; then
printf '%s\n' "$candidate"
return 0
fi
local probe="${candidate%/*}"
if [[ "$probe" != "$candidate" ]]; then
while [[ -n "$probe" ]]; do
if [[ -d "$REPO_ROOT/contracts/$probe" ]]; then
printf '%s\n' "$probe"
return 0
fi
if [[ "$probe" != *"/"* ]]; then
break
fi
probe="${probe%/*}"
done
fi
done
if [[ "$1" == script/* ]]; then
infer_scope_from_script_alias "$1" && return 0
infer_scope_from_script_imports "$1" && return 0
fi
return 1
}
infer_scope_from_args() {
local arg inferred
for arg in "$@"; do
inferred=$(extract_scope_from_path "$arg" || true)
if [[ -n "$inferred" ]]; then
printf '%s\n' "$inferred"
return 0
fi
done
return 1
}
list_scopes() {
(
cd "$REPO_ROOT"
echo "full"
find contracts -mindepth 1 -maxdepth 2 -type d | sed 's#^contracts/##' | sort
)
}
prepare_scope_env() {
local scope="$1"
local command="$2"
if [[ "$scope" == "full" ]]; then
return 0
fi
local src_dir="contracts/$scope"
[[ -d "$REPO_ROOT/$src_dir" ]] || die "unknown scope '$scope' (expected directory '$src_dir')"
local label
label=$(scope_label "$scope")
export FOUNDRY_SRC="$src_dir"
export FOUNDRY_OUT="out/scopes/$label"
export FOUNDRY_CACHE_PATH="cache/scopes/$label"
export FOUNDRY_SPARSE_MODE="${FOUNDRY_SPARSE_MODE:-true}"
if [[ "$command" == "test" ]]; then
local test_dir="test/$scope"
if [[ -d "$REPO_ROOT/$test_dir" ]]; then
export FOUNDRY_TEST="$test_dir"
fi
fi
if [[ "$command" == "script" ]]; then
local script_dir="script/$scope"
if [[ -d "$REPO_ROOT/$script_dir" ]]; then
export FOUNDRY_SCRIPT="$script_dir"
fi
fi
}
main() {
cd "$REPO_ROOT"
local command="${1:-}"
[[ -n "$command" ]] || {
usage
exit 1
}
shift || true
case "$command" in
help|-h|--help)
usage
;;
list)
list_scopes
;;
orphans)
exec python3 scripts/forge/report-contract-reachability.py "$@"
;;
build|test|script)
local scope=""
if [[ $# -gt 0 && "$1" != --* ]]; then
local maybe_scope
maybe_scope=$(resolve_scope "$1")
if scope_exists "$maybe_scope"; then
scope="$maybe_scope"
shift
fi
fi
if [[ -z "$scope" ]]; then
if [[ -n "${FORGE_SCOPE:-}" ]]; then
scope=$(resolve_scope)
else
scope=$(infer_scope_from_args "$@" || printf 'full\n')
fi
fi
prepare_scope_env "$scope" "$command"
if [[ "$scope" == "full" ]]; then
info "Forge scope: full repo"
else
info "Forge scope: $scope"
info " src=$FOUNDRY_SRC out=$FOUNDRY_OUT cache=$FOUNDRY_CACHE_PATH"
[[ -n "${FOUNDRY_TEST:-}" ]] && info " test=$FOUNDRY_TEST"
[[ -n "${FOUNDRY_SCRIPT:-}" ]] && info " script=$FOUNDRY_SCRIPT"
fi
case "$command" in
build)
if [[ "$scope" == "full" ]]; then
exec forge build "$@"
fi
exec forge build --skip test --skip script "$@"
;;
test)
if [[ "$scope" != "full" && -z "${FOUNDRY_TEST:-}" ]]; then
die "scope '$scope' has no matching test/<scope> directory"
fi
exec forge test "$@"
;;
script)
[[ $# -gt 0 ]] || die "script command requires a script target, e.g. script/treasury/DeployTreasuryExecutor138.s.sol:DeployTreasuryExecutor138"
exec forge script "$@"
;;
esac
;;
*)
die "unknown command '$command'"
;;
esac
}
main "$@"