You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[CRITICAL] Persistent storage TTLs can expire before claims/refunds — user funds permanently locked #166
All four contracts store user-claimable state (bet entries, refund records, claim windows, referral earnings) in persistent storage entries with fixed TTLs that are never extended on the read path. If a market resolves or a payout window extends beyond the original TTL, the storage entry expires and the data is permanently lost — the user can no longer claim their refund or payout.
Impact
Permanent fund lock: expired BetEntry or RefundRecord storage means users lose access to their XLM.
No read-bump: view-only operations (e.g., checking claimable amounts) do not extend the TTL, so merely querying state accelerates expiry.
Keeper-dependent: only an external keeper can refresh TTLs before they expire; if the keeper is offline, funds are at risk.
Fix
Extend the TTL on every read path (Soroban's extend_ttl or equivalent) for entries that hold claimable state.
Set TTLs relative to the longest possible claim window, not the creation time.
Add a bump_ttl public function callable by anyone for entries close to expiry.
I'd like to work on resolving this issue. Here is my proposed plan of approach to prevent user funds from becoming locked due to expiring persistent storage TTLs:
Plan of Approach
Implement Read-Path TTL Bumping:
Update all four contracts (BetEntry, RefundRecord, claim windows, and referral earnings) to invoke Soroban's extend_ttl on every read/query path.
Ensure TTLs are dynamically extended upon interaction to prevent active entries from expiring during resolution or payout windows.
Align TTL Thresholds with Claim Lifecycles:
Adjust storage TTL initial values to be relative to the maximum possible claim window duration rather than a fixed creation-time value.
Expose Public bump_ttl Function:
Implement a permissionless bump_ttl entrypoint across contracts, allowing any user or keeper to refresh TTLs for storage entries approaching expiration.
Testing & Validation:
Add unit tests simulating market resolution extensions to verify storage entries remain accessible throughout the entire claim window.
Verify that read operations and public bump_ttl calls correctly extend storage lifetimes without corrupting state.
I can implement these TTL updates and test cases promptly.
Activity
GauravKarakoti commentedon Aug 23, 2026
Allow me to work on this one
samjay8 commentedon Aug 23, 2026
Hi team,
I'd like to work on resolving this issue. Here is my proposed plan of approach to prevent user funds from becoming locked due to expiring persistent storage TTLs:
Plan of Approach
Implement Read-Path TTL Bumping:
BetEntry,RefundRecord, claim windows, and referral earnings) to invoke Soroban'sextend_ttlon every read/query path.Align TTL Thresholds with Claim Lifecycles:
Expose Public
bump_ttlFunction:bump_ttlentrypoint across contracts, allowing any user or keeper to refresh TTLs for storage entries approaching expiration.Testing & Validation:
bump_ttlcalls correctly extend storage lifetimes without corrupting state.I can implement these TTL updates and test cases promptly.
grantfox-oss commentedon Aug 23, 2026
🦊 GrantFox — @samjay8 has been assigned to this issue as part of the Third Campaign campaign!
Next steps:
Closes #166)Good luck! Track your progress on GrantFox.
fix: extend persistent storage TTLs on read paths to prevent fund lock
grantfox-oss commentedon Aug 30, 2026
🎉 This issue has been marked as completed on GrantFox!
@samjay8's PR #191 was approved and merged by @Muyideen-js.
🏆 @samjay8: You earned 40 FoxPoints for this contribution! Your current tier: Builder (2,220 total points). Track your full progress on GrantFox.
👏 Great work, @samjay8! Keep contributing to SPulse-Org.
Merge branch 'main' into fix/issue-24-leaderboard-merge-corruption
chore: repair main so the workspace compiles and tests pass
Merge upstream/main: resolve conflicts from set_config Config-struct …