Skip to content

Big Brother audit: 189 findings across 10 areas (94 user-visible / 100 code-bug, 9 high) #657

Description

@joshuakrueger-dfx

RealUnit (RealUnitCH/app) — Consolidated Bug-Audit Findings

Source: Big Brother test-agent run, 2026-06-03. 10 report-only audits over the Flutter app
at base commit 2702a2b. Each part = best (most complete) orchestrator run, per
fixer-iteration-1/fixer/fix-spec.md (cross-checked against fixer-repair-report.md).
All findings are report-only (no code was changed). Classifications USER-VISIBLE / CODE-BUG
are preserved exactly as each report labelled them.

Best run chosen per part

Part Audit Run dir Source artifact
1 Onboarding & Seed q-20260603-132637-47467-6 fix-spec.md
2 Auth & PIN q-20260603-132637-47467-5 fix-spec.md (full detail in audit-findings.md)
3 Dashboard/Home/Tx History q-20260603-142104-86882-4 fix-spec.md
4 Buy & Sell q-20260603-142104-86882-6 fixer-repair-report.md (fix-spec.md held method only)
5 KYC & Legal q-20260603-142104-86882-5 fix-spec.md
6 Receive & Wallet Address q-20260603-132637-47467-3 fix-spec.md
7 Hardware Wallet / BitBox q-20260603-132638-47467-9 fix-spec.md
8 Settings & Support q-20260603-132637-47467-1 fix-spec.md
9 Core packages q-20260603-132637-47467-4 fix-spec.md
10 Cross-cutting q-20260603-132638-47467-10 fix-spec.md

Summary table

Part Area Findings USER-VISIBLE CODE-BUG HIGH
1 Onboarding & Seed 14 8 6 1
2 Auth & PIN 21 10 11 2
3 Dashboard/Home/Tx History 30 13 17 1
4 Buy & Sell 19 12 7 2
5 KYC & Legal 15 7 8 1
6 Receive & Wallet Address 8 5 5 1
7 Hardware Wallet / BitBox 14 4 10 1
8 Settings & Support 23 13 10 0
9 Core packages 18 7 14 1
10 Cross-cutting 27 15 12 0
Total 189 94 100 9

(Some findings are dual-classed USER-VISIBLE+CODE-BUG; they are counted under both columns,
so the UV+CB columns sum slightly above the findings total for parts 1/2/6/9/10. Per-part
findings counts are exact.)


Part 1 — Onboarding & Seed

ID file:line Sev Class Description
B1 restore_wallet_cubit.dart:18-41 High USER-VISIBLE restoreWallet() has no try/catch; persist failure freezes UI at loading spinner forever, no error/retry.
B2 restore_wallet_cubit.dart:35-40 Medium CODE-BUG Missing isClosed guard before final emit; popping page mid-await throws StateError.
B3 create_wallet_cubit.dart:27-56 Medium USER-VISIBLE createWallet() no try/catch; generation failure leaves a permanent spinner, no retry.
B4 settings_seed_cubit.dart:35 Medium USER-VISIBLE Unguarded as SoftwareWallet cast crashes on a real unlock race → infinite spinner.
B5 settings_seed_cubit.dart:31 Medium USER-VISIBLE ensureCurrentWalletUnlocked() not wrapped; unlock failure → infinite spinner, no failure UI.
B6 verify_seed_page.dart:40-55 Medium USER-VISIBLE Back during the 2s success delay leaves wallet committed but Home un-notified → inconsistent route.
B7 create_wallet_cubit.dart:27 Low CODE-BUG createWallet() fire-and-forget void async with no concurrency guard; lifecycle cycling overlaps calls.
B8 create_wallet_state.dart:9-16 Low CODE-BUG copyWith cannot reset wallet to null (nullable-field copyWith anti-pattern).
B9 verify_seed_cubit.dart:31-33 Low CODE-BUG Unbounded while loop if seed length < 4 (latent; unreachable with 12-word seeds).
B10 verify_seed_cubit.dart:31 Low CODE-BUG New Random() constructed inside the selection loop; wasteful and non-deterministic for tests.
B11 restore_wallet_view.dart:31-43 Low USER-VISIBLE Arbitrary 2s delay + un-gated ValidateSeed listener (no listenWhen) → possible duplicate restore.
B12 welcome_card.dart:25-27 Low USER-VISIBLE Primary onboarding choices use GestureDetector — no button semantics, no press feedback, no disabled visual.
B13 validate_seed_cubit.dart:13-20 Low USER-VISIBLE Only exactly-12-word seeds accepted; 15/18/24-word BIP39 silently rejected with no message (by-design limit).
B14 settings_seed_cubit.dart:43-50 Low CODE-BUG close() awaits lockCurrentWallet() with no try/catch → unhandled async error on teardown.

