Skip to content

No reproducible-build / supply-chain verification — deployed testnet WASM hash cannot be independently confirmed against published source #59

Description

@chonilius

Overview

README.md's "Deployed on Stellar testnet" section publishes three specific contract IDs as if they're canonical, verifiable references to this repository's current source:

Contract Contract ID
mergefi-escrow CAY77D2SFDVQYONSPYHOEWARE3UIWQDYHWWI2WXNPFBLBKR2Q4GEWXFB
mergefi-milestones CBBRLSL6TM6XCNP2XBVT4GFHJ3NNPFKI2BCZQJ4U3TI7GV7DO2F2HG6F
mergefi-maintenance-pool CD46U7WTEM2I77TXQI2VIBRQXOHEFEYYR2XFA7OVGTXX5M2F7Z3ZQOX2

Nothing in this repository lets an independent third party confirm that the WASM bytecode actually running at those three addresses corresponds, byte-for-byte, to the Rust source currently in contracts/*/src/. Concretely:

  1. The dependency version constraint isn't pinned. Cargo.toml's soroban-sdk = "26.1.0" (Cargo.toml:16) is a caret requirement (^26.1.0 under Cargo's default semantics), permitting any 26.x.y with x.y >= 1.0 at resolution time — a plain cargo build without a committed, respected Cargo.lock (or in any CI/build environment that runs cargo update first) could compile against a meaningfully different soroban-sdk patch/minor version than whatever was used to produce the deployed bytecode, potentially changing generated code, host-interface behavior, or the resulting WASM hash, without any source-level change being visible in a diff.
  2. The release profile has no documented, pinned toolchain. Cargo.toml's [profile.release] (lines 18-27) sets opt-level = "z", lto = true, codegen-units = 1, and other settings that affect codegen — but LLVM/rustc codegen is not guaranteed bit-for-bit reproducible across different rustc/LLVM versions even with identical source and identical Cargo.lock. The README does state the repo "was built/tested against rustc 1.95.0" (README, "Prerequisites" section), but this is descriptive prose, not a rust-toolchain.toml or equivalent enforced pin — nothing in the repository actually requires a build to use that exact version.
  3. No published WASM-hash-to-source-commit mapping. There's no equivalent of a "built from commit <sha> with rustc <version>, resulting hash <hash>" record anywhere — a user who wants to verify the deployed CAY77D... bytecode genuinely corresponds to, say, the current main branch (or any specific historical commit) has no documented recipe to reproduce that exact WASM and compare hashes.

This matters specifically because the README invites this kind of trust: publishing contract IDs as a concrete, checkable reference implies they're meant to be checkable, and a bounty-escrow platform handling real sponsor funds is exactly the kind of application where "does the deployed bytecode match the published, presumably-audited source" is a first-order security question, not a nice-to-have — this is the standard supply-chain concern any smart-contract audit would flag, and it's currently unaddressed here.

Requirements

  • Commit an exact rust-toolchain.toml pinning the specific rustc version (1.95.0, per the README's current prose claim, or whatever is current at implementation time) so rustup automatically selects the correct toolchain for anyone building from this repo, rather than relying on the README text being read and manually followed.
  • Confirm Cargo.lock is checked in (already appears to be, per the repository listing) and document explicitly in the README that cargo build/make build must be run without cargo update first, to respect the locked soroban-sdk version exactly.
  • Document a concrete reproducible-build recipe: given a specific git commit, the exact sequence of commands (toolchain install, cargo build --target wasm32v1-none --release -p ..., optionally stellar contract optimize) that should produce byte-identical WASM to what's deployed, plus the actual resulting hash for each of the three currently-deployed testnet contracts, so a reader can verify today's claim without needing to first trust it.
  • Consider whether soroban-sdk's dependency itself should be pinned to an exact version ("=26.1.0") rather than a caret range, removing one further axis of non-determinism, independent of Cargo.lock being respected.

Acceptance Criteria

  • rust-toolchain.toml added, pinning the exact rustc version
  • README documents the reproducible-build recipe and warns against cargo update before building against a specific deployed instance
  • Actual WASM hashes for the three currently-deployed testnet contracts published in the README alongside their contract IDs, with the exact commit/toolchain combination that produces them
  • Decision recorded on whether soroban-sdk's version constraint should be tightened from a caret range to an exact pin

Additional Notes

  • Precise references: Cargo.toml:16 (soroban-sdk = "26.1.0", caret range); Cargo.toml:18-27 (release profile settings affecting codegen determinism); README's "Prerequisites" section (the unpinned, prose-only rustc 1.95.0 claim); README's "Deployed on Stellar testnet" section (the contract-ID table this issue is about making independently verifiable).
  • This is scoped as security/documentation rather than pure performance, distinct from the existing issue "Investigate WASM binary size and compute-cost effectiveness of current release profile settings" — that issue is about optimizing the release profile's output size/cost; this issue is about verifying that whatever the profile produces is reproducible and matches what's actually deployed, an orthogonal concern (a profile can be both well-optimized and non-reproducible, or vice versa).
  • Cross-references: the existing WASM-size/compute-cost issue (shares the same [profile.release] settings as its subject matter, from a different angle); Research and design a safe upgrade / storage-migration path (contracts currently have none) #15 (upgrade/migration path — any future upgrade mechanism's trustworthiness also depends on being able to verify what's being upgraded to, making reproducible builds a prerequisite for a trustworthy upgrade story, not just today's deploy-once model).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial Campaign | FWC26Campaign: Official Campaign | FWC26Third CampaignCampaign: Third CampaigndocumentationImprovements or additions to documentationsecuritySecurity-related issuevery hardVery difficult task, expert-level effort required

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions