Repository navigation
Invariant test: Σ locked_tokens + Σ claimed_tokens + Σ surplus == total_funded #223
Description
Problem Statement. The Soroban contract tracks KEY_TOTAL_LOCKED and KEY_TOTAL_CLAIMED
per token but never asserts the invariant that those totals plus the surplus equal the
total ever funded. A single off-by-one in decrement_locked() or finalize_claim() would
corrupt the ledger silently — and there is no on-chain total_funded storage key, so the
test must reconstruct that aggregate from the EscrowFunded event stream.
Why it matters. Mis-bookkeeping on a humanitarian escrow is what auditors will look at
first. Even a sub-stroop drift compounds through the lifetime of the contract.
Technical Context. app/onchain/contracts/aid_escrow/src/lib.rs keeps two Map<Address, i128> totals. get_total_locked and get_total_claimed are exposed to readers but never
asserted against one another, and the contract emits EscrowFunded { from, token, amount, timestamp } events from fund() and SurplusWithdrawnEvent / PackageRefunded events
elsewhere. Invariant #15 reconstructs total_funded by summing those events in a Soroban
test harness.
Expected Outcome. A proptest!-driven invariant test that exercises
fund → create → claim → fund → create → revoke / refund / withdraw_surplus triples and
asserts
Σ locked(tokens) + Σ claimed(tokens) == Σ EscrowFunded.amount(tokens)
− Σ SurplusWithdrawn.amount(tokens)
− Σ transfers-to-admin (refunded)
Acceptance Criteria.
- New file
app/onchain/contracts/aid_escrow/tests/invariants.rsaggregates events using
env.events().all()and replays them post-hoc, then runs 100 random sequences. - Failure produces a minimal shrunk example identifying which instruction broke it,
along with a printed event-stream snapshot. - The invariant is also asserted at bookkeeping calls (
decrement_locked,
finalize_claim,withdraw_surplus,refund) using unit-level smoke tests.
Implementation Notes. Use proptest as a dev-dependency. Seed proptest! with a
fixed seed in CI for reproducibility. Events are emitted via the contractevent macro —
use env.events().all() (or the equivalent in the chosen SDK) at assertion time.
Files or modules likely to be affected. app/onchain/contracts/aid_escrow/tests/invariants.rs.
Dependencies. None.
Difficulty. Medium
Estimated effort. M
Backlog item #15 from `docs/maintainer-issue-backlog.md.
Activity
Jumongweb commentedon Jul 15, 2026
Hi maintainer, i will like to solve this issue
Clement-coder commentedon Jul 20, 2026
Hi,
I’m a full-stack software and blockchain engineer with hands-on experience delivering production-ready solutions across frontend, backend, and blockchain systems.
I’d like to take ownership of this issue. I’ve reviewed the requirements and can implement a scalable, maintainable, and well-tested solution that fully satisfies the acceptance criteria.
Ready to start immediately and keep the team updated throughout the process.
YAustinXYZ commentedon Jul 21, 2026
Good morning, I wanna make this issue, i have experiencie working with this type of technologies.
dzekojohn4 commentedon Jul 21, 2026
I want to work on this
grantfox-oss commentedon Jul 21, 2026
🦊 GrantFox — @dzekojohn4 has been assigned to this issue as part of the Official Campaign | FWC26 campaign!
Next steps:
Closes #223)Good luck! Track your progress on GrantFox.
test(aid_escrow): add proptest invariant fuzz tests (ChainForgee#223)
test(aid_escrow): add proptest invariant fuzz tests (ChainForgee#223)
test(aid_escrow): add proptest invariant fuzz tests (ChainForgee#223)
test(aid_escrow): add invariant fuzz tests with proptest (ChainForgee…
grantfox-oss commentedon Jul 22, 2026
🎉 This issue has been marked as completed on GrantFox as part of the Official Campaign | FWC26 campaign!
@dzekojohn4's PR #407 was approved and merged by @kilodesodiq-arch.
🏆 @dzekojohn4: You earned 35 FoxPoints for this contribution! Your current tier: Explorer (624 total points). Track your full progress on GrantFox.
👏 Great work, @dzekojohn4! Keep contributing to ChainForgee.
test(aid_escrow): add proptest invariant fuzz tests (#223) (#407)
test(aid_escrow): add proptest invariant fuzz tests (ChainForgee#223) (…