Skip to content

Research notes

Chainlink Feed Decimals vs Token Decimals

A constructed six-decimal holding and eight-decimal price feed produce $640.01. Trace each scale, premature division and the quote-currency label.

Two ivory ceramic measuring wheels with different divisions joined by a lime connector on black.
Illustration for research notes; examples in this article are educational.

Chainlink feed decimals scale the reported answer; token decimals scale the raw token balance. To value a holding, convert each with its own scale, then multiply the token quantity by the price in the stated quote currency. Choose the result's precision separately and make rounding explicit. A correct decimal adjustment does not verify the feed's asset identity, freshness or suitability for valuation.

Two scales and a currency label

A token balance and an oracle answer measure different things. The balance says how much of an asset is held. A price feed says how much of a specified quote currency corresponds to one unit of its base asset. Their decimal counts can differ without either being wrong.

The ERC-20 specification defines balanceOf as an integer balance and makes decimals optional metadata for its user representation. With six token decimals, one displayed token corresponds to 1,000,000 raw units. If the metadata is unavailable, the balance alone does not establish its scale. The ERC-20 raw-amount guide covers that quantity boundary in detail.

The feed has its own contract and its own decimals() response. Chainlink's Price Feeds documentation says to divide the answer by ten raised to that decimal count. It also warns against hardcoding precision from conventions such as USD or ETH pairs. On EVM networks, read the selected feed proxy's precision.

Neither count identifies a currency. An eight-decimal answer might describe USD per token, while another feed describes a different unit. Record the base asset, quote currency and direction alongside the integer. The label “price” is incomplete without those units.

Also distinguish precision from accuracy. Eight stored decimal places describe an answer's scale. They do not establish eight decimal places of economic certainty or the price at which a holding can be sold.

Reconcile one constructed holding

This illustrative example uses fictional token X with ordinary integer balance accounting and a fictional X/USD price observation. It is not a live feed response, a market quote or an investment recommendation. Assume the asset mapping and observation validity have already been checked so the arithmetic can be examined separately.

InputRecorded valueInterpretation
Raw X balance347125809Integer token units
Token decimals61,000,000 raw units per X
Raw feed answer184375000Scaled USD-per-X answer
Feed decimals8100,000,000 answer units per USD/X
Desired result precision2USD cents, chosen by this worksheet

The quantity is 347125809 divided by 1,000,000, or 347.125809 X. The price is 184375000 divided by 100,000,000, or 1.84375000 USD per X.

Multiplying gives 640.01321034375 USD. The X in the quantity cancels the X in the rate's denominator. This unit cancellation explains why the result is USD; the fact that the feed has eight decimals does not explain its currency.

The same calculation can retain exact integers until the last step. Multiplying the two raw inputs gives 64001321034375000. The combined scale is ten raised to fourteen, because the token contributes six decimal places and the feed contributes eight. Dividing that product by 100000000000000 recovers exactly 640.01321034375 USD.

If an otherwise equivalent token represented the same holding with eighteen decimals, its raw balance would be 347125809000000000000. Using eighteen for that token and eight for the same price answer gives the same value. A larger raw balance caused by a finer token unit does not create more economic value.

Decide what the output integer means

Suppose the application stores valuation in cents. Multiply the exact raw product by 100 before dividing by the combined scale. For this positive example, rounding down gives the output integer 64001, representing $640.01.

The quotient leaves a remainder of 32103437500000 against the combined denominator. That is 0.321034375 cents, or $0.00321034375, discarded by rounding. Retaining that remainder makes the rounding decision reproducible.

More generally, let B be the raw balance, A the positive price answer, t the token decimals, f the feed decimals and o the chosen output decimals. Form the numerator B × A × ten raised to o. Divide it by ten raised to the sum of t and f, applying the selected rounding policy at that division. The result is an integer in quote units scaled by ten raised to o.

For six output decimals, this fixture instead produces 640013210, representing 640.013210 USD after rounding down. Those six places are an application convention. USD is the quote currency; this calculation has not produced a balance of any six-decimal USD stablecoin.

Keep B and A exact through multiplication. The product in this example exceeds JavaScript's safe integer range, even though both individual inputs fit. Use exact integer or decimal arithmetic throughout the calculation. In a fixed-width environment, check intermediate multiplication and exponent ranges too; a small final quotient does not prove its intermediate product fits.

Rounding down is the policy of this illustration. A display might use rounding to nearest, while a particular accounting rule requires another direction. State the rule and the unit it affects before comparing results.

Diagnose the wrong value by its scale

The following comparisons use the same illustrative inputs and round each final result down to cents. They show several different errors that can survive a successful contract read.

