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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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