Skip to content

🟠 One VITE_FACTORY_CONTRACT_ID shared across the network switcher β€” mainnet/testnet toggle points both networks at the same contractΒ #1016

Description

@Ejirowebfi

Area: Frontend Β· frontend/src/config/env.ts, config/stellar.ts, context/NetworkContext.tsx

Description

The UI offers a runtime testnet/mainnet switcher (persisted in localStorage), but
STELLAR_CONFIG.factoryContractId is a single value from VITE_FACTORY_CONTRACT_ID, applied to
whichever network is selected. Switching a testnet-configured build to mainnet makes the app issue
mainnet transactions against a contract ID that either doesn't exist on mainnet (confusing "contract
not found" failures) or β€” the dangerous case β€” does exist as an unrelated contract at the same ID,
against which users could be prompted to sign real-XLM transactions. The same applies to
VITE_TOKEN_WASM_HASH. Additionally, the hardcoded mainnet RPC endpoint
https://soroban-mainnet.stellar.org (config/stellar.ts:21) is not an SDF-operated public service
(SDF provides no public mainnet Soroban RPC), so mainnet mode is broken at the transport layer too.
The service-worker cache key derives from the single contract ID, compounding cross-network cache
confusion.

Tasks

  • Introduce per-network env vars (VITE_FACTORY_CONTRACT_ID_TESTNET / _MAINNET, same for the
    WASM hash) resolved through NETWORK_CONFIGS, with the misconfiguration screen listing exactly
    which network is missing configuration.
  • Disable (with explanation) the network switcher for any network whose contract ID is not
    configured, instead of switching into a broken state.
  • Make the mainnet RPC URL a required explicit env var (VITE_SOROBAN_RPC_URL_MAINNET) with
    documentation on choosing a provider, and validate reachability on startup (surfaced, not
    silent).
  • Include the active network in the service-worker cache version key alongside its own contract ID.
  • Update .env.example, vercel.json env docs, README, and the Vercel deploy button parameters.
  • Tests: network switch resolves the correct contract ID; unconfigured network cannot be selected;
    misconfiguration screen names the missing variable.

Acceptance criteria

  • Each network resolves its own contract ID, WASM hash, and RPC endpoint, proven by tests.
  • It is impossible to end up signing transactions on network A against network B's (or a missing)
    contract ID via the switcher.
  • Mainnet mode has an explicitly configured, documented RPC endpoint.

Issue 12 of 20 from the codebase audit tracked in ISSUES.md.

Metadata

Metadata

Assignees

Labels

GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial Campaign | FWC26Campaign: Official Campaign | FWC26auditFrom the ISSUES.md codebase auditseverity: highBroken core feature or exploitable abuse vector

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions