Problem Statement
Every contract has positive tests but no explicit invariant tests that:
- After every public method returns successfully, exactly one event is emitted (or the documented count).
- Storage is in a consistent shape (e.g.,
course.active == true implies DataKey::Course(id) exists).
- No intermediate keys leak.
Without these, refactoring or feature additions can introduce silent storage-drift bugs.
Expected Outcome
A new contracts/invariant-tests/ crate (or per-crate modules) containing tests:
assert_event_count(env, expected: u32) macro.
assert_no_orphan_storage(env, contract_addr, allowed_keys) helper.
- Per-method tests confirming event cardinality.
Acceptance Criteria
- At least one invariant test per public method, per contract.
- Tests fail clearly if a method is added without an event or removes invariant storage.
Implementation Notes
- Walk
env.events().all().len() and compare to expected.
- This is "behavior-driven testing" — pair with golden storage introspection.
Files / Modules Affected
- New tests crate or per-crate
#![cfg(test)] mod invariants modules.
Dependencies
None.
Difficulty
Medium.
Estimated Effort
2–3 days.
Suggested Labels
testing, correctness, P2
Problem Statement
Every contract has positive tests but no explicit invariant tests that:
course.active == trueimpliesDataKey::Course(id)exists).Without these, refactoring or feature additions can introduce silent storage-drift bugs.
Expected Outcome
A new
contracts/invariant-tests/crate (or per-crate modules) containing tests:assert_event_count(env, expected: u32)macro.assert_no_orphan_storage(env, contract_addr, allowed_keys)helper.Acceptance Criteria
Implementation Notes
env.events().all().len()and compare to expected.Files / Modules Affected
#![cfg(test)] mod invariantsmodules.Dependencies
None.
Difficulty
Medium.
Estimated Effort
2–3 days.
Suggested Labels
testing,correctness,P2