Skip to content

Prevent swap KYC terms modal from stacking and dismiss abuse#5983

Open
j0ntz wants to merge 1 commit intodevelopfrom
jon/fix/swap-kyc-modal-popup
Open

Prevent swap KYC terms modal from stacking and dismiss abuse#5983
j0ntz wants to merge 1 commit intodevelopfrom
jon/fix/swap-kyc-modal-popup

Conversation

@j0ntz
Copy link
Contributor

@j0ntz j0ntz commented Mar 19, 2026

Description

Asana task

Fixes two bugs with the swap KYC terms verification modal:

  1. Stacking modals: When the quote auto-refresh timer expires while the terms modal is open, the scene replaces itself via SwapProcessingScene, remounts, and calls swapVerifyTerms again — stacking a duplicate modal on the still-open first one. Fixed by deferring the timer: if it fires while the terms modal is pending, the expiry is recorded and replayed after the modal resolves.

  2. Destructive dismissal: Backdrop tap, swipe-down, X button, and hardware back all resolved false, triggering changeEnabled(false) on the swap provider — silently removing it from exchange settings without clear user intent. Fixed by removing onCancel from the EdgeModal, making the modal non-dismissable. The user must now explicitly tap Accept or Reject.

Closes: https://app.asana.com/1/9976422036640/project/1200972350208303/task/1213613256799799

CHANGELOG

Does this branch warrant an entry to the CHANGELOG?

  • Yes
  • No

Dependencies

none

Requirements

If you have made any visual changes to the GUI. Make sure you have:

  • Tested on iOS device
  • Tested on Android device
  • Tested on small-screen device (iPod Touch)
  • Tested on large-screen device (tablet)

Note

Medium Risk
Touches the swap confirmation/quote-expiry flow and changes how swap providers are disabled based on the terms modal outcome, which could affect swap navigation and provider availability if edge cases remain.

Overview
Prevents the swap KYC terms verification modal from being dismissed implicitly (backdrop/back/swipe/X) by removing the EdgeModal onCancel handler, so users must explicitly Accept or Reject.

Fixes a race where the quote auto-refresh/expiry could fire while the terms modal is open, causing the scene to remount and re-run swapVerifyTerms (stacking duplicate modals); the timer expiry is now deferred and replayed after the terms check resolves.

Adds a changelog entry for the swap KYC terms modal stacking/dismissal fixes.

Written by Cursor Bugbot for commit e9a56ab. This will update automatically on new commits. Configure here.

Defer the quote auto-refresh timer while the terms modal is pending so
a scene remount cannot stack a second modal. Track deferred timer
expiry and replay it after the modal resolves to ensure fresh quotes.

Make the terms modal non-dismissable (no backdrop tap, swipe, or X
button) so the user must explicitly accept or reject. This prevents
accidental dismissal from silently disabling the swap provider.
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

}
})
.catch((err: unknown) => {
termsCheckPending.current = false
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Catch handler doesn't replay deferred expired timer

Medium Severity

The .catch() handler resets termsCheckPending.current and shows the error, but unlike the .then() handler it never checks timerExpiredDuringTerms.current to replay the deferred timer expiry. If swapVerifyTerms throws (e.g. changeUserSettings fails) after the CircleTimer already fired, the user gets stuck on the confirmation screen with an expired quote — the timer won't fire again and no navigation occurs.

Additional Locations (1)
Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant