Thinking through a quantization scheme
Say you are building a staking contract and need to store ETH balances. ETH has 18 decimals, so 1 ETH = 1018 wei. Where do you start?
- What is the largest value I will ever store? The total ETH supply is ~120M ETH = 1.2 × 1026 wei. No single balance can exceed that, so it is a safe domain max. If the field is an accumulator (e.g., total staked across all users), estimate the worst-case accumulated total instead.
- How many bits does that need? log2(1.2 × 1026) ≈ 86.6, so 87 bits minimum. Next byte boundary:
uint88.
- How much resolution can I sacrifice? Do you need wei-level resolution? Probably not for staking. If you accept rounding to the nearest 65,536 wei (216), that is roughly 0.000000000000065 ETH: invisible to any user. So discarding 16 bits is safe.
- What is the result? With
uint88 and 16 discarded bits: 88 − 16 = 72 encoded bits, stored as uint72. The call is create(16, 72).
- What do I lose? Max error per value is 216 − 1 = 65,535 wei ≈ 0.000000000000065 ETH. Values within 65,535 of
uint88.max will revert with Overflow. Both are negligible for ETH staking. If you want zero error, enforce step-aligned inputs: the library provides requireAligned() and encode(value, true) which revert on non-aligned values, guaranteeing lossless round-trips.
Enter your domain max below to run this reasoning for your own field.