Context
Read-only source-level audit of develop (2026-06-01). develop is dfx01-green; these are not caught by the gates. flutter not run in the audit env; items are code-evidenced (file:line) with confidence. Bundled: KYC routing dead-ends + raw-error UX. Split into PRs as appropriate.
Related in-flight: #604 (countryAndTINs + phone validator — excluded here), #605 (registration confirm-and-sign page — reworks kyc_page_manager.dart/kyc_cubit.dart; see notes below). Suggested label: bug.
Findings
K1 — KycStep.dfxApproval routes to a blank white Scaffold (silent dead-end) — HIGH
K2 — Financial-data submit failure is a dead-end and discards all answers — HIGH
K3 — swissTaxResidence hardcoded true for all registrations — HIGH
K4 — Raw e.toString() exception text shown to users across KYC steps — MEDIUM
K5 — KycPending/KycUnsupportedStepFailure show raw enum/wire identifiers — LOW
Checked & clean: ident uses the Sumsub native SDK with an access token (not a loaded URL/JS; token not logged); nationality/country force-unwraps are validator-guarded; link-wallet missing-userData has a dedicated retry page.
Context
Read-only source-level audit of
develop(2026-06-01).developis dfx01-green; these are not caught by the gates.flutternot run in the audit env; items are code-evidenced (file:line) with confidence. Bundled: KYC routing dead-ends + raw-error UX. Split into PRs as appropriate.Related in-flight: #604 (countryAndTINs + phone validator — excluded here), #605 (registration confirm-and-sign page — reworks
kyc_page_manager.dart/kyc_cubit.dart; see notes below). Suggested label:bug.Findings
K1 —
KycStep.dfxApprovalroutes to a blank whiteScaffold(silent dead-end) — HIGHlib/screens/kyc/kyc_page_manager.dart:61-76: theKycSuccessstep switch has cases for email/legalDisclaimer/registration/linkWallet/nationality/twoFa/ident/financialData but noKycStep.dfxApproval→ falls through to(_) => const Scaffold()(line 75)._continueKyccan emitKycSuccess(currentStep: KycStep.dfxApproval)(kyc_cubit.dart:247-258,_mapStepNamemapsdfxApproval).PendingReviewpath is guarded withKycUnsupportedStepFailure; this path is not).dfxApprovalcase — still reproducible. Test-gap: no test drivesKycSuccess(dfxApproval); the(_) => Scaffold()fallback hides the gap from exhaustiveness checks.K2 — Financial-data submit failure is a dead-end and discards all answers — HIGH
lib/screens/kyc/steps/financial_data/cubits/kyc_financial_data_cubit.dart:79-92replacesKycFinancialDataLoadedSuccess(which holds the user'sresponses) withKycFinancialDataFailureon submit error;subpages/kyc_financial_data_failure_page.darthas only an AppBar — no retry button, no recovery — and the answers are gone from state.K3 —
swissTaxResidencehardcodedtruefor all registrations — HIGHlib/screens/kyc/steps/registration/kyc_registration_page.dart:280swissTaxResidence: true,(no UI control, no country logic); flows into the EIP-712-signed envelope (eip712_signer.dart:62) and the request DTO.+ swissTaxResidence: true— please confirm whether feat(kyc): replace registration form with confirm-and-sign page #605 actually resolves this or carries it forward.K4 — Raw
e.toString()exception text shown to users across KYC steps — MEDIUMnationality cubit:26(setNationalityFailed),link_wallet cubit:30,32(registrationFailed),ident cubit:69+kyc_ident_page.dart:61(raw-appended),financial_data cubit:36,90,kyc_cubit.dart:54,220(KycFailurePage). Users see e.g.Exception: ... Status: 500 {body}/type 'Null' is not a subtype.... i18n gap + internal detail leak.K5 —
KycPending/KycUnsupportedStepFailureshow raw enum/wire identifiers — LOWkyc_pending_page.dart:46,54uses Dart enum.name("DFXAPPROVAL","FINANCIALDATA");kyc_page_manager.dart:54-56injects the raw API step value. Not localized/human-readable.Checked & clean: ident uses the Sumsub native SDK with an access token (not a loaded URL/JS; token not logged); nationality/country force-unwraps are validator-guarded; link-wallet missing-userData has a dedicated retry page.