Skip to content

The mainnet confirmation modal the README promises is unreachable dead code #1157

Description

@Ejirowebfi

Area: Frontend — hooks/useMainnetConfirmation.ts, components/UI/MainnetConfirmationModal.tsx
Severity: Critical
Component: Mainnet-destructive-action safety gate

Description

useMainnetConfirmation()'s requestDeployment(params, onConfirm) is the only code
path that opens MainnetConfirmationModal: it checks isMainnet() and shows the modal,
or calls onConfirm() straight through on testnet. A full-tree search shows
requestDeployment is referenced only inside useMainnetConfirmation.ts itself, and
MainnetConfirmationModal is referenced only in its own file, a barrel re-export
(components/UI/index.ts), and its Storybook story — never from any form.

CreateToken.tsxTokenForm.tsx (the actual create-token submit path) calls
onSubmit(formData) directly, with no mainnet gate of any kind. MintForm.tsx,
BurnForm.tsx, SetMetadataForm.tsx, and AdminPanel.tsx all use the generic,
network-agnostic ConfirmModal — the same "are you sure?" dialog shown on testnet and
mainnet alike. useNetworkGuard only blocks a Freighter-vs-app network mismatch; it
does nothing to add friction to a mainnet-destructive action when Freighter and the app
already agree they're on mainnet.

The README states, as a named feature: "Network Mismatch Protection... with an explicit
confirmation modal before mainnet-destructive actions."
That control does not exist in
the shipped app.

Failure Scenario

A user connected to mainnet (Freighter and the app in agreement — no mismatch) deploys
a token, mints extra supply, burns tokens, or updates metadata. They see only the
generic ConfirmModal, identical to what testnet users see — no mainnet-specific
warning, no "type the token symbol to confirm," no extra friction of any kind before a
real-money-destructive transaction is built and sent to Freighter for signing.

Why Critical

It is the one safety control the README calls out by name, specifically for mainnet,
and it is entirely unreachable from any real user flow. Anyone relying on the README's
description of the app's safety posture — an auditor, a new team member, a user
deciding whether to trust the app with mainnet funds — is being told about a control
that isn't wired in.

Tasks

  • Wire useMainnetConfirmation().requestDeployment (or an equivalent shared hook)
    into every mutating submit path that can run on mainnet: TokenForm.tsx
    (create), MintForm.tsx, BurnForm.tsx, SetMetadataForm.tsx,
    AdminPanel.tsx (fee/pause/whitelist/admin-rotation/upgrade actions).
  • Decide whether MainnetConfirmationModal should replace ConfirmModal on
    mainnet across the board, or ConfirmModal should grow a "mainnet mode" that
    adds the same friction (e.g. type-to-confirm) — pick one and apply it
    consistently rather than leaving two divergent confirmation UIs.
  • Add a lint rule, code-review checklist item, or a test asserting every
    contract.call write-path component imports and invokes the mainnet
    confirmation gate, so a new form can't reintroduce this gap silently.
  • Add component/integration tests: on mainnet, submitting each form opens the
    mainnet-specific confirmation before any transaction is built; on testnet, the
    generic flow is used.

Acceptance Criteria

  • Every mutating action reachable on mainnet (create, mint, burn, set metadata,
    admin actions) is provably gated by a mainnet-specific confirmation step in an
    automated test, not just by manual inspection.
  • No mutating Soroban transaction can be built and handed to Freighter for
    mainnet signing without the user passing through that gate first.
  • The README's claim about the confirmation modal is either now true (preferred)
    or corrected to describe the actual behavior.


Filed from the August 2026 critical-issues audit — see CRITICAL_ISSUES.md for the full summary table.

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 rewardThird CampaignCampaign: Third CampaignauditFrom the ISSUES.md codebase auditbugSomething isn't workingfrontendsecurityseverity: criticalFunds/consensus/permanent-brick risk

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions