ERC-20 decimals explains how a raw integer token amount becomes the number shown to a person. The key relationship is a scale: divide the raw amount by 10 raised to the decimals value. Reading that relationship correctly requires the decimals value for the particular token, rather than a number borrowed from another token or a familiar example.
There are two separate questions to keep in view: does the token provide this optional metadata, and what value does its implementation use? OpenZeppelin’s default helps explain one implementation, but it does not answer those questions for every ERC-20 token. The examples below use invented inputs solely to explain the arithmetic.
What ERC-20 decimals actually specifies
The EIP-20 token standard describes decimals as the number used to obtain a token amount’s user representation. Crucially, the method is optional. Interfaces and other contracts must not assume that the metadata is present. That qualification belongs in any explanation of decimals, because a scaling formula needs an appropriate input before it can produce a meaningful display.
Think of a token amount as having two related descriptions: an integer count of raw units and a scaled number intended for reading. Decimals supplies the scale between those descriptions. When interpreting an amount, keep the raw integer alongside the decimals value instead of treating a formatted number as self-explanatory.
For this purpose, the notation 10 ** decimals means ten raised to the power of decimals. It is the divisor used in the display conversion. The word decimals therefore refers to the scale used for representation, rather than an instruction to perform contract accounting with fractional raw units.
Raw integers and displayed amounts
The OpenZeppelin ERC-20 guide explains the accounting through integer amounts. Arithmetic inside the token contract remains integer arithmetic, while interfaces adjust the displayed values according to decimals. Its hypothetical GLD example illustrates the distinction between the raw count and the amount a person reads.
The conversion can be written as displayed amount = raw amount / (10 ** decimals). This relationship only answers the display question when the decimals value belongs to the token being interpreted. Substituting an assumed value still produces a mathematical result, but it does not establish that the result is the appropriate representation for that token.
Interfaces have responsibility for applying this adjustment. That description of responsibility is not a finding that a particular wallet or other interface has used the correct metadata. When reviewing an explanation or example, look for both inputs: the raw amount and the stated scale. A number without that context leaves the conversion unexplained.
A hypothetical example, worked through
Suppose an invented token has 4 decimals and an invented account has 1234500 raw units. These are teaching assumptions, not information about a deployed token, an actual account or a completed transaction.
- Start with the stated decimals value:
4. - Calculate the scale:
10 ** 4 = 10000. - Divide the raw amount by that scale:
1234500 / 10000 = 123.45. - Describe the result as
123.45displayed tokens, while retaining1234500as the raw integer amount.
The result is a deduction from the display formula and the hypothetical inputs. It is not a quoted account balance. Writing both forms makes the relationship visible: the example describes one amount using a raw-unit count and a scaled representation.
The conversion also works in reverse. Algebraically rearranging the same formula gives raw amount = displayed amount * (10 ** decimals). In this example, multiplying 123.45 by 10000 returns 1234500. Because the underlying accounting uses integers, exact reverse conversion requires an integer result. This is a mathematical check on the representation, not an instruction to submit a transaction or evidence that an operation would succeed.
Why OpenZeppelin’s 18 is a default
The OpenZeppelin Contracts 5.x ERC20 reference documents a default decimals value of 18. It also explains that a derived contract can override the function to return another value. Both details matter when using the documentation to interpret a token.
The default belongs to that implementation. An override is a customization of the implementation; it should not be read as a promise that users can adjust the decimals of a deployed token. Likewise, a general ERC-20 label does not establish that the token uses OpenZeppelin’s unchanged default.
This leads to an explicit deduction: because EIP-20 makes decimals optional, and because OpenZeppelin’s 18 is an overridable implementation default, the ERC-20 label alone establishes neither the method’s availability nor a value of 18. Those premises explain why token-specific interpretation matters. They do not identify the metadata of any particular contract.
What the display conversion does not change
OpenZeppelin’s reference states that decimals is display information and does not affect its contract arithmetic, including balanceOf and transfer. In that documented implementation, using a divisor to interpret a raw balance does not itself update the balance. Performing the display calculation also does not execute a transfer.
Keep this limitation attached to the example. The hypothetical calculation changes how the amount is expressed for a reader; its raw-unit input remains the integer used in the calculation. The explanation concerns the documented scaling relationship, not an assessment of custom contract behavior.
This article does not assess token prices, authenticate a contract or establish transaction outcomes. For a separate explanation of transaction-cost terminology, see Ethereum gas fees versus the amount sent. That is a different reading task from converting token units.
A checklist for interpreting a token amount
- Identify the inputs. Record the raw integer amount and the decimals value being used.
- Establish the metadata basis. Determine whether decimals is provided for the particular token; do not fill an unresolved gap with 18 merely because it is OpenZeppelin’s default.
- Show the conversion. Divide the raw amount by
10 ** decimalsand label the result as the displayed amount. - Check the relationship. If reversing the conversion, multiply by the same scale and require an integer raw-unit result.
- Preserve the limits. A display calculation does not establish a balance update, a transfer result or contract authenticity.
If the token-specific decimals value remains unresolved, its scaled interpretation remains unresolved too. In an editorial workflow, that uncertainty requires editorial_review; a generic implementation default cannot serve as approval of the interpretation.
Educational material prepared with AI assistance. The invented example explains unit conversion and does not recommend a live transaction.