Round 5, fresh-eyes brief. MEDIUM.
assert_not_frozen_before_reveal has exactly one call site in the whole tree: Erc20HtlcLeg.claim (erc20_leg.py:206). It is never called from verify_funded or EthLeg.verify_counterparty_funded — the gate the coordinator runs before telling the maker to lock RXD.
A maker can therefore verify-and-lock RXD against an HTLC or claimant that is already frozen. The secret stays safe (claim raises PreRevealAbort), but the RXD is committed into the covenant for the full t_rxd CSV window before the maker learns the swap can never complete — for a condition that one already-implemented, already-tested read would have caught for free.
docs/solutions/design-decisions/usdc-corridor-is-issuer-trusted-not-trustless.md documents the reveal-time check-then-reveal race as an accepted residual, but says nothing about this earlier, cheaply avoidable case. It reads as an oversight rather than a deliberate trade.
Fix
Check contract + refundee before funding, and contract + claimant before claiming. (Round 5 narrowed the pre-claim gate to the claimant — the refundee cannot affect a claim — so the pre-fund gate is now the only place a frozen refundee would be caught at all.)
Note this is the reachability class again: the capability exists, is tested, and is not called where it would do the most good.
Round 5, fresh-eyes brief. MEDIUM.
assert_not_frozen_before_revealhas exactly one call site in the whole tree:Erc20HtlcLeg.claim(erc20_leg.py:206). It is never called fromverify_fundedorEthLeg.verify_counterparty_funded— the gate the coordinator runs before telling the maker to lock RXD.A maker can therefore verify-and-lock RXD against an HTLC or claimant that is already frozen. The secret stays safe (claim raises
PreRevealAbort), but the RXD is committed into the covenant for the fullt_rxdCSV window before the maker learns the swap can never complete — for a condition that one already-implemented, already-tested read would have caught for free.docs/solutions/design-decisions/usdc-corridor-is-issuer-trusted-not-trustless.mddocuments the reveal-time check-then-reveal race as an accepted residual, but says nothing about this earlier, cheaply avoidable case. It reads as an oversight rather than a deliberate trade.Fix
Check contract + refundee before funding, and contract + claimant before claiming. (Round 5 narrowed the pre-claim gate to the claimant — the refundee cannot affect a claim — so the pre-fund gate is now the only place a frozen refundee would be caught at all.)
Note this is the reachability class again: the capability exists, is tested, and is not called where it would do the most good.