Skip to content

fix(prediction-market): protect claimable state from TTL expiry - #113

Open
afeezorobsco-cyber wants to merge 4 commits into
SPulse-Org:mainfrom
afeezorobsco-cyber:fix/prediction-market-claim-ttl
Open

fix(prediction-market): protect claimable state from TTL expiry#113
afeezorobsco-cyber wants to merge 4 commits into
SPulse-Org:mainfrom
afeezorobsco-cyber:fix/prediction-market-claim-ttl

Conversation

@afeezorobsco-cyber

Copy link
Copy Markdown

##close #92

Summary

Protects persistent market and bet state required for post-resolution claims and refunds from expiring prematurely.

Changes

  • Audited persistent storage used by market claim/refund flows.
  • Added TTL lifecycle handling for claimable market/bet state.
  • Extended TTL on relevant lifecycle operations using existing repository conventions.
  • Kept missing/expired state semantics unchanged.
  • Preserved intentional terminal cleanup behavior.
  • Added regression tests for TTL extension and claim/refund recovery paths.
  • Documented the storage TTL lifecycle and its limitations.

Security / Fund Safety

Claim and refund state must remain available while users can legitimately recover funds. The implementation ensures the relevant persistent entries are refreshed together rather than protecting only the top-level market record.

Already-expired Soroban persistent entries cannot be resurrected; the implementation does not attempt to fabricate missing financial state.

Validation

  • cargo fmt --all -- --check
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo test --workspace

Issue

Closes #[ISSUE_NUMBER]

Cap lives in pulse_token::mint() (DataKey::MaxSupply, instance storage) so every
authorized minter - leaderboard reward/reward_bonus or any future minter -
shares one global ceiling. Result is computed via i128::checked_add before any
write; over-cap or overflow mints reject with MaxSupplyExceeded (SPulse-Org#7) leaving
balance and total_supply untouched. No authoritative tokenomics value exists in
the repo, so the cap is deployer-supplied via initialize(_, max_supply); legacy
instances fail closed until admin declares a cap through set_max_supply, an
admin-only one-way ratchet (cannot raise, cannot go below current supply).

Closes issue SPulse-Org#34.
Market, Bet, Payout, and bettor-index entries in persistent storage could
expire before claim/refund, permanently locking user funds (issue SPulse-Org#9).
Add read-time TTL refresh: claim now also bumps the winner's Payout key,
resolve_market bumps the bettor index/Bets/Payouts it walks, and the
user-facing views (get_market/get_bet/get_payout/get_market_bettors_page)
re-arm the entries they read. Every bump reuses the existing TTL_BUMP/TTL_HIGH
constants; missing/expired state keeps its not-found semantics. Already-expired
entries cannot be resurrected by design.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[CRITICAL] Persistent storage TTLs can expire before claims/refunds — user funds permanently locked

1 participant