Skip to content

Commit

Permalink
fix(swap): Fix limit price precision / denomination (#2771)
Browse files Browse the repository at this point in the history
  • Loading branch information
michaeljscript authored Oct 15, 2023
1 parent b677695 commit d87f736
Show file tree
Hide file tree
Showing 6 changed files with 506 additions and 438 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,9 @@ export const EditLimitPrice = () => {
}, [orderData.type, orderData.limitPrice, orderData.amounts.sell, denomination, orderData.selectedPoolCalculation])

const onChange = (text: string) => {
const [formattedPrice, price] = Quantities.parseFromText(text, PRECISION, numberLocale)
const value = Quantities.denominated(price, PRECISION)

const [formattedPrice, price] = Quantities.parseFromText(text, denomination, numberLocale, PRECISION)
setText(formattedPrice)
limitPriceChanged(value)
limitPriceChanged(price)
}

return (
Expand Down
3 changes: 3 additions & 0 deletions apps/wallet-mobile/src/yoroi-wallets/utils/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ describe('Quantities', () => {
expect(Quantities.parseFromText('55.10', 3, english)).toEqual(['55.10', '55100'])

expect(Quantities.parseFromText('ab1.5c,6.5', 3, english)).toEqual(['1.56', '1560'])

expect(Quantities.parseFromText('1.23456', 0, english, 3)).toEqual(['1.234', '1.234'])
expect(Quantities.parseFromText('1.23456', 2, english, 3)).toEqual(['1.234', '123.4'])
})
})

Expand Down
48 changes: 35 additions & 13 deletions apps/wallet-mobile/src/yoroi-wallets/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,26 +133,48 @@ export const Quantities = {

return absoluteQuantity.isEqualTo(minimalFractionalPart)
},
parseFromText: (text: string, denomination: number, format: NumberLocale) => {
parseFromText: (
text: string,
denomination: number,
format: NumberLocale,
precision = denomination,
): [string, Balance.Quantity] => {
const {decimalSeparator} = format
const invalid = new RegExp(`[^0-9${decimalSeparator}]`, 'g')
const sanitized = text === '' ? '' : text.replaceAll(invalid, '')
if (sanitized === '') return ['', `0`] as [string, Balance.Quantity]
if (sanitized.startsWith(decimalSeparator)) return [`0${decimalSeparator}`, `0`] as [string, Balance.Quantity]

if (sanitized === '') return ['', Quantities.zero]
if (sanitized.startsWith(decimalSeparator)) return [`0${decimalSeparator}`, Quantities.zero]

const parts = sanitized.split(decimalSeparator)
const isDec = parts.length >= 2

const fullDecValue = isDec ? `${parts[0]}${decimalSeparator}${parts[1].slice(0, denomination)}1` : sanitized
const fullDecFormat = new BigNumber(fullDecValue.replace(decimalSeparator, '.')).toFormat()
const input = isDec ? fullDecFormat.slice(0, -1) : fullDecFormat
let fullDecValue = sanitized
let value = sanitized

let fullDecFormat = new BigNumber(fullDecValue.replace(decimalSeparator, '.')).toFormat()
let input = fullDecFormat

if (parts.length <= 1) {
const quantity = asQuantity(
new BigNumber(value.replace(decimalSeparator, '.')).decimalPlaces(precision).shiftedBy(denomination),
)

const value = isDec ? `${parts[0]}${decimalSeparator}${parts[1].slice(0, denomination)}` : sanitized
const quantity = new BigNumber(value.replace(decimalSeparator, '.'))
.decimalPlaces(denomination)
.shiftedBy(denomination)
.toString(10)
return [input, quantity]
}

const [int, dec] = parts
// trailing `1` is to allow the user to type `1.0` without losing the decimal part
fullDecValue = `${int}${decimalSeparator}${dec?.slice(0, precision)}1`
value = `${int}${decimalSeparator}${dec?.slice(0, precision)}`
fullDecFormat = new BigNumber(fullDecValue.replace(decimalSeparator, '.')).toFormat()
// remove trailing `1`
input = fullDecFormat.slice(0, -1)

const quantity = asQuantity(
new BigNumber(value.replace(decimalSeparator, '.')).decimalPlaces(precision).shiftedBy(denomination),
)

return [input, quantity] as [string, Balance.Quantity]
return [input, quantity]
},
format: (quantity: Balance.Quantity, denomination: number, precision?: number) => {
if (precision === undefined) return new BigNumber(Quantities.denominated(quantity, denomination)).toFormat()
Expand Down
Loading

0 comments on commit d87f736

Please sign in to comment.