Skip to content

A class for managing large numbers with a decimal scale, useful for web3 development

License

Notifications You must be signed in to change notification settings

merofinance/scaled-number

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

41 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Scaled Number

npm package Build Status Downloads Issues Semantic Release

A class for managing large numbers with a decimal scale, useful for web3 development.

Install

yarn add scaled-number

Basic Usage

import { ScaledNumber } from 'scaled-number';

const scaledNumber = ScaledNumber.fromUnscaled(123);
console.log(scaledNumber.mul(10).toString());

Example Web3 Usage

import { ScaledNumber } from 'scaled-number';
import { getTokenDecimals, getContract, getPrice } from "helpers";

export interface Pool {
	symbol: string;
	tvl: ScaledNumber;
	apy: ScaledNumber;
}

// Returns some key info about a Pool
export const getPoolInfo = async (poolAddress: string): Pool => {
  const pool = getContract(poolAddress);

  // Getting Pool info
  const [
    underlyingAddress,
    tvlBN,
    apyBN
  ] = await Promise.all([
    pool.underlyingAddress(),
    pool.tvl(),
    pool.apy(),
  ]);

  // Getting the underlying info
  const underlying = getContract(underlyingAddress);
  const [
    decimals,
    symbol
  ] = await Promise.all([
    underlying.decimals(),
    underlying.symbol()
  ]);

  // Getting the TVL as a Scaled Number (using the underlying decimals)
  const tvl = new ScaledNumber(tvlBN, decimals);

  // Getting the APY as a Scaled Number (uses default 18 decimals)
  const apy = new ScaledNumber(apyBN);

  return {
    symbol
    tvl,
    apy
  }
}

// Logs key information about a pool
export const logPoolInfo = async (pool: Pool): void => {
  // Getting the price of the underlying
  const price = await getPrice(pool.symbol);

  console.log(`Underlying Balance: ${pool.tvl.toCryptoString()} ${pool.symbol}`);
  // Output: `Underlying Balance: 12,456.87 ETH`

  console.log(`TVL: ${pool.tvl.toCompactUsdValue(price)}`);
  // Output: `TVL: $13.4m`

  console.log(pool.apy.toPercent())
  // Output: `24.34%`
}

Creating Scaled Number

From bigint

new ScaledNumber(bigInt: bigint, decimals?: number);
import { ScaledNumber } from 'scaled-number';

const scaledNumber = new ScaledNumber(BigInt(123));

From BigNumber

new ScaledNumber(bigNumber: BigNumber, decimals?: number);
import { ScaledNumber } from 'scaled-number';
import { BigNumber } from '@ethersproject/bignumber';

const scaledNumber = new ScaledNumber(BigNumber.from(123));

From Unscaled

fromUnscaled(value: number | string = 0, decimals = 18)
import { ScaledNumber } from 'scaled-number';

const scaledNumber = ScaledNumber.fromUnscaled(123, 8);

From Plain

fromPlain(value: PlainScaledNumber)
import { ScaledNumber } from 'scaled-number';

const scaledNumber = ScaledNumber.fromPlain({
  value: '123000000',
  decimals: 6,
});

Manipulate

Add

add(other: ScaledNumber)
const one = ScaledNumber.fromUnscaled(1);
const two = ScaledNumber.fromUnscaled(2);

const three = one.add(two);

console.log(three.toString()); // 3

Subtract

sub(other: ScaledNumber)
const three = ScaledNumber.fromUnscaled(3);
const two = ScaledNumber.fromUnscaled(2);

const one = three.sub(two);

console.log(one.toString()); // 1

Maximum

max(other: ScaledNumber)
const three = ScaledNumber.fromUnscaled(3);
const two = ScaledNumber.fromUnscaled(2);

const max = three.max(two);

console.log(max.toString()); // 3

Mimimum

min(other: ScaledNumber)
const three = ScaledNumber.fromUnscaled(3);
const two = ScaledNumber.fromUnscaled(2);

const min = three.min(two);

console.log(min.toString()); // 2

Multiply

mul(value: number | string | ScaledNumber)
const three = ScaledNumber.fromUnscaled(3);

