Skip to content

Add requireAligned() and requireMinStep() convenience guards #93

@0xferit

Description

@0xferit

Motivation

When using lossy quantization with encode(), consumers often need to enforce input constraints upstream to prevent silent precision loss. Two patterns recur:

  1. 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.

  2. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions