Stablecoin payments don't have chargebacks. Once an agent signs, the money is gone. So the check has to happen before signing, and a claim about that check is worthless without a log, a transaction, and a third party who replayed it.
On 1 November, my agent proposed payments and sra-riskgate 0.15.0 checked each one before signing. This is what happened, on two testnets.
Arc testnet, through Circle Gateway
- 0.01 USDC to a known payee: APPROVE. Submitted to Circle Gateway, batch
c1491e17-cc2b-472c-b444-62beb83300fc. - Unlimited USDC approval for "auto-billing": HOLD (
TOKEN_APPROVAL,UNLIMITED_APPROVAL). Not signed. Anapprove(address, uint256)lets another address spend the wallet's USDC later, effectively without limit. - 0.01 USDC to a look-alike payee: REJECT (
LOOKALIKE_RECIPIENT). Not signed. The address imitated the known payee: same start, same end.
Settlement, checked on both sides rather than taken from the batch id:
| Run | Agent's Gateway balance | Payee's Gateway balance |
|---|---|---|
| 26 October (earlier Gateway run) | 0.10 → 0.09 | 0 → 0.01 |
| 1 November | 0.09 → 0.08 | 0.01 → 0.02 |
The 1 November payment landed on top of the 26 October one: the agent was debited exactly 0.01 and the payee credited exactly 0.01.
Script, log and settlement balances: gist
Base Sepolia, same version, third-party verified
The same evening, on Base Sepolia:
- 0.01 USDC to a known payee: APPROVE, sent, then read back from the receipt and verified. Transaction
- 2.00 USDC to an unknown payee: HOLD before signing (
HIGH_VALUE_TRANSFER,NEW_COUNTERPARTY). No transaction exists for it, by design. The hold reason and log are public, so anyone can replay why it stopped: gist
Flow Executor then verified both halves from the chain, not from my claim. The approved run settled (same transaction, success, block 53339258, payee 0x870b…7DDc, matching the APPROVE). For the held run, no transaction exists, and the log shows signed: false with the same two hold reasons.
Flow verified the settlement. Flow did not run or adopt RiskGate itself, and the evidence file keeps that distinction.
The count
2 good payments settled and 3 bad payments stopped before signing, across two testnets, in one evening, all with sra-riskgate 0.15.0.
Since then, sra-riskgate 0.18.0 builds the receipt check into the library: verify_settlement() confirms a mined receipt holds exactly the approved payment, and verify_gateway_balances() does the same for Circle Gateway.
If you build agents that pay, what would you want published with a claim like this: the log, the transaction, or a third party replaying the settlement?
- Model: SRA-RiskGate-4B
- SDK: sra-riskgate (
pip install sra-riskgate) - Benchmark: sra-stablecoin-risk-bench
- Original X post with both Base Sepolia runs: x.com
