Skip to content

Commit b3e63b8

Browse files
committed
fix(ocp/fiat): handle HALF_UP rounding when currency doesn't support decimals
Signed-off-by: Brandon McAnsh <[email protected]>
1 parent 260bfbf commit b3e63b8

File tree

2 files changed

+23
-17
lines changed

2 files changed

+23
-17
lines changed

services/opencode/src/main/kotlin/com/getcode/opencode/model/financial/Fiat.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import kotlinx.serialization.Serializable
1111
import java.math.BigDecimal
1212
import java.math.RoundingMode
1313
import java.text.DecimalFormat
14+
import java.util.Currency
1415
import java.util.Locale
1516

1617
@Serializable
@@ -79,8 +80,7 @@ data class Fiat(
7980
}
8081

8182
val formatter = DecimalFormat.getInstance(Locale.US).apply {
82-
val decimalDigits =
83-
java.util.Currency.getInstance(currencyCode.name).defaultFractionDigits
83+
val decimalDigits = Currency.getInstance(currencyCode.name).defaultFractionDigits
8484
val preferredDigits = when (formatting) {
8585
is Formatting.Length -> formatting.decimalPlaces
8686
Formatting.None -> decimalDigits
@@ -90,7 +90,7 @@ data class Fiat(
9090
}
9191
minimumFractionDigits = preferredDigits
9292
maximumFractionDigits = preferredDigits
93-
roundingMode = ROUNDING_MODE
93+
roundingMode = if (decimalDigits == 0) RoundingMode.DOWN else ROUNDING_MODE
9494
(this as DecimalFormat).decimalFormatSymbols =
9595
decimalFormatSymbols.apply {
9696
currencySymbol = ""
@@ -133,6 +133,8 @@ data class Fiat(
133133
includeCommas = false
134134
).toDouble()
135135

136+
fun valueNonZero(): Boolean = toDouble() != 0.0
137+
136138
fun valueLessThan(other: Fiat): Boolean = toDouble() < other.toDouble()
137139
fun valueGreaterThan(other: Fiat): Boolean = toDouble() > other.toDouble()
138140
fun valueGreaterThanOrEqualTo(other: Fiat): Boolean = toDouble() >= other.toDouble()

services/opencode/src/main/kotlin/com/getcode/opencode/model/financial/LocalFiat.kt

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -103,33 +103,37 @@ data class LocalFiat(
103103
// USD is a 1:1 fx so we can be blind here
104104
val fx = rate.fx * usdFx.toDouble()
105105

106-
val sellAmount = Fiat.tokenBalance(quarks.toLong(), token = token)
106+
val sellAmountUsd = Fiat.tokenBalance(quarks.toLong(), token = token)
107107

108108
if (debug) {
109109
println("############## EXCHANGE REPORT ###################")
110-
println("requested quarks: ${usdValue.quarks * 1_000_000}")
111-
println("balance quarks: ${balance?.quarks?.times(1_000_000)}")
112-
println("capped quarks: ${cappedValue.quarks * 1_000_000}")
113-
println("circulating supply: $circulatingSupply")
114-
println("calculated quarks: $quarks")
115-
println("units: $units")
116-
println("fx: $fx")
117-
println("sellAmount: ${sellAmount.formatted(formatting = Fiat.Formatting.Length(10))}")
110+
println("requested currency: ${rate.currency.name}")
111+
println("requested amount: ${amount.formatted()}")
112+
println("requested quarks (in USD): ${usdValue.quarks * 1_000_000}")
113+
println("balance quarks (in USD): ${balance?.quarks?.times(1_000_000)}")
114+
println("capped quarks (in USD): ${cappedValue.quarks * 1_000_000}")
115+
println("circulating supply (of ${token.symbol}): $circulatingSupply")
116+
println("calculated quarks: $quarks")
117+
println("units: $units")
118+
println("fx: $fx")
119+
println("sellAmount: ${sellAmountUsd.formatted(formatting = Fiat.Formatting.Length(token.decimals))}")
118120
println("##################################################")
119121
}
120122

121123
trace(
122124
tag = "LocalFiat",
123125
message = "Bill created",
124126
metadata = {
125-
"requested quarks" to usdValue.quarks * 1_000_000
126-
"balance quarks" to balance?.quarks?.times(1_000_000)
127+
"requested currency" to rate.currency.name
128+
"requested amount" to amount.formatted()
129+
"requested quarks (in USD)" to usdValue.quarks * 1_000_000
130+
"balance quarks (in USD)" to balance?.quarks?.times(1_000_000)
131+
"capped quarks (in USD)" to cappedValue.quarks * 1_000_000
132+
"circulating supply of ${token.symbol}" to circulatingSupply
127133
"calculated quarks" to quarks
128134
"units" to units
129135
"fx" to fx
130-
"circulating supply" to circulatingSupply
131-
"capped value" to cappedValue.quarks * 1_000_000
132-
"sell amount" to sellAmount.formatted(formatting = Fiat.Formatting.Length(10))
136+
"sell amount (in USD)" to sellAmountUsd.formatted(formatting = Fiat.Formatting.Length(token.decimals))
133137
}
134138
)
135139

0 commit comments

Comments
 (0)