Skip to content

[CRITICAL] resolve_market lets resolver sweep entire pool to fees by resolving to empty side #177

Description

@grantfox-oss

Summary

prediction_market/src/lib.rs resolve_market has no validation that the winning side actually has bettors. A resolver can call resolve_market(market_id, true) (Yes wins) even when total_yes == 0 — all XLM in the pool (from the losing side) is then treated as "fees" and credited to AccumulatedFees.

Impact

  • Direct fund theft: the resolver redirects all user bets to the platform fee pool. Users who bet on the correct side get 0 payout; users who bet on the losing side lose everything.
  • No revert or warning: the market simply resolves and there is no mechanism for users to challenge it.
  • Single point of failure: the resolver role is typically a governance multisig, but a compromised or malicious resolver can execute this at any time.

Why it's hard

  • The resolver is trusted by design — the market needs an oracle to determine the outcome.
  • Adding a "challenge window" requires rethinking the entire settlement lifecycle.
  • Distinguishing "legitimate outcome" from "malicious sweep" is impossible on-chain without external price feeds.

Fix

  • Add a minimum bettor count / minimum pool size check before allowing resolution.
  • Require that the winning side has at least one bettor.
  • Emit a MarketResolved event with both sides' totals so off-chain monitors can flag suspicious resolutions.
  • Add a dispute window before fees are claimable.

Metadata

Metadata

Assignees

Labels

GrantFox OSSIssue tracked in GrantFox OSSThird CampaignCampaign: Third CampaigncriticalCritical severity - funds at riskprediction-marketPrediction market contractsecuritySecurity vulnerability

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions