fix: withdraw/deposit converts from BZZ (10^16 base units) (#66)

* refactor: added toBZZbaseUnit function

* feat: added utility for attesting value is BZZ convertible to base units

* fix: conversion from 15 to 16 decimal places, added unsafe versions

* refactor: withdraw modal uses the safe conversion from BZZ

* refactor: added BigNumber and Token class to handle BZZ digits correctly

* refactor: extract deposit and withdraw functionality into single modal

* test: added tests for Token

* chore: removed unused component

* chore: addressed PR review, token decimal is now integer 0-18

* chore: added comment to clarify the value restriction on token amount
This commit is contained in:
Vojtech Simetka
2021-04-13 12:26:29 +02:00
committed by GitHub
parent 343e388498
commit 825772cf73
19 changed files with 411 additions and 238 deletions
-3
View File
@@ -1,3 +0,0 @@
export const ConvertBalanceToBZZ = (amount: number): number => {
return amount / 10 ** 16
}
+71
View File
@@ -0,0 +1,71 @@
import BigNumber from 'bignumber.js'
import { fromBZZbaseUnit, isInteger, makeBigNumber } from './index'
describe('utils', () => {
describe('fromBZZbaseUnit', () => {
const values = [
{ bzz: 0, baseUnits: 0 },
{ bzz: 0.1, baseUnits: 1e15 },
{ bzz: 0.9, baseUnits: 9e15 },
]
values.forEach(({ bzz, baseUnits }) => {
test(`converting ${bzz} => ${baseUnits}`, () => {
expect(fromBZZbaseUnit(baseUnits)).toBe(bzz)
})
})
})
describe('isInteger', () => {
const correctValues = [
BigInt(0),
BigInt(1),
BigInt(-1),
new BigNumber('1'),
new BigNumber('0'),
new BigNumber('-1'),
]
const wrongValues = ['1', new BigNumber('-0.1'), new BigNumber(NaN), new BigNumber(Infinity)]
correctValues.forEach(v => {
test(`testing ${v}`, () => {
expect(isInteger(v)).toBe(true)
})
})
wrongValues.forEach(v => {
test(`testing ${v}`, () => {
expect(isInteger(v)).toBe(false)
})
})
})
describe('makeBigNumber', () => {
const correctValues = [
BigInt(0),
BigInt(1),
BigInt(-1),
'1',
'0',
'-1',
'0.1',
new BigNumber('1'),
new BigNumber('0'),
new BigNumber('-1'),
]
const wrongValues = [new Function(), 0, 1]
correctValues.forEach(v => {
test(`testing ${v}`, () => {
expect(BigNumber.isBigNumber(makeBigNumber(v))).toBe(true)
})
})
wrongValues.forEach(v => {
test(`testing ${v}`, () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
expect(() => makeBigNumber((v as unknown) as any)).toThrow()
})
})
})
})
+48
View File
@@ -0,0 +1,48 @@
import { BigNumber } from 'bignumber.js'
/**
* @deprecated Should be removed in favour of Token class
*/
const BZZ_BASE_UNIT = 1e16
/**
* Convert from base units of BZZ token to BZZ
* @deprecated This should only be used for displaying values, it's unsafe and should be replaced with Token class
*
* @param amount Amount in base units of BZZ token
*
* @returns amount in BZZ
*/
export const fromBZZbaseUnit = (amount: number): number => {
return amount / BZZ_BASE_UNIT
}
/**
* Test if value is an integer
*
* @param value Value to be tested if it is an integer
*
* @returns True if the passed in value is integer
*/
export function isInteger(value: unknown): value is BigNumber | bigint {
return (BigNumber.isBigNumber(value) && value.isInteger()) || typeof value === 'bigint'
}
/**
*Convert value into a BigNumber if not already
*
* @param value Value to be converted
*
* @throws {TypeError} if the value is not convertible to a BigNumber
*
* @returns BigNumber - but it may still be NaN or Infinite
*/
export function makeBigNumber(value: BigNumber | bigint | string): BigNumber | never {
if (BigNumber.isBigNumber(value)) return value
if (typeof value === 'string') return new BigNumber(value)
if (typeof value === 'bigint') return new BigNumber(value.toString())
throw new TypeError('Not a BigNumber or BigNumber convertible value')
}