Problem Statement
Soroban storage entries have a TTL measured in ledgers. The DataKey::Progress(Address, u32) and DataKey::UserBadges(Address) entries are read repeatedly throughout the lifecycle of the protocol. There is no env.storage().persistent().bump_* call anywhere in the codebase — meaning storage will eventually expire and silently disappear, causing learner badges/progress to vanish.
Why It Matters
- Storage TTL is invisible to most developers because expiration is ledger-counted, not time-counted.
- A learner completing a course and receiving their badge could find their badge gone weeks later if no one interacts with their storage entry.
- Already-emitted events are immutable, but the storage state behind them can be lost.
Technical Context
- Soroban default
MAX_LIVE_UNTIL is approximately 30 days; BUMP_THRESHOLD and other constants exist in the host.
- Conservation: any function that reads a key should bump its TTL.
- Conservation: any function that writes should also extend TTL.
Expected Outcome
Acceptance Criteria
- New audit test: simulate 100,000 ledgers passing with no interactions and assert all badges/progress/courses still readable.
- TTL bumps confirmed via a CI test instrumented for
env.storage().persistent() access patterns.
Implementation Notes
- Determine an optimal "minimum bump window" (e.g., 1 million ledgers ≈ 1 week).
- Be mindful of TTL-bump costs — Soroban charges fees per bump.
Files / Modules Affected
All six contracts.
Dependencies
Issue #7 (common crate) precedes.
Difficulty
Medium-Hard.
Estimated Effort
2–3 days.
Suggested Labels
reliability, performance, P1, storage
Problem Statement
Soroban storage entries have a TTL measured in ledgers. The
DataKey::Progress(Address, u32)andDataKey::UserBadges(Address)entries are read repeatedly throughout the lifecycle of the protocol. There is noenv.storage().persistent().bump_*call anywhere in the codebase — meaning storage will eventually expire and silently disappear, causing learner badges/progress to vanish.Why It Matters
Technical Context
MAX_LIVE_UNTILis approximately 30 days;BUMP_THRESHOLDand other constants exist in the host.Expected Outcome
bump_persistent_ttl(env, key)helper incontracts/common(ties to Issue [7]create_contracts_commonshared crate — eliminate duplicated types and patterns #7).Acceptance Criteria
env.storage().persistent()access patterns.Implementation Notes
Files / Modules Affected
All six contracts.
Dependencies
Issue #7 (common crate) precedes.
Difficulty
Medium-Hard.
Estimated Effort
2–3 days.
Suggested Labels
reliability,performance,P1,storage