You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
reclaim_stalled_dispute (contracts/tholos/src/lib.rs:831-886) pays assertion.bond to each of the asserter and disputer directly, with no check against how much the contract actually received when those bonds were originally deposited. This is the same class of gap #164 identified for finalize/resolve: a fee-on-transfer token can mean the contract actually holds less than 2 * assertion.bond for a given dispute.
#180 (fixing #164) adds an AssertionEscrow mechanism that finalize and resolve now use to cap payouts against what was actually escrowed for that specific assertion, rather than trusting the nominal bond value. reclaim_stalled_dispute isn't touched by that fix and still pays the raw nominal amount.
Impact: a stalled dispute funded with a fee-on-transfer token either traps on insufficient balance when someone calls reclaim_stalled_dispute (bricking the liveness fallback #166 exists to provide, for exactly the disputes most in need of it), or, if the contract's pooled balance from other open assertions happens to cover the shortfall, pays out more than this specific assertion actually escrowed, at other assertions' expense.
Add a test using a fee-on-transfer token that opens a dispute, lets it stall, and confirms reclaim_stalled_dispute either succeeds with the correct escrowed amounts or fails cleanly, rather than trapping or overpaying.
Proposed approach
Mirror whatever pattern #180 lands for finalize/resolve's escrow-capped payout in reclaim_stalled_dispute's two token_client.transfer calls.
Summary
reclaim_stalled_dispute(contracts/tholos/src/lib.rs:831-886) paysassertion.bondto each of the asserter and disputer directly, with no check against how much the contract actually received when those bonds were originally deposited. This is the same class of gap #164 identified forfinalize/resolve: a fee-on-transfer token can mean the contract actually holds less than2 * assertion.bondfor a given dispute.#180 (fixing #164) adds an
AssertionEscrowmechanism thatfinalizeandresolvenow use to cap payouts against what was actually escrowed for that specific assertion, rather than trusting the nominal bond value.reclaim_stalled_disputeisn't touched by that fix and still pays the raw nominal amount.Impact: a stalled dispute funded with a fee-on-transfer token either traps on insufficient balance when someone calls
reclaim_stalled_dispute(bricking the liveness fallback #166 exists to provide, for exactly the disputes most in need of it), or, if the contract's pooled balance from other open assertions happens to cover the shortfall, pays out more than this specific assertion actually escrowed, at other assertions' expense.Scope
AssertionEscrowexists, updatereclaim_stalled_disputeto cap its two payouts against that same tracking, the same wayfinalize/resolvenow do, instead of paying the rawassertion.bondvalue to each side.reclaim_stalled_disputeeither succeeds with the correct escrowed amounts or fails cleanly, rather than trapping or overpaying.Proposed approach
Mirror whatever pattern #180 lands for
finalize/resolve's escrow-capped payout inreclaim_stalled_dispute's twotoken_client.transfercalls.