Incorrect token transfer in _processERC20Payment() function
_processERC20Payment uses transferFrom on the contract's own address with the initiator as recipient, but no allowance exists, so every ERC-20 subscription payment reverts with insufficient allowance.
Description
The current design of the payment management within the SubExecutor contract introduces significant risks of logic failures in token transfer operations, potentially resulting in the inability to fulfill certain subscriptions and the potential locking of tokens.
The SubExecutor contract is designed to manage subscriptions and process automatic payments between accounts, using native/ERC20 tokens as a payment method. The current implementation presents an inconsistency in the authorization flow and execution of payments, specifically in the _processERC20Payment() function, which attempts to transfer ERC20 tokens from the SubExecutor contract to the initiator of the subscription using the transferFrom() method.
The payment functionality consists of the following steps:
-
Payment Processing (
processPayment()): invoked by the initiator to process a payment based on an active subscription. The logic ensures that only the initiator can execute the payment. It executes either_processERC20Payment()or_processNativePayment()whether it is a native payment or ERC20. -
ERC20 Token Transfer (
_processERC20Payment()): the use oftransferFrom()implies that the initiator has permitted theSubExecutorto withdraw tokens on their behalf, which does not align with the subscription model where theSubExecutoris the holder of the funds and must send them directly to theinitiator. This approach misinterprets the authorization dynamics in ERC20 contracts, leading to a potential failure in payment execution due to "insufficient allowance".
/// @notice Processes an ERC20 payment for the subscriptionfunction _processERC20Payment(SubStorage storage sub) internal {IERC20 token = IERC20(sub.erc20Token);uint256 balance = token.balanceOf(address(this));require(balance >= sub.amount, "Insufficient token balance");token.transferFrom(address(this), sub.initiator, sub.amount);}
Impact
Every ERC-20 subscription payment reverts due to missing allowance, breaking the protocol's primary recurring-payment functionality for ERC-20 tokens.
Recommendation
Consider changing the code in the following way:
- token.transferFrom(address(this), sub.initiator, sub.amount);+ token.transfer(sub.initiator, sub.amount);
Resolution
Team Response: Acknowledged and fixed as suggested.

