Summary
The rewards contract has a fuzz target at contracts/rewards/fuzz/fuzz_targets/fuzz_balance.rs that randomizes credit/claim sequences. The campaign contract has no fuzz coverage, leaving participant registration, Merkle proof verification, cap enforcement, and time window logic untested by property-based randomization.
Problem
Campaign contract logic involves multiple interacting invariants:
- Registration is idempotent (double register returns false, count does not increase)
- Cap is never exceeded (participant_count ≤ max_cap when max_cap > 0)
- Time window is enforced (no registration outside [start, end])
- Merkle proof rejection (invalid proof must never register participant)
These invariants can be broken by edge cases that unit tests miss. Fuzzing catches them systematically.
Acceptance Criteria
References
contracts/rewards/fuzz/fuzz_targets/fuzz_balance.rs — existing fuzz target to mirror
contracts/campaign/src/lib.rs — target logic
.github/workflows/contracts-ci.yml
Summary
The rewards contract has a fuzz target at
contracts/rewards/fuzz/fuzz_targets/fuzz_balance.rsthat randomizes credit/claim sequences. The campaign contract has no fuzz coverage, leaving participant registration, Merkle proof verification, cap enforcement, and time window logic untested by property-based randomization.Problem
Campaign contract logic involves multiple interacting invariants:
These invariants can be broken by edge cases that unit tests miss. Fuzzing catches them systematically.
Acceptance Criteria
contracts/campaign/fuzz/directory structure mirroringcontracts/rewards/fuzz/fuzz_targets/fuzz_register.rsthat:participant_count <= max_capalwaysCargo.tomlandCargo.lockfor the fuzz workspacecontracts/campaign/README.mdor a newFUZZING.mdcontracts-ci.ymlas an optionalcargo fuzz buildstepReferences
contracts/rewards/fuzz/fuzz_targets/fuzz_balance.rs— existing fuzz target to mirrorcontracts/campaign/src/lib.rs— target logic.github/workflows/contracts-ci.yml