Skip to content

test(pm): replay test — settlement zero-sum vs known exploit classes (t16) - #153

Merged
On1x merged 2 commits into
pmfrom
test/pm-settlement-exploit-classes
Aug 13, 2026
Merged

test(pm): replay test — settlement zero-sum vs known exploit classes (t16)#153
On1x merged 2 commits into
pmfrom
test/pm-settlement-exploit-classes

Conversation

@chiliec

@chiliec chiliec commented Aug 12, 2026

Copy link
Copy Markdown
Member

Summary

Adds a replay test that links the real settlement math (libraries/chain/pm/parimutuel.cpp) and asserts the documented zero-sum identity holds against adversarial inputs drawn from known DeFi/AMM/prediction-market exploit classes. No chain build required — it compiles just parimutuel.cpp + an fc-uint128 shim (see tests/pm/replay/README.md), so it runs in seconds and cannot OOM.

The invariant checked on every case:

Σ winner_payout + oracle_take + creator_take + lp_bonus
  == Σ winner.amount + losers_sum + forfeit_pool + uncovered

LP principal is returned 1:1 by the caller and cancels; uncovered (F1) sits on the input side as the shortfall the caller charges to LP principal — so the identity holds unconditionally and nothing is ever minted.

Exploit classes probed

  • A. Oracle resolves to a non-participated outcome (empty winners) → whole pool routes to lp_bonus, conserved. (self-oracle abuse)
  • B. Extreme negative forfeit_pool (heavy leverage-profit residual, tested down to −9×10¹⁵) → clamped to 0 and reported as uncovered, never the uint64 wrap/mint. (B3/F1 surface)
  • C. Dust winner weight vs a large pool → rounding remainder routes to LP, no mint/loss.
  • D. Max time_penalty → profit fully penalised to LP; payout == principal, never below.
  • E. distribute_lp: Σ shares == bonus for skewed principal/time mixes.
  • F. 300,000-case randomized fuzz over the reachable input space — 0 zero-sum violations.

Contract note

The test encodes the function's real contract: every on-chain winner has weight > 0 (pm_place_bet asserts tokens_out > 0), so the total_weight == 0 branch is reached only with an empty winners vector — which settle_market's caller iterates in lockstep with winner_bets, so there is no out-of-bounds on the empty winner_payout. (My first draft fed weight-0 "winners" and flagged false positives; characterizing this contract is what the exercise surfaced — the math itself is correct.)

Verification

Built and run green with g++:

ALL EXPLOIT-CLASS CHECKS PASS — settlement is zero-sum on every reachable input (0 failing assertions)

Registered in tests/pm/replay/build.sh linked list. Existing linked cases (t10/t14/t15) still build + pass — no regression.

chiliec and others added 2 commits August 12, 2026 18:33
…(t16)

Adds tests/pm/replay/t16_settlement_exploit_classes.cpp, which LINKS the real
libraries/chain/pm/parimutuel.cpp settlement math (no chain build required — see
tests/pm/replay/README.md) and asserts the documented zero-sum identity

  Σ winner_payout + oracle_take + creator_take + lp_bonus
    == Σ winner.amount + losers_sum + forfeit_pool + uncovered

across adversarial-but-REACHABLE inputs mapped to known DeFi/AMM exploit classes:

  A. oracle resolves to a non-participated outcome (empty winners) → whole pool to LP
  B. extreme negative forfeit_pool (heavy leverage-profit residual) → clamped to 0 and
     reported as `uncovered` (F1), never the uint64 wrap/mint (B3 surface)
  C. dust winner weight vs a large pool → rounding remainder routes to LP, no mint/loss
  D. max time_penalty → profit fully penalised to LP; payout == principal, never below
  E. distribute_lp: Σ shares == bonus for skewed principal/time mixes
  F. 300k-case randomized fuzz over the reachable input space

The test encodes the function's real contract: every on-chain winner has weight > 0
(pm_place_bet asserts tokens_out > 0), so the total_weight==0 branch is reached only with
an EMPTY winners vector — which the settle_market caller iterates in lockstep with
winner_bets, so there is no out-of-bounds. All checks pass, fuzz violations = 0.

Registered in tests/pm/replay/build.sh `linked` list. Built + run green with g++.
# Conflicts:
#	tests/pm/replay/build.sh
@On1x
On1x merged commit 29580c9 into pm Aug 13, 2026
2 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.

2 participants