Skip to content

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

@joshuakrueger-dfx

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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions