@ -6,31 +6,39 @@ const DEFAULT_MIN_ROUNDED_VALUE = 0.00001;
const DEFAULT_DISPLAY_DECIMALS = 4 ;
const DEFAULT_TOKEN_DECIMALS = 18 ;
type NumberT = BigNumber . Value ;
// Use toString(10) on bignumber.js to prevent ethers.js bigNumber error
// when parsing exponential string over e21
/ * *
* Convert the given Wei value to Ether value
* @param value The value to convert .
* @returns Converted value in string type .
* /
export function fromWei (
value : NumberT | null | undefined ,
value : BigNumber.Value | null | undefined ,
decimals = DEFAULT_TOKEN_DECIMALS ,
) : number {
if ( ! value ) return 0 ;
const valueString = value . toString ( ) . trim ( ) ;
const flooredValue = new BigNumber ( valueString ) . toFixed (
0 ,
BigNumber . ROUND_FLOOR ,
) ;
return parseFloat ( formatUnits ( flooredValue , decimals ) ) ;
) : string {
if ( ! value ) return ( 0 ) . toString ( ) ;
const valueString = value . toString ( 10 ) . trim ( ) ;
const flooredValue = BigNumber ( valueString ) . toFixed ( 0 , BigNumber . ROUND_FLOOR ) ;
return parseFloat ( formatUnits ( flooredValue , decimals ) ) . toString ( ) ;
}
// Similar to fromWei above but rounds to set number of decimals
// with a minimum floor, configured per token
/ * *
* Convert the given Wei value to Ether value ,
* round to set number of decimals with a minimum floor , configured per token
* @param value The value to convert .
* @param decimals
* @returns Converted value in string type .
* /
export function fromWeiRounded (
value : NumberT | null | undefined ,
value : BigNumber.Value | null | undefined ,
decimals = DEFAULT_TOKEN_DECIMALS ,
roundDownIfSmall = true ,
) : string {
if ( ! value ) return '0' ;
const flooredValue = new BigNumber ( value ) . toFixed ( 0 , BigNumber . ROUND_FLOOR ) ;
const amount = new BigNumber ( formatUnits ( flooredValue , decimals ) ) ;
const flooredValue = BigNumber ( value ) . toFixed ( 0 , BigNumber . ROUND_FLOOR ) ;
const amount = BigNumber ( formatUnits ( flooredValue , decimals ) ) ;
if ( amount . isZero ( ) ) return '0' ;
// If amount is less than min value
@ -40,38 +48,49 @@ export function fromWeiRounded(
}
const displayDecimals = amount . gte ( 10000 ) ? 2 : DEFAULT_DISPLAY_DECIMALS ;
return amount . toFixed ( displayDecimals ) . toString ( ) ;
return amount . toFixed ( displayDecimals ) ;
}
/ * *
* Convert the given value to Wei value
* @param value The value to convert .
* @returns Converted value in string type .
* /
export function toWei (
value : NumberT | null | undefined ,
value : BigNumber.Value | null | undefined ,
decimals = DEFAULT_TOKEN_DECIMALS ,
) : BigNumber {
if ( ! value ) return new BigNumber ( 0 ) ;
) : string {
if ( ! value ) return BigNumber ( 0 ) . toString ( ) ;
// First convert to a BigNumber, and then call `toString` with the
// explicit radix 10 such that the result is formatted as a base-10 string
// and not in scientific notation.
const valueBN = new BigNumber ( value ) ;
const valueBN = BigNumber ( value ) ;
const valueString = valueBN . toString ( 10 ) . trim ( ) ;
const components = valueString . split ( '.' ) ;
if ( components . length === 1 ) {
return new BigNumber ( parseUnits ( valueString , decimals ) . toString ( ) ) ;
return parseUnits ( valueString , decimals ) . toString ( ) ;
} else if ( components . length === 2 ) {
const trimmedFraction = components [ 1 ] . substring ( 0 , decimals ) ;
return new BigNumber (
parseUnits ( ` ${ components [ 0 ] } . ${ trimmedFraction } ` , decimals ) . toString ( ) ,
) ;
return parseUnits (
` ${ components [ 0 ] } . ${ trimmedFraction } ` ,
decimals ,
) . toString ( ) ;
} else {
throw new Error ( ` Cannot convert ${ valueString } to wei ` ) ;
}
}
/ * *
* Try to parse the given value into BigNumber . js BigNumber
* @param value The value to parse .
* @returns Parsed value in BigNumber . js BigNumber type .
* /
export function tryParseAmount (
value : NumberT | null | undefined ,
value : BigNumber.Value | null | undefined ,
) : BigNumber | null {
try {
if ( ! value ) return null ;
const parsed = new BigNumber ( value ) ;
const parsed = BigNumber ( value ) ;
if ( ! parsed || parsed . isNaN ( ) || ! parsed . isFinite ( ) ) return null ;
else return parsed ;
} catch ( error ) {
@ -79,15 +98,20 @@ export function tryParseAmount(
}
}
// Checks if an amount is equal of nearly equal to balance within a small margin of error
// Necessary because amounts in the UI are often rounded
/ * *
* Checks if an amount is equal of nearly equal to balance within a small margin of error
* Necessary because amounts in the UI are often rounded
* @param amountInWei1 The amount to compare .
* @param amountInWei2 The amount to compare .
* @returns true / false .
* /
export function eqAmountApproximate (
amountInWei1 : BigNumber ,
amountInWei2 : NumberT ,
) {
amountInWei1 : BigNumber.Value ,
amountInWei2 : BigNumber.Value ,
) : boolean {
const minValueWei = toWei ( DEFAULT_MIN_ROUNDED_VALUE ) ;
// Is difference btwn amount and balance less than min amount shown for token
return amountInWei1 . minus ( amountInWei2 ) . abs ( ) . lt ( minValueWei ) ;
return BigNumber ( amountInWei1 ) . minus ( amountInWei2 ) . abs ( ) . lt ( minValueWei ) ;
}
/ * *
@ -96,26 +120,27 @@ export function eqAmountApproximate(
* @param fromDecimals The number of decimals ` value ` has .
* @param toDecimals The number of decimals to convert ` value ` to .
* @param value The value to convert .
* @returns ` value ` represented with ` toDecimals ` decimals .
* @returns ` value ` represented with ` toDecimals ` decimals in string type .
* /
export function convertDecimals (
fromDecimals : number ,
toDecimals : number ,
value : NumberT ,
) {
const amount = new BigNumber ( value ) ;
value : BigNumber.Value ,
) : string {
const amount = BigNumber ( value ) ;
if ( fromDecimals === toDecimals ) return amount ;
if ( fromDecimals === toDecimals ) return amount . toString ( 10 ) ;
else if ( fromDecimals > toDecimals ) {
const difference = fromDecimals - toDecimals ;
return amount
. div ( new BigNumber ( 10 ) . pow ( difference ) )
. integerValue ( BigNumber . ROUND_FLOOR ) ;
. div ( BigNumber ( 10 ) . pow ( difference ) )
. integerValue ( BigNumber . ROUND_FLOOR )
. toString ( 10 ) ;
}
// fromDecimals < toDecimals
else {
const difference = toDecimals - fromDecimals ;
return amount . times ( new BigNumber ( 10 ) . pow ( difference ) ) ;
return amount . times ( BigNumber ( 10 ) . pow ( difference ) ) . toString ( 10 ) ;
}
}