CalculationReported USD valueWhat went wrong
Keep both scales through multiplication$640.01Correct under the stated rounding rule
Divide the feed by the token's six-decimal scale$64,001.32Price is 100 times too large before rounding
Omit the token scale$640,013,210.34Raw token units were treated as whole X
Integer-divide the balance before multiplying$639.78Fractional X was discarded first
Integer-divide the price before multiplying$347.12Price was reduced to 1 USD/X first

The last two rows are especially easy to miss because their outputs look plausible. Dividing the raw balance by its token scale using integer arithmetic first leaves only 347 X. Dividing the answer by its feed scale first leaves only 1 USD/X. Both discard information that belongs in the multiplication.

Two mistakes can also offset. If a parser understates quantity while overstating price, the total might happen to look reasonable. Check quantity and rate independently before checking their product. An expected-looking portfolio value is weak evidence that the units are correct.

A useful regression fixture therefore checks intermediate interpretations as well as the final cents. For this case, require exactly 347.125809 X, exactly 1.84375 USD/X and the final 64001 cents. That identifies which boundary failed.

Validate a price answer as a price answer

Chainlink's Data Feeds API reference defines the EVM latestRoundData() answer as a signed int256. It also explains that the data can represent asset prices, reserves or other feed-specific values. A shared interface does not give every answer the same meaning.

For this worksheet's selected positive-price valuation, reject an answer at or below zero before converting it to an unsigned integer or multiplying it into positive holdings. This is a requirement of the chosen price model. It is not a universal validation rule for every Chainlink feed.

For example, Chainlink's L2 Sequencer Uptime Feeds use zero to mean the sequencer is up and one to mean it is down. Feeding that status into a token valuation would be a schema error, regardless of its decimal count.

A positive answer still needs identity, timestamp and application checks. The startedAt versus updatedAt guide examines the separate timestamp roles. Do not substitute a good scale for a freshness decision. Chainlink assigns application developers responsibility for the data-quality checks, circuit breakers and contingency logic their use case requires. Chainlink developer responsibilities.

The current API reference marks answeredInRound deprecated and says minAnswer and maxAnswer are no longer used on most feeds. Copying those older checks into a worksheet does not establish current application protection; inspect the selected implementation and define the required response to invalid input.

Preserve the quote currency through the next step

Now change only the fictional feed's unit from USD/X to Q/X, where Q is another asset. Keeping the same integer and decimals would produce 640.01321034375 Q. Writing a dollar sign beside that result would add an unsupported conversion assumption.

If Q itself is an ERC-20 token, its token decimals describe Q balances. They do not convert Q into USD. A Q/USD rate is separate evidence, with its own direction, precision and observation time. Chainlink's denomination example illustrates deriving a different quoted pair from separately scaled feeds.

Likewise, a feed measured in X per USD is the inverse direction of USD per X. Multiplying an X holding directly by an X-per-USD rate would leave the wrong units. Write the units first; then choose multiplication, division or an additional conversion.

Valuation can precede other rules without absorbing them. The collateral-haircut worksheet separates market value, quote conversion and recognized support. Correct oracle scaling supplies an input to that process. It does not establish collateral eligibility, borrowing capacity or executable sale proceeds.

Keep a record another reader can reconstruct

Use one valuation record that binds the holding to its selected feed and output convention. For an EVM observation, retain the block reference used for the reads so a later review does not silently combine different states.

RecordValidation question
Chain and token addressWhich asset does the raw holding measure?
Token scale and provenanceWas it read or explicitly resolved when metadata was absent?
Feed proxy and base/quote unitsDoes this rate value that asset in the intended direction?
Feed decimals and signed answerHas the answer been interpreted with its own scale and semantics?
Block and round evidenceWhich observation produced the recorded answer?
Timestamps and acceptance rulesIs this observation usable for the application?
Output scale and roundingWhat does one output integer unit represent?
Product, quotient and remainderCan the numerical result be reproduced exactly?

Retain the returned round identifier with the feed identity. The proxy-phase versus round-ID guide explains why historical round references need the proxy context; a round number alone is an incomplete record.

Exercise the record with one whole token, one raw token unit, a zero balance and deliberately different feed and token decimals. Under this fixture, one whole X is worth 1.84375 USD and one raw X unit is worth 0.00000184375 USD. A cents output rounds the latter to zero; the holding itself remains positive. Also check missing token metadata, a failed feed read and a nonpositive price answer as distinct cases.

Before accepting the valuation, reconstruct the token quantity, reconstruct the rate with its units, and reproduce the output rounding. Save all three beside the raw inputs so the next reader can tell a scale error from a currency conversion or an invalid observation.

Keep the context with the example.

Each worked example is illustrative, with its sources and assumptions in the article. Read our editorial standards for authorship, verification and corrections.