Part 2 — Auth & PIN

ID file:line Sev Class Description
F-01 verify_pin_cubit.dart:35-49 High CODE-BUG (security) Lockout under-count race in PIN verification (async/race, security).
F-02 verify_pin_cubit.dart:35-49 Medium USER-VISIBLE Error-handling gap in verify-PIN flow.
F-03 verify_pin_cubit.dart:55-82 Low-Med CODE-BUG Error-handling weakness.
F-04 verify_pin_cubit.dart:51-53 Low CODE-BUG State handling issue.
F-05 verify_pin_cubit.dart:74-81 + page:91-98 Low CODE-BUG Async/race between cubit and page.
F-06 verify_pin_page.dart:202-226 Low USER-VISIBLE UI/UX defect.
F-07 verify_pin_page.dart:239-253 Low CODE-BUG Async/UX issue.
F-08 verify_pin_page.dart:42-46,184 Low USER-VISIBLE UI/UX / design defect.
F-09 setup_pin_cubit.dart:43-77 High (low likelihood) USER-VISIBLE Setup salt/hash race (async/race, security).
F-10 setup_pin_cubit.dart:60-77 Medium USER-VISIBLE Error-handling gap in PIN setup.
F-11 setup_pin_cubit.dart:79 Low CODE-BUG State / security-hygiene issue.
F-12 setup_pin_page.dart:126-130 Med USER-VISIBLE Async/race (enabler of F-09).
F-13 pin_auth_cubit.dart:35-48 Low CODE-BUG State handling issue.
F-14 pin_auth_cubit.dart:37-44 Info CODE-BUG Security / design note.
F-15 debug_auth_cubit.dart:19-37 Medium USER-VISIBLE Logic / state defect in debug-auth.
F-16 debug_auth_view.dart:104-110 Low-Med USER-VISIBLE Async/race.
F-17 debug_auth_view.dart:25,35 Low USER-VISIBLE Error-handling / security.
F-18 debug_auth_view.dart:23-29 Low CODE-BUG State handling.
F-19 verify_pin_cubit.dart:22-27 vs setup:22-31 Info CODE-BUG Consistency.
F-20 verify_pin_page.dart:85-88 Low CODE-BUG Lifecycle issue.
F-21 debug_auth_cubit.dart:24,33 Low USER-VISIBLE Error-handling.

Part 3 — Dashboard, Home & Transaction History

