> ## Documentation Index
> Fetch the complete documentation index at: https://hedera-0c6e0218-docs-g53-fix-msgvalue-decimals-clarity.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Decimal Handling (8 vs. 18 Decimals)

## **Overview**

Managing token decimals is critical when working with HBAR, HTS tokens, and ERC tokens on Hedera, as each system has distinct precision standards. These differences impact how token balances are calculated, displayed, and transferred across various tools and environments.

***

## Token Decimal Comparison and API Context

The table below compares the decimal handling of HBAR, HTS tokens, and ERC tokens on Hedera, incorporating details about their representation across APIs and services. This overview highlights differences in precision and context.

<table><thead><tr><th>API/Service</th><th>Decimals</th><th>Explanation</th></tr></thead><tbody><tr><td><strong>Hedera API (HAPI)</strong></td><td>8 decimals</td><td>HBAR is represented with 8 decimal places, aligning with its native smallest unit tinybar.</td></tr><tr><td><strong>Hedera Smart Contract Service (EVM execution)</strong></td><td>8 decimals</td><td>Within the EVM, HBAR is tinybar-scaled: <code>msg.value</code>, <code>address(this).balance</code>, and the <code>value</code> passed to <code>call</code>/<code>send</code>/<code>transfer</code> are all 8 decimals during execution.</td></tr><tr><td><strong>JSON-RPC Relay (Arguments)</strong></td><td>8 decimals</td><td>When HBAR values are passed as arguments in JSON-RPC calls, they are represented with 8 decimal places.</td></tr><tr><td><strong>JSON-RPC Relay (<code>msg.value</code> / <code>gasPrice</code>) — RPC boundary only</strong></td><td>18 decimals</td><td>Ethereum tooling submits and reads the transaction <code>value</code> and <code>gasPrice</code> in 18-decimal weibar at the JSON-RPC boundary. <strong>The relay converts weibar to tinybar (÷10<sup>10</sup>) before the EVM executes</strong>, so the <code>msg.value</code> your contract actually sees is 8-decimal tinybar — not 18-decimal wei. See the warning below.</td></tr><tr><td><strong>HTS Tokens</strong></td><td>Configurable (up to 8 decimals)</td><td>HTS tokens allow token creators to define precision at token creation, offering flexibility for various use cases.</td></tr><tr><td><strong>ERC Tokens</strong></td><td>Default 18 decimals</td><td>ERC tokens on Hedera follow Ethereum token standards, with 18 decimals as the default unless specified otherwise.</td></tr></tbody></table>

**Key Impacts**:

* Account for scaling differences when converting HBAR between APIs, especially when using JSON-RPC.
* HBAR fees are always calculated in tinybars, regardless of the API or service used.
* The 18-decimal representation is a **JSON-RPC boundary convention only** — inside the EVM, native value is tinybar (8 decimals). Do not assume `msg.value` is wei-scale (see warning).

<Warning>
  **Inside a contract, native value is tinybar (8 decimals), not wei (18).** `msg.value`, `address(this).balance`, and the `value` you pass to `call`/`send`/`transfer` are all tinybar-denominated during EVM execution. Two cases to design for:

  * **Transactions from tooling (relay path).** When you send 1 HBAR as `value: 1 ether` (1e18 weibar), the relay divides by 10<sup>10</sup>, so your contract sees `msg.value == 1e8`. A contract that stores `msg.value` — e.g. a WETH-style wrapper reporting `decimals() = 18` — will record a balance 10<sup>10</sup> smaller than an Ethereum developer would expect.
  * **Contract-to-contract calls (no conversion).** `payable(x).call{value: 1 ether}("")` compiles `1 ether` to `1e18` and sends it **as tinybar** (= 10<sup>10</sup> HBAR), which either reverts (insufficient balance) or over-transfers. Specify the value in tinybar instead.

  ```solidity theme={null}
  // ❌ BROKEN — `1 ether` compiles to 1e18 and is treated as tinybar (= 10^10 HBAR)
  (bool ok, ) = payable(vault).call{value: 1 ether}("");

  // ✅ CORRECT — specify the value in tinybar (1 HBAR = 100,000,000 tinybar)
  (bool ok, ) = payable(vault).call{value: 100000000}("");
  ```
</Warning>

***

## Conversion Helpers

Utility functions are essential for managing discrepancies between HBAR (measured in tinybars, 8 decimals), HTS tokens (which can have configurable decimal places), and ERC tokens (measured in wei, 18 decimals). These conversions ensure consistency across your smart contracts, front-end applications, and APIs.

**Code Example: Decimal Conversion Helpers**

```solidity wrap theme={null}
// Convert from 18 decimals (weibar/wei) to 8 decimals (tinybar)
function convertToTinybar(uint256 weiAmount) public pure returns (uint256) {
    // 1 tinybar = 10^10 weibar
    return weiAmount / (10 ** 10);
}

// Convert from 8 decimals (tinybar) to 18 decimals (weibar/wei)
function convertToWei(uint256 tinybarAmount) public pure returns (uint256) {
    return tinybarAmount * (10 ** 10);
}
```

Reference: [**Smart Contracts Gas and Fees**](/evm/development/gas-fees)

***

### **Additional Resources**

* [**ERC-20 Token Standard**](/evm/tokens/erc20)
* [**Hedera Token Service Documentation**](/learn/core-concepts/tokens)
* [**HBAR Decimal Places Documentation**](/native/fundamentals/hbars#hbar-decimal-places)
* [**Token Managed by Smart Contracts**](/evm/tokens)
