What changed, and why it matters
This commit fixes a single-character bug in the Stack Wallet exchange flow. A double negation (!!) was accidentally used where a single negation (!) was intended. The bug caused the app to require a refund address even from exchanges that do not support one, which could block legitimate transactions. The fix changes the logic so that a refund address is only required when the exchange actually supports it. There is no direct evidence in the commit that this was a security vulnerability, but a mis-gated refund flow could in theory lead to user confusion or funds being sent to an unsupported/invalid refund path.
Review the full exchange refund flow to confirm the corrected gating matches backend expectations. Add unit/widget tests covering both supportsRefundAddress=true and supportsRefundAddress=false cases. Monitor for any user reports of stuck or mis-routed exchange refunds around the affected release.
Security signals we found
Logic bug in refund-address gating
UI flow control for cryptocurrency exchange refund path
Potential for user funds to be mishandled if refund address is incorrectly required or omitted
Evidence from the diff
In lib/pages/exchange_view/exchange_step_views/step_2_view.dart, the condition enabling the ‘Next’ button was: _toController.text.isNotEmpty && (_refundController.text.isNotEmpty || !!ref.read(efExchangeProvider).supportsRefundAddress). The !! is a no-op in Dart for a bool (it just converts to bool twice), so the expression effectively required the refund address to be non-empty OR the exchange to support refund addresses. The intended logic, per the fix, is to require a refund address only when the exchange supports refund addresses: _refundController.text.isNotEmpty || !supportsRefundAddress. This is a logic bug fix, not an obvious exploit, but it gates whether a user can proceed with an exchange and whether a refund address is collected.
Changed components
lib/pages/exchange_view/exchange_step_views/step_2_view.dartExchange step 2 UI/validationRefund address collection flowInspect captured patch +1 / −1
diff --git a/lib/pages/exchange_view/exchange_step_views/step_2_view.dart b/lib/pages/exchange_view/exchange_step_views/step_2_view.dart
index 1b2fa42..e9735a5 100644
--- a/lib/pages/exchange_view/exchange_step_views/step_2_view.dart
+++ b/lib/pages/exchange_view/exchange_step_views/step_2_view.dart
@@ -150,7 +150,7 @@ class _Step2ViewState extends ConsumerState<Step2View> {
enableNext =
_toController.text.isNotEmpty &&
(_refundController.text.isNotEmpty ||
- !!ref.read(efExchangeProvider).supportsRefundAddress);
+ !ref.read(efExchangeProvider).supportsRefundAddress);
});
}
} on PlatformException catch (e, s) {
Why this scored 50/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.