Skip to content

Reference prices

Listings on LootFi are priced in ETH. Skins off LootFi are priced in dollars. The reference price exists to bridge that gap so a buyer can judge whether a listing is reasonable.

It is not a quote, not an offer, and not a valuation.

Where reference prices come from

Reference prices are third-party CS2 market data — what the underlying skin trades for on established skin marketplaces, keyed by the item's market_hash_name. They are:

  • Stored as integer USD cents. No floating-point money anywhere in the pipeline.
  • Refreshed periodically in the background, for the items LootFi actually holds tokens for.
  • Marked stale after a few hours. A stale price is shown and labelled stale, rather than hidden. A buyer is better served by "this figure is from a while ago" than by a blank space they will fill in with an assumption.

Data is per item name, not per token. Float, pattern, and stickers move a real skin's value substantially, and a name-keyed reference price captures none of that.

Two units, one comparison

This is the arithmetic hazard the whole page exists for:

  listing price     →  WEI          (native ETH, 18 decimals, on-chain, exact)
  reference price   →  USD CENTS    (integer, off-chain, third-party)

They are different units and different currencies. They can only be compared through an ETH/USD rate. There is no direct conversion and no "close enough" approximation that is safe on money.

The discount formula

listingUsd      = weiToUsdCents(priceWei, ethUsdCents)
discountPercent = (referenceUsd − listingUsd) / referenceUsd × 100

Positive means the listing is cheaper than the reference — a discount. Negative means it is more expensive.

The wide part of the arithmetic runs in bigint:

ts
const WEI_PER_ETH = 10n ** 18n;

export function weiToUsdCents(priceWei: bigint, ethUsdCents: number): number | null {
  if (priceWei < 0n) return null;
  if (!Number.isFinite(ethUsdCents) || ethUsdCents <= 0) return null;
  // Scale by 1000 before dividing so sub-cent listings don't floor to zero
  // and read as free.
  const scaled = (priceWei * BigInt(Math.round(ethUsdCents)) * 1000n) / WEI_PER_ETH;
  return Number(scaled) / 1000;
}

export function discountPercent(
  priceWei: bigint,
  ethUsdCents: number | null,
  referenceUsdCents: number | null,
): number | null {
  if (ethUsdCents === null || referenceUsdCents === null) return null;
  if (referenceUsdCents <= 0) return null;
  const listingUsdCents = weiToUsdCents(priceWei, ethUsdCents);
  if (listingUsdCents === null) return null;
  const pct = ((referenceUsdCents - listingUsdCents) / referenceUsdCents) * 100;
  if (!Number.isFinite(pct)) return null;
  return Math.round(pct * 10) / 10;   // one decimal — all the data supports
}

Two details in there are not incidental:

  • bigint for the multiply. A wei price times a rate exceeds JavaScript's safe integer range long before it exceeds a bigint. Doing this in number loses precision silently, which is not acceptable on money.
  • Scale before divide. Without the ×1000, a listing worth a fraction of a cent floors to zero and renders as free.

The result is rounded to one decimal place, because reference prices move by more than that between refreshes. Publishing more digits would imply a precision the underlying data does not have.

The system refuses to answer rather than guess

Every branch that cannot be computed honestly returns null, and null renders as no badge at all — not "0%", not "—", not a greyed-out figure.

ConditionResult
No ETH/USD rate availableNo discount shown
No reference price for the itemNo discount shown
Reference price is 0 or negativeNo discount shown
Listing price is negativeNo discount shown
The computation is not finiteNo discount shown

A source reporting 0 means "no price", not "free"

Market data sources routinely report 0 for items they do not actually price. Treating that as a real price would be catastrophic in a specific way: dividing by it makes every listing look like a 100% discount, and the badge would be loudest on exactly the items where the data is worst.

So a zero or absent reference is dropped at ingestion and again at computation. It never becomes a number on a page.

The rule throughout: a confidently wrong "23% below market" is far worse than an absent badge, because a wrong number invites somebody to buy on it. An absent badge invites them to look for themselves.

What a discount badge does and does not tell you

It tells you: this listing's ETH price, converted at a current rate, is below what an item of this name recently traded for elsewhere.

It does not tell you:

  • That the price is fair for this specific item. Float and pattern can move a real skin's value by multiples. The reference is name-keyed and blind to both.
  • That you could resell at the reference price. That figure is somebody else's listing or sale on a different platform with different fees and different liquidity.
  • That the reference is current. Check the stale marker.
  • Anything about LootFi's own liquidity. A cheap listing that nobody buys is still just a listing.

Reference prices are informational

Reference prices are third-party data shown for orientation only. They are not quotes, not offers, not an appraisal, and not a valuation of your token. LootFi does not buy at them, does not sell at them, and makes no representation that any item can be traded at any price shown. Settlement is always — and only — the price in the signed order, on chain, in wei.

Settlement is unaffected by any of this

The reference price decorates a listing. It never enters settlement.

fulfillOrder transfers exactly order.price in order.currency, as signed by the maker. No oracle, no rate, and no reference price is read on chain. If every price feed on the internet went dark, fills would continue to work identically.

That separation is the point: pricing information is a convenience layer with no authority over anyone's money.

For integrators

  • Listing prices in the API are wei, as decimal strings. Parse them as bigint.
  • Reference prices are integer USD cents.
  • Never combine them without an explicit rate, and never substitute a hardcoded rate for a missing one.
  • Treat a missing discount as missing. Do not render it as zero.
  • Buy — what to check before filling.
  • Fees — what a fill actually costs.
  • Marketplace — how settlement works.

LootFi is not affiliated with, endorsed by, or sponsored by Valve Corporation. Counter-Strike and Steam are trademarks of Valve Corporation.