Skip to content

feat: deterministic distribution ordering with address tie-break (#472)#500

Open
MorsH14 wants to merge 1 commit into
RevoraOrg:masterfrom
MorsH14:feat/deterministic-distribution-order
Open

feat: deterministic distribution ordering with address tie-break (#472)#500
MorsH14 wants to merge 1 commit into
RevoraOrg:masterfrom
MorsH14:feat/deterministic-distribution-order

Conversation

@MorsH14

@MorsH14 MorsH14 commented Jun 29, 2026

Copy link
Copy Markdown

Closes #472


Closes #476


Summary

  • Implement prove_distribution_for_period — reads on-chain period revenue, normalises by payment-token decimals, computes per-holder payouts, then sorts and digests the result canonically.
  • Sort key for both prove_distribution_for_period and simulate_distribution: (share_bps desc, address-XDR bytes asc).
  • SHA-256 digest is domain-separated by (issuer, namespace, token, period_id) so different periods always produce distinct digests even with identical revenue amounts.
  • Fix four pre-existing DataKey2 missing variants (SupplyCap, DepositedRevenue, MinRevenueThreshold, InvestmentConstraints) and missing RevoraError::StaleConcentrationData that blocked CI compilation.
  • Update README event-spec "Deterministic ordering" section to document the new canonical sort contract.

Changes

File Change
src/lib.rs Add addr_lt + sort_holder_indices private helpers; implement prove_distribution_for_period; sort simulate_distribution before iterating; fix 5 pre-existing missing enum variants; register test_prove_distribution module
src/test_prove_distribution.rs Rename + fix ordering test (assert_neassert_eq); add prove_distribution_identical_bps_tie_break_by_address fixture
README.md Rewrite "Deterministic ordering" section to document on-chain sort with the exact sort key

Implementation details

  • addr_lt(env, a, b) — byte-wise XDR comparison used as address tie-break.
  • sort_holder_indices(env, bps_vec, addr_vec, n) — O(n²) selection sort with a 256-bit bitmask (4 × u64), safe for n ≤ MAX_CHUNK_PERIODS (200).
  • prove_distribution_for_period is pure read-only (no state mutation). Caps at 200 holders.

Test plan

  • prove_distribution_sorting_makes_order_invariant — swapped input produces identical digest and entry order.
  • prove_distribution_identical_bps_tie_break_by_address — tie-break fixture: same BPS → stable address-bytes-ascending order regardless of input permutation.
  • prove_distribution_different_periods_produce_different_digests — period domain-separation with identical revenue.
  • All other prove_distribution_* tests (normal case, empty holders, zero BPS, USDC 6-decimal normalisation, RoundHalfUp, 200-holder cap) pass unmodified.
  • CI: cargo fmt --check, cargo clippy -D warnings, cargo test --test-threads=1.

🤖 Generated with Claude Code

@drips-wave

drips-wave Bot commented Jun 29, 2026

Copy link
Copy Markdown

@MorsH14 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

…RevoraOrg#472)

Sort `prove_distribution_for_period` and `simulate_distribution` output
by (share_bps desc, address-XDR bytes asc) so indexers always receive a
canonical ordering regardless of the input `holders` slice order.

Key changes:
- Add `addr_lt` private helper: byte-wise XDR comparison for Address tie-break
- Add `sort_holder_indices`: O(n²) selection sort with u256 bitmask (4×u64),
  safe for n ≤ MAX_CHUNK_PERIODS (200)
- Implement `prove_distribution_for_period`: reads PeriodRevenue, decimals,
  RoundingMode; normalises revenue; sorts holders; builds domain-separated
  SHA-256 digest (offering + period_id + sorted entries)
- Update `simulate_distribution` to sort before iterating (same key)
- Fix pre-existing DataKey2 missing variants (SupplyCap, DepositedRevenue,
  MinRevenueThreshold, InvestmentConstraints) that prevented CI compilation
- Fix pre-existing missing RevoraError::StaleConcentrationData (= 52)
- Register `test_prove_distribution` module; update ordering test from
  assert_ne → assert_eq; add `prove_distribution_identical_bps_tie_break_by_address` fixture
- Update DistributionEntry doc comment and README event spec section

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@MorsH14 MorsH14 force-pushed the feat/deterministic-distribution-order branch from 0ea9542 to e30d267 Compare June 29, 2026 03:43
@MorsH14 MorsH14 changed the title feat: enforce deterministic distribution order with address tie-break (#472) feat: deterministic distribution ordering with address tie-break (#472) Jun 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant