Skip to content

refactor(core): name the round-to-display-precision step on FiatAmount - #702

Merged
bmc08gt merged 1 commit into
mainfrom
refactor/fiat-rounded-to-smallest-unit
Aug 31, 2026
Merged

refactor(core): name the round-to-display-precision step on FiatAmount#702
bmc08gt merged 1 commit into
mainfrom
refactor/fiat-rounded-to-smallest-unit

Conversation

@bmc08gt

@bmc08gt bmc08gt commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Follow-up to #701, which added the ninth copy of this idiom.

Nine call sites rounded a fiat value to its currency's fraction digits by hand:

FiatAmount(value: value.rounded(to: currency.maximumFractionDigits), currency: currency)

They are all reaching for the same thing — the figure a user is actually shown, so a comparison against a displayed bound holds ("what we display is what we accept"). The concept had no name, which is how it ended up written out nine times.

FiatAmount.roundedToSmallestUnit() names it, next to the existing flooredToSmallestUnit(). The two now read as the choice they are: round half-up for a figure being compared, floor for a ceiling that rounding up would break, such as a spend limit derived from a balance. Each doc points at the other so the wrong one is harder to reach for by accident.

Call sites routed through it:

File What it was rounding
FiatAmount.converted(to:rates:) both legs of a cross-currency conversion
TipFloor.isMet(by:) the entered amount against a recipient's fee
UserFlags.TipPresets.meetsMinimum(_:) the entered amount against the regional minimum
AddMoneyGate.canPayLaunchCost the balance against the launch cost
StoredBalance.displayedUSDF the wallet card's USD figure
EnterAmountCalculator.isWithinDisplayLimit the keypad entry against its cap
WithdrawViewModel.displayFee the converted network fee
CoinbaseDepositOperation.checkMinimum the converted $5 minimum
BuyAmountViewModel.computePaymentAmount the balance the entry is capped at

Behaviour is unchanged — the helper is the same expression. Two of the call sites additionally drop a hand-unpacked .value comparison in favour of comparing the FiatAmounts directly; that is safe in both because a preceding guard establishes the currencies match, which is what FiatAmount: Comparable preconditions on.

SendTipSheet's amount == amount.rounded(to: 0) is left alone: it is a whole-number check on a bare Decimal, not this concept.

Five tests cover the new helper in FiatAmountTests — half-up above the half-unit, truncation below it, an exact value untouched, a zero-decimal currency (JPY), and the wallet's case of two values that display alike collapsing to the same figure.

Nine call sites rounded a fiat value to its currency's fraction digits by
hand, each writing out `value.rounded(to: currency.maximumFractionDigits)`
and rebuilding a FiatAmount around the result. They are all doing the same
thing — taking the figure a user is actually shown, so a comparison against
a displayed bound holds — and that concept had no name.

`roundedToSmallestUnit()` gives it one, next to the existing
`flooredToSmallestUnit()`. The pair now reads as the choice it is: round
half-up for a figure being compared, floor for a ceiling that rounding up
would break. Both are named in each other's docs so the wrong one is harder
to reach for.

Behaviour is unchanged; the helper is the same expression. Two call sites
also drop a hand-unpacked `.value` comparison in favour of comparing the
FiatAmounts themselves, which is safe where a preceding guard establishes
the currencies match.
@bmc08gt bmc08gt self-assigned this Aug 31, 2026
@bmc08gt
bmc08gt merged commit 009c50a into main Aug 31, 2026
@bmc08gt
bmc08gt deleted the refactor/fiat-rounded-to-smallest-unit branch August 31, 2026 17:11
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