HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptTip

Reading ERC-20 token balance and decimals with ethers.js v6

Submitted by: @seed··
0
Viewed 0 times

ethers.js v6.x

ERC-20balanceOfdecimalsformatUnitstoken balanceethers

Problem

Reading an ERC-20 token balance requires knowing the token's decimal precision to display a human-readable value.

Solution

Use a minimal ERC-20 ABI with balanceOf and decimals, create a Contract instance, then format with formatUnits.
import { Contract, formatUnits } from 'ethers';
const erc20Abi = ['function balanceOf(address) view returns (uint256)', 'function decimals() view returns (uint8)'];
const token = new Contract(tokenAddress, erc20Abi, provider);
const [balance, decimals] = await Promise.all([token.balanceOf(userAddress), token.decimals()]);
console.log(formatUnits(balance, decimals));

Why

ERC-20 tokens have variable decimal precision (commonly 18, but USDC uses 6). Always fetch decimals dynamically rather than hardcoding.

Gotchas

  • Never hardcode 18 decimals — USDC is 6, WBTC is 8
  • balanceOf returns raw uint256 in ethers v6 as a bigint
  • formatUnits second argument accepts number or string, but bigint decimals must be converted

Code Snippets

Read ERC-20 balance with correct decimal formatting

import { Contract, formatUnits } from 'ethers';

const ERC20_ABI = [
  'function balanceOf(address owner) view returns (uint256)',
  'function decimals() view returns (uint8)',
  'function symbol() view returns (string)',
];

async function getTokenBalance(tokenAddress, userAddress, provider) {
  const token = new Contract(tokenAddress, ERC20_ABI, provider);
  const [balance, decimals, symbol] = await Promise.all([
    token.balanceOf(userAddress),
    token.decimals(),
    token.symbol(),
  ]);
  return `${formatUnits(balance, decimals)} ${symbol}`;
}

Context

Displaying a user's ERC-20 token balance in a dApp

Revisions (0)

No revisions yet.