fix: an approval claimed when its window closes is orphaned, leaving the dApp promise unsettled forever #262
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found by the round-5 independent review of #205 and reproduced there. Non-blocking for that PR, which passed.
The approval window is closed while an attempt holds the claim, and the attempt then fails retryably at the verify stage (
src/background/index.js:914). The release path returns the approval to the pool — but the window it would be retried from no longer exists, and nothing else will ever settle it. The dApp'seth_sendTransactionpromise stays pending indefinitely.This is the deliberate safe side of the round-3 trade, not a regression: settling on that path is precisely the fund-loss defect round 3 found, where an in-flight broadcast was reported to the dApp as
4001 User rejected the request.while the transaction actually sent. Liveness was given up to buy that safety. It should not be given up permanently.Acceptable fix, from the review: re-check the window on release, and settle
4001if it is gone. That distinguishes "retry is still possible" from "nobody can ever retry this", which the current release path conflates.Also in scope: three settlement paths with no test coverage
The suite added by #205 covers the window-close, address-switch and reject paths against a claimed approval. Three more route through
settleApproval()and are exercised only by the reviewer's throwaway probes:AUTISTMASK_APPROVAL_RESPONSE, approve polarityAUTISTMASK_APPROVAL_RESPONSE, reject polarityruntime.onConnectport disconnectAll three were verified correct by hand — each is refused against a mid-broadcast claimed approval and the dApp still receives its result — but nothing in the repo would catch a regression. Given that every one of the five review rounds on that PR found a defect in exactly this machinery, they should be pinned.
One tightening, not a defect
A
TX_RESPONSEcarrying an attacker-paying artifact aimed at apersonal_signor connection approval (neither hastxParams) broadcasts nothing — but it fails closed via aTypeErrorrather than an explicit type check. Worth making explicit so a future refactor cannot turn an incidental throw into a path.Definition of done
TX_RESPONSEis honoured.TODO.mdupdated in the same commit.make checkpasses.