Problem Statement
starforge upgrade currently verifies that the deployed WASM hash matches the intended new bytecode (see closed issue #11), which protects against deploying the wrong bytes but says nothing about whether the new contract is actually safe to upgrade to. Soroban contract upgrades can silently break production state if a storage key changes type, a persistent storage entry is dropped, or a public function's signature changes in a way existing callers don't expect. There is currently no tooling in StarForge to catch this before an upgrade is executed on mainnet.
Proposed Solution
Add starforge upgrade analyze --current <old.wasm> --candidate <new.wasm>, which statically compares two compiled Soroban contracts and produces a structured upgrade-safety report:
- Interface diff: extract the contract's exported function spec (name, argument types, return type) from each WASM's embedded contract metadata (the same metadata already used by
starforge contract generate-bindings) and diff them, flagging removed functions, changed argument/return types, and changed function names as breaking changes; added functions and unchanged signatures are reported as non-breaking.
- Storage key diff: statically analyze both WASM binaries' storage access patterns (instance/persistent/temporary key literals and their associated value types, to the extent recoverable from the compiled contract's metadata) and flag storage keys that are removed, or whose associated type appears to change — since a type change on an existing persistent key is a common source of upgrade corruption.
- Risk classification: each finding is tagged
breaking, warning, or info, and the command exits non-zero if any breaking finding is present (suitable for CI gating an upgrade PR).
- Report output: human-readable table by default,
--format json for CI, and --output <file> to save a permanent record of the analysis alongside the upgrade for audit purposes.
Technical Scope
- New
src/utils/upgrade_analyzer.rs: WASM metadata extraction (reusing the existing contract-spec parsing used by bindings.rs/contract inspect), interface diff engine, best-effort storage key/type extraction, and risk classification rules.
- Extend
src/commands/upgrade.rs with the analyze subcommand.
- Because full storage-type recovery from compiled WASM without source is inherently best-effort, the report must clearly distinguish "confirmed from contract metadata" findings from "heuristic, verify manually" findings rather than presenting both with equal confidence.
- Tests using paired fixture contracts (built two ways from the existing templates: an additive-only change, and a deliberately breaking change to a function signature and a storage key) verifying the analyzer correctly classifies each.
Acceptance Criteria
- Running
analyze on two builds of the same template with only an added function reports zero breaking findings.
- Running
analyze on two builds where a public function's argument type changed reports it as breaking, naming the specific function.
--format json output validates against a documented JSON schema for downstream CI consumption.
- Exit code is non-zero exactly when a
breaking finding is present.
- Documentation includes a recommended CI snippet gating merges to an upgrade PR on
starforge upgrade analyze.
Estimated Scope
Approximately 700 lines of new Rust across the analyzer, CLI wiring, fixtures, and tests.
Problem Statement
starforge upgradecurrently verifies that the deployed WASM hash matches the intended new bytecode (see closed issue #11), which protects against deploying the wrong bytes but says nothing about whether the new contract is actually safe to upgrade to. Soroban contract upgrades can silently break production state if a storage key changes type, a persistent storage entry is dropped, or a public function's signature changes in a way existing callers don't expect. There is currently no tooling in StarForge to catch this before an upgrade is executed on mainnet.Proposed Solution
Add
starforge upgrade analyze --current <old.wasm> --candidate <new.wasm>, which statically compares two compiled Soroban contracts and produces a structured upgrade-safety report:starforge contract generate-bindings) and diff them, flagging removed functions, changed argument/return types, and changed function names as breaking changes; added functions and unchanged signatures are reported as non-breaking.breaking,warning, orinfo, and the command exits non-zero if anybreakingfinding is present (suitable for CI gating an upgrade PR).--format jsonfor CI, and--output <file>to save a permanent record of the analysis alongside the upgrade for audit purposes.Technical Scope
src/utils/upgrade_analyzer.rs: WASM metadata extraction (reusing the existing contract-spec parsing used bybindings.rs/contract inspect), interface diff engine, best-effort storage key/type extraction, and risk classification rules.src/commands/upgrade.rswith theanalyzesubcommand.Acceptance Criteria
analyzeon two builds of the same template with only an added function reports zerobreakingfindings.analyzeon two builds where a public function's argument type changed reports it asbreaking, naming the specific function.--format jsonoutput validates against a documented JSON schema for downstream CI consumption.breakingfinding is present.starforge upgrade analyze.Estimated Scope
Approximately 700 lines of new Rust across the analyzer, CLI wiring, fixtures, and tests.