Summary
dispute (contracts/tholos/src/lib.rs:618-655) requires disputer.require_auth() and checks the assertion is Pending and within the challenge window, but never checks disputer != assertion.asserter. An asserter can call dispute on their own pending assertion, consuming the assertion's one dispute slot and locking out any honest third party who might otherwise have disputed a bad-faith assertion. Because resolve's winner is selected purely from assertion.asserter/assertion.disputer, when disputer == asserter the winner is the same address regardless of the resolver committee's actual vote, guaranteeing both bonds back independent of the truth. This nullifies the bond-forfeiture deterrent that is the entire economic premise of the dispute mechanism.
Scope
- Add a check in
dispute rejecting a caller whose address matches assertion.asserter.
- Add a new
Error::SelfDispute variant.
Proposed approach
if disputer == assertion.asserter {
return Err(Error::SelfDispute);
}
Placed alongside the existing Pending/challenge-window checks in dispute. Add a test asserting this returns Err(Error::SelfDispute) and doesn't mutate assertion state.
Summary
dispute(contracts/tholos/src/lib.rs:618-655) requiresdisputer.require_auth()and checks the assertion isPendingand within the challenge window, but never checksdisputer != assertion.asserter. An asserter can calldisputeon their own pending assertion, consuming the assertion's one dispute slot and locking out any honest third party who might otherwise have disputed a bad-faith assertion. Becauseresolve's winner is selected purely fromassertion.asserter/assertion.disputer, whendisputer == asserterthe winner is the same address regardless of the resolver committee's actual vote, guaranteeing both bonds back independent of the truth. This nullifies the bond-forfeiture deterrent that is the entire economic premise of the dispute mechanism.Scope
disputerejecting a caller whose address matchesassertion.asserter.Error::SelfDisputevariant.Proposed approach
Placed alongside the existing
Pending/challenge-window checks indispute. Add a test asserting this returnsErr(Error::SelfDispute)and doesn't mutate assertion state.