const six = three.mul(2);

console.log(six.toString()); // 6

Divide

div(value: number | string | ScaledNumber)
const six = ScaledNumber.fromUnscaled(3);

const three = three.div(2);

console.log(three.toString()); // 3

Display

String

toString(): string
const sn = ScaledNumber.fromUnscaled(1.234);

console.log(sn.toString()); // 1.234

Number

toNumber(): number
const sn = ScaledNumber.fromUnscaled(1.234);

console.log(sn.toNumber()); // 1.234

Crypto String

toCryptoString(): string
const sn = ScaledNumber.fromUnscaled('12345678.12345678');

console.log(sn.toCryptoString()); // 12,345,678
const sn = ScaledNumber.fromUnscaled('12.12345678');

console.log(sn.toCryptoString()); // 12.123
const sn = ScaledNumber.fromUnscaled('0.0000000123');

console.log(sn.toCryptoString()); // 0.0000000123

Crypto String

toCryptoString(): string
const sn = ScaledNumber.fromUnscaled('12345678.12345678');

console.log(sn.toCryptoString()); // 12,345,678
const sn = ScaledNumber.fromUnscaled('12.12345678');

console.log(sn.toCryptoString()); // 12.123
const sn = ScaledNumber.fromUnscaled('0.0000000123');

console.log(sn.toCryptoString()); // 0.0000000123

USD Value

toUsdValue(price: number): string
const sn = ScaledNumber.fromUnscaled('12345678.12345678');

console.log(sn.toUsdValue(7)); // $86,419,746.86

Compact USD Value

toCompactUsdValue(price: number): string
const sn = ScaledNumber.fromUnscaled('12345678.12345678');

console.log(sn.toCompactUsdValue(7)); // $86,4m

Percent

toPercent(): string
const sn = ScaledNumber.fromUnscaled('0.12345678');

console.log(sn.toPercent()); // 12.34%

Query

Value

value: bigint;
const sn = ScaledNumber.fromUnscaled('0.123', 5);

console.log(sn.value.toString()); // 12300

Decimals

decimals: number;
const sn = ScaledNumber.fromUnscaled('0.123', 5);

console.log(sn.decimals); // 5

toPlain

toPlain(): PlainScaledNumber
const sn = ScaledNumber.fromUnscaled('0.123', 5);

console.log(sn.toPlain()); // { value: "12300", decimals: 5 }

Is Zero

isZero(): boolean
const sn = ScaledNumber.fromUnscaled('0.123', 5);

console.log(sn.isZero()); // false
const sn = ScaledNumber.fromUnscaled();

console.log(sn.isZero()); // true

Is Negative

isNegative(): boolean
const sn = ScaledNumber.fromUnscaled('0.123', 5);

console.log(sn.isNegative()); // false
const sn = ScaledNumber.fromUnscaled('-0.123', 5);

console.log(sn.isNegative()); // true

Equal

eq(): boolean
const first = ScaledNumber.fromUnscaled(1);
const second = ScaledNumber.fromUnscaled(2);

console.log(first.eq(second)); // false
const first = ScaledNumber.fromUnscaled(1);
const second = ScaledNumber.fromUnscaled(1);

console.log(first.eq(second)); // true

Greater Than

gt(): boolean
const first = ScaledNumber.fromUnscaled(1);
const second = ScaledNumber.fromUnscaled(2);

console.log(first.gt(second)); // false

Greater Than or Equal

gte(): boolean
const first = ScaledNumber.fromUnscaled(1);
const second = ScaledNumber.fromUnscaled(1);

console.log(first.gte(second)); // true

Less Than

lt(): boolean
const first = ScaledNumber.fromUnscaled(1);
const second = ScaledNumber.fromUnscaled(2);

console.log(first.lt(second)); // true

Less Than or Equal

lte(): boolean
const first = ScaledNumber.fromUnscaled(1);
const second = ScaledNumber.fromUnscaled(1);

console.log(first.lte(second)); // true

Less Than or Equal

lte(): boolean
const first = ScaledNumber.fromUnscaled(1);
const second = ScaledNumber.fromUnscaled(1);

console.log(first.lte(second)); // true