Invariant
A1
Category
Algorand
Priority
Must-have — headline
Violation classes
All four USENIX classes
Why this is the headline invariant
A1 is the sharpest, most Algorand-specific test Ward runs, and the one every other invariant in the suite exists partly to set up context for. It targets a real, concrete trust boundary in Algorand’s gasless/sponsored-fee flow — not a hypothetical one.The trust boundary
The facilitator’s fee-abstraction flow builds a 2-transaction atomic group:1
Index 0 — the fee-payer leg, UNSIGNED by the client
A self-payment by the facilitator’s own fee-payer address, covering both transactions’ fees.
The client never signs this leg — only the facilitator does, at verify/settle time.
2
Index 1 — the client's payment, SIGNED by the client
The client’s actual ASA transfer, with
staticFee: 0 (its fee is pooled onto index 0).group
field intact, so the separate group-ID-consistency check doesn’t catch it. This exact mechanism was
confirmed by reading the compiled @x402/avm client scheme source directly — see
D7 #2 and #3
in the decision log.
A1 proves the facilitator’s own verifyFeePayerTransaction() check catches every one of these
rewrites before it would ever co-sign and broadcast the group.
Sub-cases
Each sub-case maps directly onto one of the USENIX study’s four violation classes:How it works
1
Discover the fee-payer address
Calls
GET /supported and reads the facilitator’s Algorand signer address from
signers["algorand:*"] — not blindly the first entry in the whole map, since a
multi-chain facilitator lists EVM/SVM signers too.2
Baseline sanity settlement
Builds and actually settles one honest sponsored-fee payment. If this fails, every tamper
result below would be meaningless — the facilitator might just reject everything on this
path — so A1 fails outright rather than reporting false confidence.
3
Run each sub-case against /verify only
For each of the five mutations, Ward builds a fresh payment, tampers the fee-payer leg, and
calls
/verify — never /settle for the malicious sub-cases. /verify exercises the
identical verifyFeePayerTransaction check by signing the tampered leg internally without
ever broadcasting it, so a real bug here can’t damage the facilitator’s operational key even
though this suite runs against a real, self-hosted instance.Pass condition
/verify.

