scripts/eth_swap_two_host.py and scripts/btc_swap_two_host.py dispatch exactly five phases each:
(taker, intro) (taker, fund) (taker, claim) (maker, envelope) (maker, lock-claim)
There is no refund and no abort phase in either. Consequences, traced:
- Taker funds the counter leg → maker stalls → nothing drives
mutual_refund.
- Maker locks the Radiant covenant → taker never claims → nothing drives the CSV refund, and the maker's
rxd_leg is built with a _NoFeeSource() unless --fee-* was passed, which raises SystemExit on any spend attempt.
So each role can reach funded-but-unrecoverable within the harness. The hostile-counterparty scenarios the harness's own docstring names as its reason to exist are precisely the ones it cannot execute.
This matters more than an ordinary gap because the two-party adversarial run is the project's stated hard gate before real value. A run conducted with these scripts exercises the happy path and the claim race; it cannot exercise either unwind, so it cannot evidence the recovery behaviour the safety argument depends on.
Related, same file
--asset-locked-at-height defaulted to 0 with no validation, so the reorg gate read SQUEEZED at any realistic tip and the finality wait was never observed. Fixed on feat/erc20-usdc-leg.
eth_swap_two_host built its CrossClockMargin without eth_finality_stall_tolerance_s (defaulting to 0) and exposed no flag for it, while eth_swap_run refuses < 3600 for a real-value token leg. Flag added on the same branch.
What would close this
--phase refund and --phase abort for both roles, driving mutual_refund and the CSV refund respectively, with the fee source wired so the spend can actually be built. Neither is exercised by any test today — see the fund-moving paths listed in the branch's review notes.
scripts/eth_swap_two_host.pyandscripts/btc_swap_two_host.pydispatch exactly five phases each:There is no refund and no abort phase in either. Consequences, traced:
mutual_refund.rxd_legis built with a_NoFeeSource()unless--fee-*was passed, which raisesSystemExiton any spend attempt.So each role can reach funded-but-unrecoverable within the harness. The hostile-counterparty scenarios the harness's own docstring names as its reason to exist are precisely the ones it cannot execute.
This matters more than an ordinary gap because the two-party adversarial run is the project's stated hard gate before real value. A run conducted with these scripts exercises the happy path and the claim race; it cannot exercise either unwind, so it cannot evidence the recovery behaviour the safety argument depends on.
Related, same file
--asset-locked-at-heightdefaulted to0with no validation, so the reorg gate read SQUEEZED at any realistic tip and the finality wait was never observed. Fixed onfeat/erc20-usdc-leg.eth_swap_two_hostbuilt itsCrossClockMarginwithouteth_finality_stall_tolerance_s(defaulting to 0) and exposed no flag for it, whileeth_swap_runrefuses < 3600 for a real-value token leg. Flag added on the same branch.What would close this
--phase refundand--phase abortfor both roles, drivingmutual_refundand the CSV refund respectively, with the fee source wired so the spend can actually be built. Neither is exercised by any test today — see the fund-moving paths listed in the branch's review notes.