fix(recurring): revert on a failed or short subscriber pull - #1753
fix(recurring): revert on a failed or short subscriber pull#1753LeoSlrRf wants to merge 1 commit into
Conversation
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
Greptile SummaryThe PR makes recurring ERC-20 settlement fail atomically when the subscriber pull is unsuccessful or under-delivers, an approval fails, or the relayer fee cannot be transferred.
Confidence Score: 5/5The PR appears safe to merge, with the changed settlement path consistently reverting on failed or incomplete token operations. The new checks preserve transaction atomicity, prevent residual proxy balances from funding an unsuccessful subscriber pull, and retain collectability after failures; the added tests exercise the principal changed token behaviors and rollback invariants. Important Files Changed
Sequence DiagramsequenceDiagram
participant R as Relayer
participant P as Recurring Proxy
participant T as ERC20 Token
participant F as ERC20 Fee Proxy
R->>P: triggerRecurringPayment(...)
P->>P: Validate permit and mark cycle
P->>T: balanceOf(proxy)
P->>T: transferFrom(subscriber, proxy, total)
P->>T: balanceOf(proxy)
alt pull fails or received amount is short
P-->>R: Revert entire transaction
else exact pull succeeds
P->>T: approve(feeProxy, 0)
P->>T: approve(feeProxy, payment + fee)
P->>F: transferFromWithReferenceAndFee(...)
F->>T: Transfer recipient and fee amounts
P->>T: transfer(relayer, relayerFee)
alt approval or relayer transfer fails
P-->>R: Revert all settlement effects
else settlement succeeds
P-->>R: Complete
end
end
Reviews (1): Last reviewed commit: "fix(recurring): revert on a failed or sh..." | Re-trigger Greptile |

Harden token pull safety in
ERC20RecurringPaymentProxyIntroduces two new custom errors and three private helper functions to make token transfers in
ERC20RecurringPaymentProxymore robust against non-standard ERC-20 behaviour:_pullExact— wrapssafeTransferFromand checks the contract's balance before and after the pull. Reverts withERC20RecurringPaymentProxy__TransferFailedif the call returns false, and withERC20RecurringPaymentProxy__ShortPullif fewer tokens than requested actually arrived (fee-on-transfer tokens)._approveFeeProxy— performs the USDT-safe zero-then-set approval pattern, reverting withERC20RecurringPaymentProxy__TransferFailedon either step failing._payRelayer— transfers the relayer fee tomsg.sender, reverting withERC20RecurringPaymentProxy__TransferFailedif the transfer returns false.These helpers replace the inline transfer/approve/relayer-fee logic in
_collectAndForward, ensuring that a failed or under-delivering token transfer always reverts the entire call and leaves the payment bitmap unset.Three test token contracts are added to support the new test cases:
ERC20SilentFail— returnsfalseinstead of reverting on a failedtransferFrom.ERC20FeeOnTransfer— deducts a 1-unit fee on everytransferFrom, simulating under-delivery.ERC20FailTransfer— always returnsfalsefromtransfer, allowing the relayer-fee failure path to be exercised.A new
Pull assertionstest suite covers all four failure scenarios: an under-funded subscriber, a residual proxy balance that cannot substitute for a missing subscriber pull, a fee-on-transfer token, a silently failingtransferFrom, and a failing relayer-fee payout.