Pre-release — The API surface may change. Unaudited.
Callcium LogoCallcium

Policy Validation

Type mismatches, contradictions, and redundancies.

Callcium validates policies at build time through semantic analysis. When you call PolicyBuilder.build(), the PolicyValidator inspects every constraint for type errors, logical contradictions, redundancies, and vacuous conditions — then reverts if any issue is found.

Using validation

PolicyBuilder.build() validates by default and reverts on any issue:

// Reverts with ValidationError if issues are found.
bytes memory policy = PolicyBuilder
    .create("approve(address,uint256)")
    .add(arg(0).isIn(trustedSpenders))
    .build();

To inspect issues without reverting, use PolicyBuilder.validate():

Issue[] memory issues = PolicyBuilder
    .create("approve(address,uint256)")
    .add(arg(0).isIn(trustedSpenders))
    .validate();

for (uint256 i = 0; i < issues.length; i++) {
    // Handle each issue: severity, category, code, message.
}

PolicyBuilder.buildUnsafe() skips validation entirely. The resulting policy may be invalid.

Issue structure

Each issue contains:

FieldTypeDescription
severityIssueSeverityError, Warning, or Info.
categoryIssueCategoryTypeMismatch, Contradiction, Redundancy, or Vacuity.
groupIndexuint32Constraint group where the issue was found.
constraintIndexuint32Constraint index within the group.
codebytes32Machine-readable identifier.
messagestringHuman-readable description.

Severity levels

PolicyBuilder.build() reverts on any issue regardless of severity. Use PolicyBuilder.validate() to inspect issues without reverting.

SeverityMeaning
ErrorThe policy is logically invalid (contradictions, type mismatches).
WarningThe policy is valid but contains redundant or suspicious constraints.
InfoThe constraint is technically correct but vacuous (always true).

Issue catalog

Type compatibility

Operators applied to incompatible types. All are Error severity.

CodeDescription
VALUE_OP_ON_DYNAMICValue operator used on a dynamic type.
NUMERIC_OP_ON_NON_NUMERICComparison operator used on a non-numeric type.
BITMASK_ON_INVALIDBitmask operator used on an incompatible type.
LENGTH_ON_STATICLength operator used on a non-dynamic type.
UNKNOWN_OPERATORUnrecognized operator code.

Contradictions

Make the constraint set unsatisfiable. All are Error severity.

Bound contradictions

These apply to both numeric values and lengths. Length variants have the LENGTH_ prefix.

CodeDescription
EQ_NEQ_CONTRADICTIONeq(v) and neq(v) on same path.
LENGTH_EQ_NEQ_CONTRADICTIONlengthEq(v) and lengthNeq(v) on same path.
CONFLICTING_EQUALITYMultiple eq() with different values.
CONFLICTING_LENGTHMultiple lengthEq() with different values.
OUT_OF_PHYSICAL_BOUNDSValue outside the type's physical range.
OUT_OF_PHYSICAL_LENGTH_BOUNDSLength value outside physical range.
IMPOSSIBLE_GTgt() on type maximum.
IMPOSSIBLE_LTlt() on type minimum.
IMPOSSIBLE_LENGTH_GTlengthGt() on maximum length.
IMPOSSIBLE_LENGTH_LTlengthLt(0) on minimum length.
BOUNDS_EXCLUDE_EQUALITYeq() value excluded by a bound.
BOUNDS_EXCLUDE_LENGTHlengthEq() value excluded by a bound.
IMPOSSIBLE_RANGELower bound exceeds upper bound.
IMPOSSIBLE_LENGTH_RANGELower length bound exceeds upper.

Set contradictions

CodeDescription
SET_EXCLUDES_EQUALITYSet operation excludes existing eq() value.
EMPTY_SET_INTERSECTIONMultiple isIn() sets have no intersection.
SET_FULLY_EXCLUDEDAll isIn() values excluded by neq/notIn.

Bitmask contradictions

CodeDescription
BITMASK_CONTRADICTIONConflicting bitmaskAll/bitmaskNone bits.
BITMASK_ANY_IMPOSSIBLEbitmaskAny bits all forbidden by bitmaskNone.

Structural errors

CodeDescription
UNSORTED_IN_SETisIn/notIn set is not strictly sorted and deduplicated.
EMPTY_GROUPGroup contains zero constraints.

Redundancies

Constraints with no effect because they are subsumed. All are Warning severity.

Bound redundancies

CodeDescription
DOMINATED_BOUNDNumeric bound dominated by a stricter bound.
DOMINATED_LENGTH_BOUNDLength bound dominated by a stricter bound.
REDUNDANT_BOUNDNumeric bound redundant because eq() is set.
REDUNDANT_LENGTH_BOUNDLength bound redundant because lengthEq() is set.

Set redundancies

CodeDescription
SET_REDUCTIONnotIn() value was present in isIn() set.
SET_REDUNDANCYisIn() sets partially overlap.
SET_PARTIALLY_EXCLUDEDSome isIn() values excluded by neq/notIn.

Bitmask redundancies

CodeDescription
REDUNDANT_BITMASKBitmask operation subsumed by existing mask.

Duplicates

CodeDescription
DUPLICATE_CONSTRAINTIdentical operator appears twice.

Vacuity

Constraints that are always true. All are Info severity.

CodeDescription
VACUOUS_GTEgte() on type minimum (always true).
VACUOUS_LTElte() on type maximum (always true).
VACUOUS_LENGTH_GTElengthGte(0) (always true).
VACUOUS_LENGTH_LTElengthLte() on maximum (always true).

On this page