@@ -63,16 +63,14 @@ data class LocalFiat(
6363 fun valueExchangeIn (
6464 amount : Fiat ,
6565 token : Token ,
66+ balance : Fiat = Fiat .Zero ,
6667 rate : Rate ,
68+ debug : Boolean = false,
6769 ): LocalFiat {
68- val usdValue = if (rate.currency != CurrencyCode .USD ) {
69- amount.convertingTo(Rate (1 / rate.fx, rate.currency))
70- } else {
71- amount
72- }
70+ val usdValue = amount.convertingToUsdIfNeeded(rate)
7371
7472 if (token.address == Mint .usdc) {
75- // this doesn't need a calcuated value exchange since we are USDC
73+ // this doesn't need a calculated value exchange since we are USDC
7674 return if (rate.currency != CurrencyCode .USD ) {
7775 LocalFiat (
7876 usdc = usdValue,
@@ -83,25 +81,38 @@ data class LocalFiat(
8381 }
8482 }
8583
84+ val circulatingSupply = token.launchpadMetadata?.currentCirculatingSupplyQuarks ? : 0
8685
86+ val cappedValue = min(balance, usdValue)
8787
8888 // determine quarks to exchange for the desired amount
8989 val quarks = Estimator .valueExchangeAsQuarks(
90- valueInQuarks = usdValue.quarks,
91- currentSupplyInQuarks = token.launchpadMetadata?.currentCirculatingSupplyQuarks
92- ? : 0 ,
90+ valueInQuarks = cappedValue.quarks,
91+ currentSupplyInQuarks = circulatingSupply,
9392 mintDecimals = 6 , // usdc is 6 decimals
9493 ).getOrThrow()
9594
9695 // determine the "full units" of the token being exchanged
9796 val units = quarks.units()
9897 // determine the exchange rate (native amount / units of token) (USD based)
99- val usdFx = BigDecimal (usdValue .decimalValue).divideWithHighPrecision(units)
98+ val usdFx = BigDecimal (cappedValue .decimalValue).divideWithHighPrecision(units)
10099
101100 // determine the relative exchange rate of the token in the currency selected
102101 // USD is a 1:1 fx so we can be blind here
103102 val fx = rate.fx * usdFx.toDouble()
104103
104+ if (debug) {
105+ println (" requested quarks: ${usdValue.quarks * 1_000_000 } " )
106+ println (" balance quarks: ${balance.quarks * 1_000_000 } " )
107+ println (" capped quarks: ${cappedValue.quarks * 1_000_000 } " )
108+ println (" circulating supply: $circulatingSupply " )
109+ println (" calculated quarks: $quarks " )
110+ println (" units: $units " )
111+ println (" fx: $fx " )
112+ val sellAmount = Fiat .tokenBalance(quarks.toLong(), token = token)
113+ println (" sellAmount: ${sellAmount.formatted(formatting = Fiat .Formatting .Length (10 ))} " )
114+ }
115+
105116 return LocalFiat (
106117 underlyingTokenAmount = Fiat (quarks.toLong(), CurrencyCode .USD ),
107118 nativeAmount = amount,
@@ -126,9 +137,26 @@ fun Iterable<LocalFiat>.sum(): LocalFiat {
126137 acc
127138 }
128139
129- base.copy(
130- underlyingTokenAmount = base.underlyingTokenAmount + localFiat.underlyingTokenAmount,
131- nativeAmount = base.nativeAmount + localFiat.nativeAmount,
132- )
140+ base + localFiat
133141 }
134142}
143+
144+ operator fun LocalFiat.minus (other : LocalFiat ): LocalFiat {
145+ if (mint != other.mint) throw IllegalArgumentException (" Mint is mismatched" )
146+ if (rate.currency != other.rate.currency) throw IllegalArgumentException (" Currency is mismatched" )
147+
148+ return copy(
149+ underlyingTokenAmount = underlyingTokenAmount - other.underlyingTokenAmount,
150+ nativeAmount = nativeAmount - other.nativeAmount
151+ )
152+ }
153+
154+ operator fun LocalFiat.plus (other : LocalFiat ): LocalFiat {
155+ if (mint != other.mint) throw IllegalArgumentException (" Mint is mismatched" )
156+ if (rate.currency != other.rate.currency) throw IllegalArgumentException (" Currency is mismatched" )
157+
158+ return copy(
159+ underlyingTokenAmount = underlyingTokenAmount + other.underlyingTokenAmount,
160+ nativeAmount = nativeAmount + other.nativeAmount
161+ )
162+ }
0 commit comments