Our synthetic liquidity gate requires an initial deposit of three whole tokens. For an asset using six decimal places that means 3000000 raw units. Applying an eighteen decimal constant to the same asset turns the three token rule into a completely different economic threshold.
The independent fixture uses BigInt and several invented token definitions. It models a minimum quantity check and does not implement an AMM. That narrow scope lets us inspect the unit conversion before considering pool shares or swap mathematics.
Raw quantities carry no display scale
ERC20 balance methods return integers. The decimal count describes how a user interface interprets those integers as a token quantity. Two contracts can return the same raw balance while representing very different displayed amounts.
In Solidity a literal using the ether suffix supplies a power of ten conversion. It does not inspect the token involved in the calculation. Using that literal for an arbitrary ERC20 minimum therefore embeds an eighteen decimal assumption even when the variable name says token amount.
function unit(decimals) {
if (!Number.isInteger(decimals) || decimals < 0 || decimals > 30)
throw new Error("unsupported unit");
return 10n ** BigInt(decimals);
}
function acceptsInitial(rawAmount, decimals) {
return rawAmount >= 3n * unit(decimals);
}Our fixture computes the minimum using a configured decimal count and a whole token policy value. The accepted decimal range is a deliberate bound in this example. It prevents unreasonable exponentiation and is not a statement that the ERC20 standard restricts every asset to that same range.
Metadata needs a failure policy
The ERC20 interface describes decimal metadata as optional. A contract or adapter cannot assume every token returns it successfully. An integration can require metadata during asset registration or accept an administrator supplied unit under a defined trust model.
Reading metadata once does not make the asset permanently safe. Upgradeable contracts can change behavior and an integration needs a policy for the assets it accepts. For an immutable asset configuration the chosen unit becomes part of the system's assumptions and deserves a test alongside its address.
We keep the economic threshold separate from the raw conversion so the policy remains three whole tokens across supported assets and a reviewer can change the decimal count without accidentally changing the intended minimum or introducing a second scale factor in a later liquidity share calculation that expects raw token units.
A failed metadata call should not silently select eighteen decimals. That fallback hides a missing measurement behind a familiar default and makes the same configuration appear to work for one asset while failing for another.
Initial liquidity and later liquidity have different inputs
The initial deposit establishes a ratio when the pool has no previous reserve ratio. Later deposits usually relate to existing reserves and outstanding shares. A minimum initial quantity is a policy check and does not prove that the chosen initial price is sensible.
If the two assets have different decimals then a raw reserve ratio is not their displayed price ratio. Quoting a price requires both decimal scales and a stated numerator asset. A reserve ratio of one in raw integers is a one to one displayed price only when those scales match.
Three-token thresholds checked at 0, 6 and 18 decimals
10 assertions passedThe fixture accepts the exact threshold and rejects one raw unit below it for decimal counts of zero and six and eighteen. It also demonstrates that an eighteen decimal threshold rejects a valid six decimal deposit. That negative control proves that the tests actually distinguish the unit mistake.
Multiply and divide in a declared order
For share calculations integer truncation depends on operation order. Dividing before multiplying can discard a small fractional ownership amount entirely. Multiplying first preserves more information but the intermediate quantity must fit the arithmetic type or use a multiplication and division routine designed for that range.
Solidity 0.8 overflow checks turn an oversized intermediate into a revert. They do not prove that an expression uses the correct units. We treat arithmetic safety and dimensional correctness as separate review questions and exercise both in the contract test suite.
A second participant joining a synthetic pool at the same displayed price provides the next unit check. Their issued share fraction should match their economic contribution even when the two assets use raw quantities separated by many powers of ten.