ID file:line Sev Class Description
1 transaction_history_filter_cubit.dart:39-51,60-61 High USER-VISIBLE changeFilter passes raw partial args; changing one date silently drops the previously-set other date bound.
2 transaction_history_filter_cubit.dart:61 Medium USER-VISIBLE End-date filter at midnight excludes all transactions made on the selected end day (asymmetric vs start).
3 transaction_history_filter_cubit.dart:16,18 Low CODE-BUG limit declared but never forwarded; silently ignored.
4 transaction_history_filter_state.dart:3 Low CODE-BUG State not Equatable → forced rebuilds, hard to assert.
5 transaction_history_receipt_state.dart:27-31 Medium USER-VISIBLE Failure state omits message from props → second failure equal → error SnackBar not re-shown.
6 transaction_history_multi_receipt_state.dart:27-31 Medium USER-VISIBLE Same props-omission defect as #5 for multi-receipt failure.
7 transaction_history_page.dart:33-40,115-119 Medium CODE-BUG StatelessWidget owns undisposed ValueNotifiers; reset on parent rebuild (resource leak).
8 transaction_history_page.dart:69,83 Low USER-VISIBLE firstDate: DateTime(2025) hardcoded → pre-2025 dates unreachable in picker.
9 transaction_history_page.dart:52-104 Low USER-VISIBLE No start<=end validation and no empty-state message.
10 transaction_history_row.dart:65 Low CODE-BUG InkWell with no onTap → misleading non-interactive affordance.
11 dashboard_bloc.dart:18,43,46,54 Medium CODE-BUG Injected asset never read; prices hardcode global realUnitAsset (wrong asset if they diverge).
12 dashboard_bloc.dart:45-66 Medium USER-VISIBLE Refresh handlers have no error handling; network failure shows blank/--.-- dashboard.
13 dashboard_bloc.dart:35-39,68-71 Medium USER-VISIBLE CurrencyChanged refresh has no restartable guard → stale-currency response can win the race.
14 balance_cubit.dart:22 Medium CODE-BUG watchBalance(...).listen(emit) registers no onError → balance silently frozen on stream error.
15 dashboard_transaction_history_cubit.dart:14 Low CODE-BUG Stream listen with no onError (same as #14).
16 pending_transactions_cubit.dart:14-22 Medium CODE-BUG Constructor fetch with no isClosed guard; catch's emit([]) throws again uncaught after close.
17 dashboard_price_widget.dart:27 / dashboard_portfolio_chart_widget.dart:25 Low CODE-BUG Provider key on a List's hashCode → stale chart on hash collision.
18 portfolio_chart.dart:26-41 vs portfolio_chart_cubit.dart:137-138,168-170 Low USER-VISIBLE Missing clipData: none + asymmetric band → upward spike clipped at top.
19 price_chart_cubit.dart:69,71 / portfolio_chart_cubit.dart:76,82 Low CODE-BUG .first/.last assume sorted-ascending feed; no sort/guard.
20 price_chart_cubit.dart:25-29 Low CODE-BUG selectPeriod emits twice → redundant intermediate rebuild.
21 cash_holding_box.dart:26 Low USER-VISIBLE Raw unscaled $balance BigInt interpolated into the balance×price hint.
22 dashboard_page.dart:113-116 Low CODE-BUG Redundant inner ternary; else BigInt.zero is dead code.
23 dashboard_pending_transactions.dart:11-23 Low CODE-BUG DashboardPendingTransactions is dead code (unreferenced).
24 home_state.dart:3-16 Medium CODE-BUG HomeState not Equatable; copyWith can't reset nullable openWallet.
25 home_bloc.dart:55-79 Medium USER-VISIBLE _onLoadCurrentWallet catch emits no error state → wallet-load failure invisible (spinner just stops).
26 home_bloc.dart:81-101 Medium CODE-BUG _onDeleteCurrentWallet no try/catch → stuck loading spinner + unhandled exception on throw.
27 home_bloc.dart:113 Low CODE-BUG Handler typed to base HomeEvent instead of CompleteOnboardingEvent.
28 home_bloc.dart:76-78,131-133 Low CODE-BUG Fire-and-forget balance/tx-sync futures; thrown future unobserved.
29 home_page.dart:20-23 Low CODE-BUG Splash Image.asset has no errorBuilder → broken-image box if asset missing.
30 time_period.dart:12-25 Low CODE-BUG Instance method name(context) shadows implicit EnumName.name getter → latent breakage.

Part 4 — Buy & Sell

ID file:line Sev Class Description
BB1 sell_bitbox_cubit.dart:168-182 High USER-VISIBLE (financial) Deposit retry re-broadcasts an already-sent tx (broadcast/confirm conflated) → perpetual retry loop.
BB2 sell_bitbox_cubit.dart:66-180 Medium-High CODE-BUG Systemic emit-after-close: no isClosed guards after long BitBox-signing awaits.
BB3 sell_bitbox_cubit.dart:74-89 Medium USER-VISIBLE ETH faucet polling never times out → user pinned on "Waiting for ETH" forever.
BB4 sell_bitbox_page.dart:116-121 Medium USER-VISIBLE SellBitboxError is a dead-end blank screen with no retry; must re-sign everything.
BB5 sell_bitbox_cubit.dart:45 vs :80 Low CODE-BUG Inconsistent account accessor between balance check and polling.
S1 sell_converter_cubit.dart:90 High USER-VISIBLE Currency change in Sell uses the BUY price endpoint → wrong "You receive" amount.
S2 sell_add_bank_account_sheet.dart:29-39 Medium USER-VISIBLE Add-bank-account sheet closes on failure, discarding typed IBAN/label.
S3 sell_bank_account_selection_page.dart:84-88 Medium USER-VISIBLE Deactivating the selected bank account leaves it selected & sellable.
S4 sell_button.dart:26-33 Low-Med USER-VISIBLE No payment-info refresh after KYC in Sell (inconsistent with Buy); user must re-tap.
S5 sell_payment_info_cubit.dart:43 Low-Med CODE-BUG Sell amount parsing lacks empty-guard/comma-normalization (vs Buy) → FormatException.
S6 sell_balance_cubit.dart:22 Low CODE-BUG Balance stream has no onError handler → silent stop.
S7 sell_confirm_sheet.dart:98,123 Low USER-VISIBLE Confirm sheet renders unformatted amounts (many decimals).
S8 sell_add_bank_account_sheet.dart:33 Low USER-VISIBLE Hardcoded non-localized "Error:" prefix exposing raw backend message.
B1 payment_information_details.dart:59 Medium USER-VISIBLE ValueNotifier created in build(); tab selection resets on rebuild + notifier leak.
B2 payment_information_details.dart:310-315 Medium CODE-BUG Icon(... fontWeight: ...) — invalid named arg on material Icon (analyzer/compile error).
B3 buy_confirm_cubit.dart:17-33 Medium CODE-BUG confirmPayment emits after await without isClosed guard → StateError on unmount.
B4 buy_payment_info_cubit.dart:49-50 Low-Med USER-VISIBLE Misleading generic error for multi-separator fiat input.
B5 buy_converter_cubit.dart:71,106-109 Low CODE-BUG _fractionDigits decimal branch unreachable from digits-only shares path (dead logic).
X1 sell_button.dart:48-53 (+3 sites) Low USER-VISIBLE Raw e.toString() surfaced to end users in snackbars (unlocalized, minor info exposure).

Part 5 — KYC & Legal

ID file:line Sev Class Description
F1 kyc_page_manager.dart:60-76 Medium USER-VISIBLE KYC dfxApproval step has no case → blank white screen with no way forward.
F2 kyc_cubit.dart:54,220 (+many) Medium USER-VISIBLE Raw e.toString() exception text surfaced verbatim to end users (minor info-leak).
F3 kyc_cubit.dart:51,179; kyc_registration_submit_cubit.dart:64 Low USER-VISIBLE Hardcoded non-localized English error strings shown to users.
F4 kyc_pending_page.dart:46,54 Low-Med USER-VISIBLE Internal enum identifier (e.g. FINANCIALDATA) shown to users on the pending page.
F5 kyc_registration_page.dart:73 Low CODE-BUG birthdayCtrl ValueNotifier never disposed (leak).
F6 kyc_registration_page.dart:280 High (impact) CODE-BUG swissTaxResidence: true hardcoded unconditionally → incorrect tax-residence declaration submitted.
F7 kyc_financial_data_questions_page.dart:174-179 Medium USER-VISIBLE Financial-data text field reuses controller across questions (no key) → stale previous answer shown.
F8 kyc_financial_data_cubit.dart:40-58 Medium-Low CODE-BUG currentIndex not clamped after re-filtering visibleQuestions → RangeError / wrong question.
F9 kyc_financial_data_cubit.dart:16-34 Low-Medium USER-VISIBLE Empty visibleQuestionselementAt(0) RangeError crash on questions page build.
F10 legal_document_page.dart:55-65 Medium USER-VISIBLE Legal doc: silent empty render on load failure + no loading state → blank legal/compliance doc.
F11 kyc_email_step_cubit.dart:28 Low-Medium CODE-BUG Brittle error-message substring matching for control flow.
F12 kyc_link_wallet_cubit.dart:29-33 Low CODE-BUG Redundant BitboxNotConnectedException catch; missing AddWallet reconnect path.
F13 kyc_pending_page.dart:38-43 (+4 files) Low CODE-BUG Hardcoded const TextStyle(fontSize:) violates project styling rule.
F14 kyc_email_page.dart:113 Low CODE-BUG Email validation regex not anchored at end (matches trailing garbage).
F15 kyc_registration_page.dart:274,279 Low CODE-BUG Country force-unwrap relies on external validator invariant (robustness only).

(Plus 5 minor low-confidence observations O1-O5: init-order, consent-vs-next button semantics,
empty-map .first throw, ignored mailto link, TnC link entity to verify.)

Part 6 — Receive & Wallet Address

ID file:line Sev Class Description
F1 qr_address_widget.dart:42,47,51,55 High CODE-BUG (→USER-VISIBLE crash) Unguarded fixed-index substring on the address → RangeError crash (hits Receive and Settings).
F2 qr_address_widget.dart:27-30,74 Medium USER-VISIBLE Copy-to-clipboard gives no user feedback (and tap feedback suppressed).
F3 qr_address_widget.dart:20-25 vs :74 Low CODE-BUG QR encodes ethereum: URI but copy yields bare address — payload mismatch (confirm intent).
F4 receive_page.dart:16 / settings_wallet_address_page.dart:15 Medium CODE-BUG (→USER-VISIBLE) primaryAddress read with no readiness/empty guard → crash or blank QR when not ready.
F5 receive_page.dart:9,16 / settings_wallet_address_page.dart:10,15 Medium USER-VISIBLE StatelessWidget snapshots primaryAddress, never listens → stale receive address on account switch.
F6 qr_address_widget.dart:43,56 Low CODE-BUG Hardcoded TextStyle violates project styling overlay.
F7 qr_address_widget.dart:20-25,38-61 Low USER-VISIBLE No accessibility semantics on QR / address / copy affordance.
F8 receive_page.dart:22-27 Low CODE-BUG Unconditional context.pop() with no canPop check → could trap user on root/deep-link.

Part 7 — Hardware Wallet / BitBox

ID file:line Sev Class Description
F1 connect_bitbox_cubit.dart:45-92 / bitbox.dart:46-63 High CODE-BUG (user-visible symptom) Overlapping scan ticks start concurrent init() on the shared BitBox SDK manager → pairing wedge.
F2 connect_bitbox_cubit.dart:56-64 Medium-High CODE-BUG checkForBitbox() awaits getAllUsbDevices() in a periodic timer with no try/catch → unhandled async error.
F3 connect_bitbox_view.dart:28-36 Medium USER-VISIBLE Repeated "connect failed" SnackBar spam during the silent auto-retry loop.
F4 connect_bitbox_cubit.dart:147 Medium USER-VISIBLE Hardcoded placeholder wallet name 'Luke-Skywallet' persisted and shown for paired BitBox.
F5 connect_bitbox_cubit.dart:133 Low-Medium CODE-BUG _pendingInit! force-unwrap relies on an unenforced invariant.
F6 connect_bitbox_cubit.dart:67 Low CODE-BUG connectToBitbox re-entry guard only checks BitboxConnecting.
F7 connect_bitbox_cubit.dart:95,75,108 Low CODE-BUG Channel-hash deadline and probe timeouts hardcoded (not injectable) → untestable timeout path.
F8 bitbox_credentials.dart:158-170 Low (High if triggered) CODE-BUG (user-visible symptom) EIP-155 v normalization doesn't handle a legacy 27/28 recovery id → invalid v, rejected tx.
F9 bitbox_credentials.dart:139-141 Low CODE-BUG signToSignature assumes the native signature buffer is >=65 bytes → RangeError on short buffer.
F10 connect_bitbox_view.dart:21 Low USER-VISIBLE Fixed height*0.8 bottom sheet can overflow / clip buttons on small screens.
F11 connect_bitbox_cubit.dart:179-186 Low CODE-BUG Broad catch (e) in _captureAuthSignature swallows non-Exception Errors, masking real bugs.
F12 bitbox.dart:53-63 Low CODE-BUG Connection-status observer only (re)started by confirmPairing; init return didInit is dead.
F13 connect_bitbox_view.dart:162-175 Low USER-VISIBLE BitboxFound base state momentarily renders the generic default UI (cosmetic flash).
F14 bitbox.dart:101-107 Low CODE-BUG _disconnectAndForget only catches on Exception; a thrown Error escapes the periodic timer.

Part 8 — Settings & Support

ID file:line Sev Class Description
F1 settings_tax_report_state.dart:27-31 Medium CODE-BUG SettingsTaxReportFailure omits props → all failures Equatable-equal (latent error de-dup).
F2 settings_tax_report_page.dart:46-48 Low-Med USER-VISIBLE OpenFile.open result ignored → silent no-op if PDF can't be opened.
F3 settings_tax_report_page.dart:31,102-106 Low CODE-BUG _DatePickerModel ValueNotifier on StatelessWidget, never disposed; resets on rebuild.
F4 settings_tax_report_page.dart:74 Low USER-VISIBLE firstDate: DateTime(2025) hardcoded → pre-2025 report dates unreachable.
F5 settings_bloc.dart:45-51 Medium CODE-BUG + USER-VISIBLE _onSetNetworkModeEvent no error handling: repo mutated pre-await; failure hangs network-page spinner.
F6 settings_network_page.dart:13 Low CODE-BUG _loadingModel ValueNotifier on StatelessWidget, never disposed.
F7 settings_user_data_cubit.dart:40-101 Medium CODE-BUG getUserData emits after awaits with no isClosed guard → StateError if page popped mid-load.
F8 settings_user_data_page.dart:182-185 Low-Med CODE-BUG _BitboxDisconnectedView calls onReconnected() after await with no mounted check.
F9 settings_edit_address_page.dart:170-174,218-219 Medium USER-VISIBLE Missing country selection → Save silently does nothing (no validator/feedback).
F10 edit_name/address submit catch Medium USER-VISIBLE Submit failure replaces filled form with full-screen failure page that re-runs startStep (inconsistent).
F11 edit_{name,address,phone} cubit catch Low-Med USER-VISIBLE Raw e.toString() shown to users; no ApiException.message path.
F12 settings_edit_{name,address,phone}_cubit.dart Low CODE-BUG Cubits emit after await with no isClosed guard (same class as F7).
F13 support_chat_cubit.dart:31-45 + support_chat_page.dart:77-83 Medium USER-VISIBLE Chat send failure: input cleared, no error shown, message lost — user believes it sent.
F14 support_chat_message_bubble.dart:77-81 Low USER-VISIBLE _formatTime uses add(timeZoneOffset) not toLocal() → wrong time across DST / non-UTC.
F15 support_chat_cubit.dart Low CODE-BUG emit-after-await without isClosed guard.
F16 support_tickets_page.dart:70-71 Low USER-VISIBLE Ticket date not zero-padded / no local tz; inconsistent with dd.MM.yyyy elsewhere.
F17 support_create_ticket_cubit.dart:48-57 Low CODE-BUG _getTicketName hardcoded English, not localized.
F18 support_create_ticket_cubit.dart:20-22 Low CODE-BUG selectReason is dead code (reason auto-set to .other).
F19 web_view_page.dart:73 (+settings_contact_page.dart:95-101) Low-Med USER-VISIBLE javaScriptEnabled:false + in-app realunit.ch with no external-browser button → blank, no escape.
F20 web_view_page.dart:64-83 Low-Med USER-VISIBLE No loading indicator and no load-error handler → blank screen on slow/failed load, no retry.
F21 settings_contact_page.dart:73,84 Low USER-VISIBLE launchUrl(tel:/mailto:) unawaited/unchecked → silent no-op / unhandled async error.
F22 settings_page.dart:102 Low CODE-BUG Wallet-backup visibility via non-reactive context.read<HomeBloc>() → stale if wallet changes.
F23 settings_bloc.dart:53-55 + settings_state.dart Low CODE-BUG hideAmounts in state but never persisted/restored → resets on bloc recreation.

Part 9 — Core packages

ID file:line Sev Class Description
H1 wallet_storage.dart:28-29 High USER-VISIBLE + CODE-BUG deleteWallet deletes account rows but NOT the walletInfos row holding the encrypted seed → deleted seed survives on disk.
H2 dfx_auth_service.dart:161-168 Medium-High USER-VISIBLE + CODE-BUG Cold-cache auth has no in-flight coalescing → duplicate signs / multiple BitBox hardware prompts.
M1 dfx_price_service.dart:35,39,65,66; real_unit_account_service.dart:38 Medium USER-VISIBLE BigInt.from(double*100) truncates toward zero → prices/portfolio off by a cent.
M2 real_unit_registration_service.dart:139 Medium USER-VISIBLE Registration language hardcoded to DE regardless of user locale.
M3 wallet_service.dart:182-222 Medium CODE-BUG (security-adjacent) ensureCurrentWalletUnlocked holder-count leak on a throwing unlock → mnemonic stays resident.
M4 real_unit_sell_payment_info_service.dart:57 Medium USER-VISIBLE SellPaymentInfo.amount truncates a double → fractional sells blocked by EIP-7702 amount check.
M5 transaction_repository.dart:82,173; transaction_storage.dart:78,116 Medium CODE-BUG Transaction type persisted/filtered by enum index & magic ints → reorder remaps/throws.
M6 transaction_history_service.dart:48,69 Medium CODE-BUG API-synced txs stored with height:0 → height-based incremental sync cursor never advances.
L1 transaction_history_service.dart:131-133 Low CODE-BUG asShortTxId RangeError on strings shorter than 10 chars (public extension).
L2 dfx_kyc_service.dart:183 Low CODE-BUG KYC session URL query-append corruption (double ? if url already has query).
L3 dfx_kyc_service.dart:118-220 Low (security) CODE-BUG Bearer token attached to backend-supplied URL with no host allowlist.
L4 secure_storage.dart:176-179 Low CODE-BUG decryptSeed doesn't validate : separator → substring(0,-1) RangeError on malformed input.
L5 balance_service.dart:56-58 Low CODE-BUG updateBalance swallows all errors with only a debug log; masks real regressions.
L6 asset_repository.dart:13-17,30-31 Low USER-VISIBLE + CODE-BUG Asset metadata never refreshed; updateAsset always nulls icon → stale decimals/symbol.
L7 payment_uri.dart:12-20 Low USER-VISIBLE (low conf) EthereumURI is not EIP-681 (no value/wei, no @ChainID) → external scanners may misread.
L8 wallet_storage.dart:61; dfx_transaction_storage.dart:58 Low CODE-BUG FK constraints declared but PRAGMA foreign_keys=ON never run → not enforced.
L9 real_unit_buy/sell_payment_info_service.dart:52-58/74-80 Low CODE-BUG Dead duplicate error branch (403 arm byte-identical to else).
L10 dfx_auth_service.dart:89,150 (+several) Low CODE-BUG Inline JSON parsing in services (CONTRIBUTING violation); root enabler of M1.

Part 10 — Cross-cutting

ID file:line Sev Class Description
B01 date_picker.dart:31-64 Medium USER-VISIBLE iOS date picker cannot be cancelled and commits a date on dismiss (vs Android null-on-cancel).
B02 blockchain.dart:9-10 Medium USER-VISIBLE getFromChainId firstWhere no orElse → StateError for any unknown chainId (crashes history/icon).
B03 currency.dart:9-10; language.dart:9 Medium USER-VISIBLE / CODE-BUG fromCode firstWhere no orElse → StateError on unknown code at unguarded buy/sell DTO call sites; Language also case-sensitive.
B04 birthday_field.dart:22-43 Medium USER-VISIBLE Accepts impossible dates (31 Feb); unsafe split('-') index → RangeError on malformed stored value.
B05 router_config.dart:82,102,150,165,306 Medium CODE-BUG (USER-VISIBLE on deep-link) state.extra as <Type> non-null casts crash on missing extra; no errorBuilder/redirect.
B06 asset_logo.dart:4-14 Medium-Low USER-VISIBLE getAssetImagePath default returns REALU.png → ZCHF/Sepolia-ETH/unknown assets show RealUnit logo.
B07 ascii_transliterate.dart:106-135 Medium USER-VISIBLE Transliteration maps only NFC precomposed runes → decomposed diacritics become ?, re-breaks BitBox registration.
B08 text_link_span.dart:19-23; text_substring_highlighting.dart:95-97 Medium-Low CODE-BUG TapGestureRecognizer created in build, never disposed → leak per rebuild.
B09 iban_input_formatter.dart:26-30 Medium-Low USER-VISIBLE IBAN formatter forces caret to end on every edit → mid-IBAN editing jumps to end.
B10 date_picker_field.dart:52 Low USER-VISIBLE Displays initialDate, never the picked date (relies on parent rebuild).
B11 phone_number_field.dart:23-35 Low USER-VISIBLE Drops a stored number with an unknown prefix → not shown, won't re-save.
B12 parse_fixed.dart:6,17,25-26 Low CODE-BUG No input validation → RangeError/FormatException on '', lone '-', leading-dot (latent).
B13 hide_amount_text.dart:13-40 Low USER-VISIBLE Zero balance renders --.-- (looks like missing data); symbol/spacing inconsistencies.
B14 info_row.dart:29-35 Low USER-VISIBLE trailing has no Expanded/ellipsis → long value RenderFlex overflow.
B15 colors.dart:9-10 Low USER-VISIBLE brand700 lighter than brand200 — inverted shade (likely swapped value).
B16 device_info.dart:6 Low CODE-BUG DeviceInfo.instance allocates a new object each access despite singleton intent.
B17 tab_selector.dart:22,37 Low CODE-BUG tabCount==0 → 1/0 Infinity layout; unknown selectedTab → indicator off-screen.
B18 standard_slide_button.dart:51-66 Low (a11y) USER-VISIBLE Slide-to-confirm drag-only, no Semantics(button)/tap fallback → inaccessible.
B19 xfile_extension.dart:13-21 Low USER-VISIBLE MIME guess misses HEIC/WEBP/GIF → iOS HEIC photos get wrong MIME on KYC upload.
B20 fast_hash.dart:2-14 Low CODE-BUG 64-bit FNV-1a lossy under JS doubles (web only; latent on mobile target).
B21 mnemonic_read_only_field.dart:9,16; seed_blur_card.dart:26-28 Low CODE-BUG Debug-only assert; always builds 12 cells → release RangeError on short seed list.
B22 svg_parser.dart:7-12 Low CODE-BUG normalize regex edge cases (.5mm no match; 123.mm FormatException).
B23 di.dart:54,101-109 Low CODE-BUG (verify) Repositories registered as factories → possible cache/state divergence (esp. CacheRepository).
B24 lifecycle_initializer.dart:47-50 Low CODE-BUG _onResumed runs unconditionally (pre-wallet/locked) → may throw or trigger spurious network calls.
B25 outlined_tile.dart:61 Low USER-VISIBLE Trailing icon tied to onTap not trailingIcon → renders blank Icon(null) or hides provided icon.
B26 mnemonic_field.dart:1-2 Low CODE-BUG bip39 internal import via lint-ignore with no WHY justification (fragile to package internals).
B27 asset.dart:4-6; balance.dart:5 Low CODE-BUG (verify) id hashes raw non-normalized address → checksummed vs lowercase yield different ids.

Grand totals

  • Total findings: 189
  • USER-VISIBLE: 94 · CODE-BUG: 100 (dual-classed findings counted in both columns)
  • HIGH-severity: 9 (counting "High"/"Medium-High" lead items: P1 B1; P2 F-01, F-09;
    P3 chore: typo in *_repository.dart #1; P4 BB1, S1; P5 F6; P6 F1; P7 F1; P9 H1 — plus borderline Medium-High P4 BB2, P7 F2,
    P9 H2 not included in the 9).

Top user-visible bugs (HIGH-severity, USER-VISIBLE, across all parts)

  • P1 B1 — restore_wallet has no error handling; restore failure freezes the UI on a permanent loading spinner with no retry. (restore_wallet_cubit.dart:18-41)
  • P2 F-09 — PIN setup salt/hash async race (USER-VISIBLE, rated High, low likelihood). (setup_pin_cubit.dart:43-77)
  • P3 chore: typo in *_repository.dart #1 — Transaction-history filter silently drops a previously-set date bound when the other date is changed. (transaction_history_filter_cubit.dart:39-51)
  • P4 BB1 — sell_bitbox deposit retry re-broadcasts an already-sent on-chain transaction → perpetual retry loop (financial). (sell_bitbox_cubit.dart:168-182)
  • P4 S1 — Currency change on the Sell screen uses the BUY price endpoint → wrong "You receive" amount shown. (sell_converter_cubit.dart:90)
  • P5 F6swissTaxResidence: true hardcoded on every KYC registration submit → incorrect tax-residence declaration (labelled CODE-BUG, High compliance impact). (kyc_registration_page.dart:280)
  • P6 F1 — Unguarded fixed-index substring on the wallet address → RangeError crash on Receive and Settings screens (CODE-BUG → USER-VISIBLE crash). (qr_address_widget.dart:42-55)
  • P7 F1 — Overlapping BitBox scan ticks start concurrent init() on the shared SDK manager → pairing wedge (CODE-BUG, user-visible pairing failure). (connect_bitbox_cubit.dart:45-92)
  • P9 H1deleteWallet never deletes the encrypted seed row → "deleted" wallet's seed survives on disk (USER-VISIBLE + CODE-BUG, privacy/data-retention). (wallet_storage.dart:28-29)

Notes on data completeness

  • No part lacked findings. All 10 parts produced a populated bug list.
  • Part 4 (Buy & Sell): the chosen run's fix-spec.md (Architect) contained only the audit
    method/scope, not the bug table; the full 19-finding inventory was taken from that run's
    fixer-repair-report.md (Repair agent). All other parts' findings came from fix-spec.md.
  • Part 2 (Auth & PIN): fix-spec.md carries the complete 21-row classified summary table
    (id, file:line, class, severity, visibility); the prose detail lives in a sibling
    audit-findings.md. Descriptions here are summarized from the table + category column.
  • Aborted/empty runs (parts 3/4/5 had earlier runs with 0-line fix-specs; part 3 also had two
    shorter complete runs) were discarded in favour of the most-populated run per part.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions