fix: exempt crypto withdrawals from the fiat $1 minimum#2433
Conversation
The shared withdraw amount step applied getMinimumAmount() to every method; crypto has no country so it fell into the $1 default — blocking sub-$1 on-chain sends that send-via-link already allows. The minimum was introduced for bank offramps (295c8ec, Bridge's $1 floor) and crypto only inherited it by sharing the page. Bank rails keep their country minimums.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Review limit reached
Next review available in: 5 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (6)
WalkthroughChangesWithdrawal amount validation
Estimated code review effort: 2 (Simple) | ~10 minutes Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Code-analysis diffPainscore total: 6122.12 → 6123.14 (+1.02) 🆕 New findings (27)
…and 7 more. ✅ Resolved (27)
…and 7 more. |
🧪 UI test report — ✅ all greenSuites
📊 Coverage (unit)
⏱ 10 slowest test cases
|
…m Rhino deposits Review findings on the initial cut: - The exemption keyed off the URL param independently of routing: a stale bank selectedMethod (app-wide context) entering via /withdraw?method=crypto got min=$0 while Continue still routed to the bank flow. The predicate now follows selectedMethod when set; the URL only covers the pre-effect frame. - Removing the blanket $1 floor exposed the cross-chain path to sub-minimum Rhino SDA deposits, which are accepted on-chain but never bridged (stranded, uncredited — known incident class). The confirm CTA now blocks below the route's minDepositLimitUsd, which the page previously discarded. - Consolidated the two other inline is-crypto checks onto the same predicate, stopped the exchange-rate poll when crypto is selected, dropped a vacuous test assertion.
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@coderabbitai full review |
✅ Action performedFull review finished. Your plan includes PR reviews subject to rate limits. More reviews will be available in 5 minutes. |
Summary
Crypto withdrawals were blocked below $1 by the shared withdraw amount step:
minUsdAmountderives a country-based bank minimum viagetMinimumAmount(), and crypto (no country) fell into the $1 default. The minimum was introduced for bank offramps (295c8ec, June 2025 — Bridge's $1 floor) and crypto only inherited it by sharing the page. Inconsistent with send-via-link, which allows sub-$1 amounts with the same sponsored gas.Fix:
minUsdAmountis 0 when the withdrawal is crypto — any amount > 0 passes. Bank rails keep their country minimums (US/EU $1, GB £3, MX 50 MXN) untouched.Review hardening (multi-agent review on the first cut):
selectedMethodwhen set (selectedMethod ? selectedMethod.type === 'crypto' : isCryptoFromSend): a stale bank method surviving in the app-wideWithdrawFlowContext(entered via/withdraw?method=crypto) still routes Continue to the bank flow, so it keeps the bank minimum. Regression test included.payAmount < minDepositLimitUsd(value the page previously discarded), with unit-tested helperisBelowRhinoMinDeposit. Direct same-chain USDC transfers keep no minimum.type !== 'crypto'checks (limits card, Continue limits gate) consolidated onto the same predicate; exchange-rate polling now disabled for crypto.Design notes / accepted trade-offs
getMinimumAmount('')silently returns the $1 default for an unknown country — the next countryless method re-arms the trap; theminUsdAmountcomputation (country derivation + FX conversion + exemption) is a candidate for an extracted, tested hook — add-money already re-implements it with a different FX hook.Risks / breaking changes
mainper request → back-merge debt main→dev after merge.QA
withdraw-states: sub-$1 crypto enables Continue and routes to/withdraw/crypto; sub-$1 bank stays blocked with the $1 message; stale-bank-method +?method=cryptostays blocked.withdraw.utils:isBelowRhinoMinDepositunit tests (below/at/above/unknown values).