Skip to content

fix(tokens): allow buying a currency with a non-USDF balance - #1171

Merged
bmc08gt merged 1 commit into
code/cashfrom
fix/buy-with-non-usdf-currency
Jul 29, 2026
Merged

fix(tokens): allow buying a currency with a non-USDF balance#1171
bmc08gt merged 1 commit into
code/cashfrom
fix/buy-with-non-usdf-currency

Conversation

@bmc08gt

@bmc08gt bmc08gt commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

Problem

On the token info screen, tapping Buy with zero USDF but a balance in another Flipcash currency wrongly routed the user to the Add Money flow. The buy gate checked only the USDF reserve balance, even though the swap flow already supports funding a buy with any held currency.

Root cause

TokenInfoViewModel gated the Buy action on State.hasReserves, which is USDF-only (observeReservesBalance()balanceForToken(Mint.usdf)). With no USDF, !hasReserves short-circuited to the Add Money prompt before the user ever reached the funding-token picker.

Fix

  • New State.hasFundableBalance: true when the user holds a displayable balance in some token other than the one being bought — mirroring the swap picker's own eligibility rule (address != desiredToken && hasDisplayableValue), so we never route to an empty picker.
  • Observe tokenCoordinator.tokenBalances (all mints) instead of observeReservesBalance() (USDF only), using the same Fiat.hasDisplayableValue "has real money" check as the existing hasBalance() / hasGiveableBalance() gates.
  • Buy gate is now if (!hasFundableBalance && addMoney). FF-off behavior is unchanged; retired the now-dead reserves tracking that existed only for this gate.

Tests

Added TokenInfoViewModelStateTest (5 cases): no balance → Add Money; only the target token → Add Money; another currency → buy allowed (the regression); USDF present → buy allowed; reducer wiring. Green against code/cash.

Audit of other Add Money gates

Swept every deposit/Add Money gate for the same USDF-only bug class. All other reachable gates (give, tip, send cash, launch/create currency, scanner, swap amount caps) already use all-currency helpers. The one USDF-only comparison in SwapViewModel.checkBalanceLimit (BalanceIncrease branch) is unreachable dead codecheckBalanceLimit() is only invoked for BalanceDecrease (Sell); Buy goes through checkFundingAmount()transactionLimit(), which is already all-currency aware. Left untouched here; flagging as a latent landmine worth removing separately.

The buy gate on the token info screen checked only the USDF reserve
balance (hasReserves), so a user holding another Flipcash currency but
no USDF was routed to the Add Money flow instead of the swap screen —
even though the swap flow already supports funding a buy with any held
currency.

Gate on whether the user holds a displayable balance in some token
other than the one being bought (hasFundableBalance), mirroring the
swap token picker's own eligibility rule. Replaces the USDF-only
reserves observation with an all-token balances observation.
@github-actions github-actions Bot added type: fix Bug fix area: tokens Token accounts, balances, token info labels Jul 29, 2026
@bmc08gt
bmc08gt merged commit 1b8a7fb into code/cash Jul 29, 2026
3 checks passed
@bmc08gt
bmc08gt deleted the fix/buy-with-non-usdf-currency branch July 29, 2026 02:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: tokens Token accounts, balances, token info type: fix Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant