Motivation
When using lossy quantization with encode(), consumers often need to enforce input constraints upstream to prevent silent precision loss. Two patterns recur:
-
Reject values below step size to prevent encode() silently returning 0 (floor-to-zero). The library has no error for this case; consumers must define their own (e.g., ContributionBelowMinimum). This is the main gap: a BelowMinStep(uint256 value, uint256 stepSize) error would let consumers revert with a standardized library error instead of inventing domain-specific ones.
-
Reject non-aligned values to guarantee lossless per-entry storage. The library already has NotAligned and isAligned(), but no standalone guard function that performs the check-and-revert. Consumers currently write if (!scheme.isAligned(value)) revert NotAligned(value, scheme.stepSize()); manually. A requireAligned(Quant, uint256) convenience would reduce boilerplate.
Proposed API
/// @notice Thrown when a non-zero value is smaller than the scheme's step size.
error BelowMinStep(uint256 value, uint256 stepSize);
/// @notice Reverts with BelowMinStep if value > 0 and value < stepSize.
/// Zero is allowed (represents empty/uninitialized state).
function requireMinStep(Quant self, uint256 value) internal pure;
/// @notice Reverts with NotAligned if value is not a multiple of stepSize.
function requireAligned(Quant self, uint256 value) internal pure;
BelowMinStep is the genuinely missing error definition. requireAligned() is a convenience wrapper around the existing NotAligned error and isAligned() function.
Context
These patterns came up while integrating the library into octant-v2-core, where ProperQF packs per-project quadratic funding data into a single storage slot. We ended up defining ContributionBelowMinimum and WeightNotAligned as custom errors in the consumer contracts, but BelowMinStep is generic enough to live in the library.
Motivation
When using lossy quantization with
encode(), consumers often need to enforce input constraints upstream to prevent silent precision loss. Two patterns recur:Reject values below step size to prevent
encode()silently returning 0 (floor-to-zero). The library has no error for this case; consumers must define their own (e.g.,ContributionBelowMinimum). This is the main gap: aBelowMinStep(uint256 value, uint256 stepSize)error would let consumers revert with a standardized library error instead of inventing domain-specific ones.Reject non-aligned values to guarantee lossless per-entry storage. The library already has
NotAlignedandisAligned(), but no standalone guard function that performs the check-and-revert. Consumers currently writeif (!scheme.isAligned(value)) revert NotAligned(value, scheme.stepSize());manually. ArequireAligned(Quant, uint256)convenience would reduce boilerplate.Proposed API
BelowMinStepis the genuinely missing error definition.requireAligned()is a convenience wrapper around the existingNotAlignederror andisAligned()function.Context
These patterns came up while integrating the library into octant-v2-core, where
ProperQFpacks per-project quadratic funding data into a single storage slot. We ended up definingContributionBelowMinimumandWeightNotAlignedas custom errors in the consumer contracts, butBelowMinStepis generic enough to live in the library.