Skip to content

feat: implement v2 bonded assertion posting and uncontested finalize - #80

Merged
collinsezedike merged 1 commit into
mainfrom
feat/v2-bonded-assertion
Aug 10, 2026
Merged

feat: implement v2 bonded assertion posting and uncontested finalize#80
collinsezedike merged 1 commit into
mainfrom
feat/v2-bonded-assertion

Conversation

@collinsezedike

Copy link
Copy Markdown
Collaborator

Summary

Implements #65: v2's assert_outcome equivalent (the optimistic first stage, before any dispute exists) and the uncontested-finalize path. Re-reading the issue body, the paragraph about finalize behavior turned out to be a real requirement, not just context: no later v2 issue (#66-#71) covers the uncontested case at all, so leaving it out here would mean nothing in the whole v2 chain ever returns an uncontested asserter's bond.

That also surfaced a real gap in #64: there was no field distinct from registration_duration_secs for "how long can a Pending assertion be disputed before it's eligible for finalize." Added:

  • PolicySnapshotV2.challenge_window_secs and finalize_reward_bps (carried over from v1 unchanged: same incentive problem, same solution, independently justified since it's the identical uncontested case in both versions).
  • AssertionV2.opened_at and finalizer.
  • assert_outcome(asserter, outcome) -> u64: requires asserter auth, writes state before the external token transfer (matching v1's reentrancy-safe ordering), transfers base_bond, emits Asserted.
  • finalize(caller, id) -> bool: requires caller auth unconditionally (same v1 hardening, so finalizer can never be spoofed regardless of reward), checks challenge_window_secs elapsed, splits the bond by finalize_reward_bps if configured, emits Finalized.
  • MAX_BOND_AMOUNT is now properly derived (i128::MAX / MAX_FINALIZE_REWARD_BPS) instead of [Feature] V2: implement PolicySnapshot and versioned assertion state #64's interim placeholder, since this issue introduces the real reward-multiply arithmetic that bound protects.

Closes #65

Test plan

  • cargo fmt --check, cargo clippy --workspace --all-targets --locked -- -D warnings, cargo test --workspace --locked all pass (67 v1 + 30 v2 + 2 integration-example tests)
  • cargo build -p tholos-v2 --target wasm32v1-none --release --locked succeeds
  • mdbook build succeeds
  • Every new Error variant has a dedicated test triggering it
  • Token balance assertions confirm the bond actually moves (asserter to contract on assert, contract to asserter/caller split correctly on finalize)

@collinsezedike
collinsezedike merged commit 7f37ece into main Aug 10, 2026
3 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.

[Feature] V2: implement bonded assertion posting

1 participant