BigDecimal

High-precision decimal arithmetic for AaveKit


AaveKit represents all decimal numbers using the BigDecimal type to ensure high-precision arithmetic for financial computations. Whenever you interact with balances, rates, or amounts in the SDK, they are returned as BigDecimal instances.

// Import from AaveKit Reactimport { bigDecimal, BigDecimal } from "@aave/react";
// Import from AaveKit TypeScriptimport { bigDecimal, BigDecimal } from "@aave/client";

Key Features:

  • Arbitrary precision arithmetic

  • Safe conversion from various numeric types

  • Display formatting with adaptive precision

  • Static utility methods for common operations

  • Type-safe operations that return BigDecimal instances

BigDecimal is immutable — its methods never modify the instance in place but always return a new one. It is based on the big.js library and provides consistent behavior across Node.js and browser environments.

Creating BigDecimals

// From string (recommended for precision)const a = bigDecimal("123.456789");
// From numberconst b = bigDecimal(123.456);
// From bigintconst c = bigDecimal(123456789n);

Arithmetic Operations

All arithmetic operations return new BigDecimal instances, making them safe for immutable workflows.

Addition

const a = bigDecimal("100");const b = bigDecimal("50");
a.plus(b); // BigDecimal('150')a.add(b); // Alias for .plus()

Subtraction

const a = bigDecimal("100");const b = bigDecimal("30");
a.minus(b); // BigDecimal('70')a.sub(b); // Alias for .minus()

Multiplication

const a = bigDecimal("10");const b = bigDecimal("5");
a.times(b); // BigDecimal('50')a.mul(b); // Alias for .times()

Division

const a = bigDecimal("100");const b = bigDecimal("3");
a.div(b); // BigDecimal('33.333...')
// Division by zero throwsbigDecimal("10").div("0"); // Throws: ±InfinitybigDecimal("0").div("0"); // Throws: NaN

Modulo

const a = bigDecimal("10");const b = bigDecimal("3");
a.mod(b); // BigDecimal('1')

Power

const a = bigDecimal("2");
a.pow(3); // BigDecimal('8')a.pow(-1); // BigDecimal('0.5')
// Range: -1e+6 to 1e+6 inclusive

Square Root

const a = bigDecimal("16");
a.sqrt(); // BigDecimal('4')
// Negative numbers throwbigDecimal("-1").sqrt(); // Throws: NaN

Absolute Value

const a = bigDecimal("-123.45");
a.abs(); // BigDecimal('123.45')

Negation

const a = bigDecimal("123.45");
a.neg(); // BigDecimal('-123.45')

Comparison Methods

All comparison methods are inherited from big.js:

const a = bigDecimal("100");const b = bigDecimal("50");
a.gt(b); // true  - greater thana.gte(b); // true  - greater than or equala.lt(b); // false - less thana.lte(b); // false - less than or equala.eq(b); // false - equal toa.cmp(b); // 1     - compare (-1, 0, or 1)

Rounding & Precision

Rounding Modes

enum RoundingMode {  Down = 0, // Towards zero (truncate)  HalfUp = 1, // Nearest neighbor; away from zero if equidistant  HalfEven = 2, // Nearest neighbor; towards even if equidistant  Up = 3, // Away from zero}

Round to Decimal Places

const a = bigDecimal("123.456789");
a.round(2, RoundingMode.HalfUp); // BigDecimal('123.46')a.round(0, RoundingMode.Down); // BigDecimal('123')a.round(); // BigDecimal('123') - defaults to 0 dp

Round to Significant Digits

const a = bigDecimal("123.456789");
a.prec(4, RoundingMode.HalfUp); // BigDecimal('123.5')a.prec(2, RoundingMode.Down); // BigDecimal('120')

Scaling

Multiply by 10^decimals (commonly used for on-chain conversions):

const amount = bigDecimal("1.5");
// Scale up (e.g., ETH to wei)amount.rescale(18); // BigDecimal('1500000000000000000')
// Scale down (e.g., wei to ETH)const wei = bigDecimal("1500000000000000000");wei.rescale(-18); // BigDecimal('1.5')

Display Formatting

Adaptive Precision Display

The toDisplayString method provides intelligent formatting based on number magnitude:

const large = bigDecimal("1234.5678");const small = bigDecimal("0.0001234");
// For numbers >= 1: preserves integer digits, controls decimal precisionlarge.toDisplayString(6); // '1234.57' (all integer digits + 2 decimals)
// For numbers < 1: uses significant figuressmall.toDisplayString(3); // '0.000123' (3 significant figures)

Formatting Options

const num = bigDecimal("123.456789");
// Basic precisionnum.toDisplayString(5);// '123.46'
// With rounding modenum.toDisplayString(4, { rounding: RoundingMode.Down });// '123.4'
// With minimum fraction digitsnum.toDisplayString(3, { minFractionDigits: 4 });// '123.4568' (enforces 4 decimal places)
// Trim trailing zerosnum.toDisplayString(10, { trimTrailingZeros: true });// '123.456789' (no trailing zeros)
// Combined optionsbigDecimal("100.5000").toDisplayString(5, {  minFractionDigits: 2,  trimTrailingZeros: true,});// '100.5' (trims trailing zeros but respects minimum)

Examples by Number Type

// Large numbers: preserves all integer digitsbigDecimal("1234567.89").toDisplayString(10);// '1234567.890'
// Small decimals: significant figuresbigDecimal("0.00001234").toDisplayString(3);// '0.0000123'
// Zero handlingbigDecimal("0").toDisplayString(5);// '0'
bigDecimal("0").toDisplayString(3, { minFractionDigits: 2 });// '0.00'

Conversion Methods

To String

const a = bigDecimal("123.456");
a.toString(); // '123.456'a.toJSON(); // '123.456' (used by JSON.stringify)
a.toFixed(); // '123.456' (fixed-point notation)a.toFixed(2); // '123.46' (2 decimal places)a.toFixed(2, RoundingMode.Down); // '123.45' (with rounding mode)
a.toExponential(); // '1.23456e+2'a.toExponential(2); // '1.23e+2' (2 decimal places)
a.toPrecision(); // '123.456'a.toPrecision(2); // '1.2e+2' (2 significant digits)a.toPrecision(4, RoundingMode.Down); // '123.4' (4 sig digits)

To Number (Approximate)

Convert to JavaScript number with safe clamping:

const safe = bigDecimal("123.456");safe.toApproximateNumber(); // 123.456
// Handles extreme valuesconst huge = bigDecimal("1e500");huge.toApproximateNumber(); // Number.MAX_VALUE (clamped)
const tiny = bigDecimal("1e-500");tiny.toApproximateNumber(); // 0 (subnormal → zero)
const negHuge = bigDecimal("-1e500");negHuge.toApproximateNumber(); // -Number.MAX_VALUE (clamped)

Use Cases:

  • Displaying approximate values in UI

  • Interfacing with APIs requiring number types

  • When precision loss is acceptable

Only use when precision loss is acceptable. For precise calculations, always use BigDecimal operations.

Static Utility Methods

Type Guard

const value: unknown = bigDecimal("123");
if (BigDecimal.isBigDecimal(value)) {  // value is BigDecimal  value.plus("10");}

Min/Max

const a = bigDecimal("100");const b = bigDecimal("50");const c = bigDecimal("75");
BigDecimal.min(a, b, c); // BigDecimal('50')BigDecimal.max(a, b, c); // BigDecimal('100')
// Minimum two arguments requiredBigDecimal.min(a, b); // BigDecimal('50')

Best Practices

  1. Use string literals for precision:

    // Goodconst amount = bigDecimal("0.1");
    // Risky (0.1 already has floating-point error)const amount = bigDecimal(0.1);
  2. Chain operations for clarity:

    const result = bigDecimal("100")  .times("1.05") // Apply 5% increase  .round(2, RoundingMode.HalfUp);
  3. Store monetary values as BigDecimal:

    interface Transaction {  amount: BigDecimal; // Not number!  currency: string;}
  4. Use toDisplayString() for UI formatting:

    // Adaptive precision for displayconst formatted = balance.toDisplayString(6);