Skip to content

[Feature] V2: implement settlement and forfeiture distribution #69

Description

@collinsezedike

Summary

Implement position settlement: converting a locked outcome (#68) into per-position entitlements, permissionlessly and in O(1) per call, with no loop over all positions.

What to build

Settlement rules depend on terminal_cause:

Strict-majority result:

  • Positions on the winning side recover their principal.
  • Positions on the losing side, and positions that never revealed, are forfeited entirely.
  • The forfeited pool is distributed among winning positions in proportion to their weight: reward_i = floor((s_i * forfeited_pool) / recipient_weight), payout_i = s_i + reward_i, where recipient_weight is the final winning-side weight.

Optimistic timeout default:

  • Every revealed position, on either side, recovers its principal.
  • Only non-revealed positions are forfeited.
  • That forfeited pool is distributed pro rata among all revealed positions (both sides), using the same reward_i formula, with recipient_weight = total revealed weight.

Mechanics required in both cases:

  • settle(id: u64, address: Address) is permissionless (any caller may settle any known position) and must be callable in any order without changing results: every position's payout uses the same forfeited_pool and recipient_weight captured at outcome-lock time, so settlement order never matters.
  • Settlement does not itself move tokens. It marks the position settled and accrues payout_i to a Credit(id, address) record. See the withdrawal issue for the separate step that actually transfers tokens.
  • Once recipient_weight reaches zero (all recipient positions settled), any remaining indivisible dust from integer division accrues to a deterministic party: the winning asserter or disputer after a strict-majority result, or the asserter after a timeout default. If forfeited_pool == 0, skip the dust step entirely.
  • All arithmetic must be checked/overflow-safe and must conserve the pool exactly: funded_total == withdrawn_total + accrued_credit + unsettled_entitlements must hold after every settlement.

Depends on

#68 (needs a locked terminal_cause and final_outcome to settle against).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesthardSecurity-sensitive or high-complexity change

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions