Skip to content

implement Prize pool escrow + configurable top-N reward split#991

Merged
Olowodarey merged 1 commit into
Arena1X:mainfrom
AJtheManager:bac
Jun 18, 2026
Merged

implement Prize pool escrow + configurable top-N reward split#991
Olowodarey merged 1 commit into
Arena1X:mainfrom
AJtheManager:bac

Conversation

@AJtheManager

Copy link
Copy Markdown
Contributor

create_event previously only charged a flat creation_fee that went to the
global treasury — a platform anti-spam fee, not a prize pool. There was no way
for a creator to fund a prize pool or define how it is split among winners
(the unused token.rs helpers hinted this was planned but never wired up).

This PR lets a creator deposit an XLM prize pool when creating an event and
define what percentage of it each leaderboard rank receives (e.g.
[40, 30, 20, 5, 5] for the top 5). The prize pool is escrowed in the contract
address, separately from the creation-fee → treasury transfer.

Changes

src/storage_types.rs

  • New constants:
    • MAX_REWARD_RANKS: u32 = 5
    • REWARD_PERCENT_TOTAL: u32 = 100
  • Event struct gains:
    • prize_pool: i128
    • reward_distribution: Vec<u32> — percentages, 1-based rank order
    • is_finalized: bool
  • Event::new takes prize_pool and reward_distribution and always
    initializes is_finalized: false.

src/event.rs

  • New EventError variants:
    • InvalidPrizePool = 13prize_pool < 0
    • InvalidRewardDistribution = 14 — empty when funded, more than
      MAX_REWARD_RANKS entries, any entry == 0 or > 100, sum != 100 (when
      funded), or a non-empty distribution on an unfunded event
    • InsufficientPrizePoolFunds = 15 — creator cannot cover
      creation_fee + prize_pool
  • New validate_prize_pool() helper enforcing all of the above. A
    prize_pool == 0 "fun event" requires an empty reward_distribution and has
    no payouts.
  • create_event signature gains prize_pool: i128 and
    reward_distribution: Vec<u32>. Flow:
    1. Validate the reward distribution.
    2. Verify the creator can cover fee + prize_pool before any transfer, so
      we never move only the fee.
    3. Transfer the creation fee to the treasury (unchanged).
    4. If prize_pool > 0, escrow prize_pool from creator to
      env.current_contract_address() — a separate transfer from the
      creation-fee transfer.
    5. Persist prize_pool, reward_distribution, and is_finalized: false.
    6. Emit (Symbol("event"), Symbol("prize_pool_funded")) with
      (event_id, prize_pool, reward_distribution) when funded.

src/views.rs + src/lib.rs

  • New read-only views:
    • get_event_prize_pool(env, event_id) -> i128
    • get_event_reward_distribution(env, event_id) -> Vec<u32>
  • lib.rs wires these through (panicking event_not_found on a missing event)
    and maps the three new errors to invalid_prize_pool,
    invalid_reward_distribution, and insufficient_prize_pool_funds.

Acceptance criteria

  • Creator can specify prize_pool and reward_distribution at creation.
  • prize_pool XLM moves from creator to the contract address (verified via
    TokenClient::balance), separate from the creation fee.
  • All InvalidRewardDistribution cases are rejected with clear errors.
  • prize_pool == 0 requires an empty reward_distribution (fun events with
    no payout).

Tests (tests/event_tests.rs)

  • test_create_event_with_prize_pool_escrows_funds — contract XLM balance
    increases by prize_pool; creator's decreases by creation_fee + prize_pool.
  • test_create_event_reward_distribution_must_sum_to_100[50, 30, 10] → error.
  • test_create_event_too_many_reward_ranks — 6 entries → error.
  • test_create_event_zero_entry_in_distribution_rejected[100, 0] → error.
  • test_create_event_insufficient_balance_for_prize_pool → error.
  • test_create_event_zero_prize_pool_requires_empty_distribution → error.
  • test_get_event_prize_pool_and_distribution_views — views + stored fields.
  • test_get_event_prize_pool_zero_for_fun_event — fun-event view defaults.

The new create_event / Event::new signatures rippled across the suite; all
existing call sites were updated (fun events pass 0 / an empty Vec).

Verification

  • cargo test — all suites pass, 0 failures (including the 8 new tests).
  • cargo build --release --target wasm32-unknown-unknown — deploy artifact
    compiles cleanly.

Notes / Follow-ups

  • This is a breaking ABI change to create_event (two new positional
    args). Off-chain callers (frontend, backend indexer) must pass prize_pool
    and reward_distribution, and the indexer should handle the new
    prize_pool_funded event and prize_pool / reward_distribution fields.
  • Payout/distribution of the escrowed pool to winners (using is_finalized) is
    intentionally out of scope here and left for a follow-up.

closes #968

@vercel

vercel Bot commented Jun 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
insight-arena-4rll Ready Ready Preview, Comment Jun 18, 2026 7:33am

@Olowodarey

Copy link
Copy Markdown
Collaborator

@AJtheManager clean job thank you for taking this with urgency

@Olowodarey Olowodarey merged commit b03f863 into Arena1X:main Jun 18, 2026
4 checks passed
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.

[Contract]-Prize pool escrow + configurable top-N reward split

2 participants