payMultiple Function
Function Type: external
Function Signature: payMultiple((address,address,string,address,uint256,uint256,uint256,bool,address,bytes)[])
Returns: (uint256 successfulTransactions, uint256 failedTransactions)
Executes a batch of individual payment instructions within a single transaction. Each payment instruction (PayData
) can originate from a different sender (from
) and specifies its own recipient, token, amount, fee, nonce, and authorization signature. This allows an executor to efficiently process multiple unrelated payments together.
Parameters
Parameter | Type | Description |
---|---|---|
payData | PayData[] | An array of structs, each defining a single payment operation |
PayData
Struct
Defines the complete set of parameters for a single, independent payment within the batch.
struct PayData {
address from;
address to_address;
string to_identity;
address token;
uint256 amount;
uint256 priorityFee;
uint256 nonce;
bool priority;
address executor;
bytes signature;
}
Field | Type | Description |
---|---|---|
from | address | The address whose funds are being sent and whose signature/nonce are validated for this payment. |
to_address | address | he recipient's direct address. Used if to_identity is empty. |
to_identity | string | An alternative identifier for the recipient. If provided, the contract will attempt to resolve it to an address. |
token | address | The specific token address for this individual transfer. |
amount | uint256 | The quantity of token to transfer from from to the recipient. |
priorityFee | uint256 | An additional fee, paid in token from the from address to the msg.sender (executor). |
nonce | uint256 | Nonce associated with the from address. Must match the expected sync or async nonce. |
priority | bool | Determines execution mode: true for asynchronous (uses async nonce), false for synchronous (uses sync nonce). |
executor | address | The address authorized to submit this transaction to the contract. Can be address(0) for unrestricted execution. |
signature | bytes | A cryptographic signature (EIP-191) from the from address, authorizing this specific payment's details. |
If you want to know more about the signature structure, refer to the Payment Signature Structure section.
Execution Methods
The function can be executed in two ways:
Fisher Execution
- An fisher collects multiple authorized
PayData
structures (with valid signatures) from various users from the fishing spot. - The fisher aggregates these into the
payData
array. - The fisher submits the transaction calling
payMultiple
.
Direct Execution
- A user or service constructs the
payData
array (potentially containing just one payment request or multiple from the same/different users for whom they have authorization). - They directly call
payMultiple
.
If using a service as the direct executor, we recommend specifying the service's address as the executor
parameter.
Workflow
-
Iterate through each
payment
(PayData
struct) in thepayData
array (i
from 0 to length-1):a. Signature & Sync Nonce Verification: Validates the provided
payData[i].signature
against the reconstructed message. Ifpriority
isfalse
(synchronous), this verification also implicitly checks thenonce
against the expected synchronous nonce as part of the signed message. Reverts if the signature is invalid.b. Executor Validation: Checks if the
payData[i].executor
parameter matches the transaction sender (msg.sender
). IfpayData[i].executor
isaddress(0)
, this check is bypassed, allowing anyone to submit the transaction (provided the signature is valid). IfpayData[i].executor
is non-zero and doesn't matchmsg.sender
incrementsfailedTransactions
and skips to the next iteration.c. Nonce Verification & Update: Checks nonce validity based on the
payData[i].priority
flag- If invalid, increments
failedTransactions
and continues to the next iteration - If valid, updates the appropriate nonce mapping:
nextSyncUsedNonce
for synchronized noncesnextAsyncUsedNonce
for asynchronized nonces
d. Resolve Recipient Address:
- If
to_identity
is provided (not empty), it attempts to resolve the identity to an owner address usingverifyStrictAndGetOwnerOfIdentity
from the MateNameService contract. - If
to_identity
is empty, it uses the providedto_address
.
e. Checks sender balance: Verifies the sender has sufficient funds for both the payment and priority fee. If insufficient, increments
failedTransactions
and moves to the next iterationf. Executes the payment: Processes the transfer using the
pay
function (which calls_updateBalance
). If payment fails, incrementsfailedTransactions
and continues to next iterationg. Processes priority fee (optional): If the executor holds sMATE and a priority fee is provided, the function calls
_updateBalance
to process the priority fee and distribute it to the executor in thepayData[i].token
.h. Records success: For successful payments, increments the
successfulTransactions
counter - If invalid, increments
-
After the loop finishes, if the
msg.sender
(executor) holds sMATE tokens:- Calculate the total reward:
reward = getReward() * successfulTransactions
. - Distribute the reward to the
msg.sender
using_giveMateReward
.
- Calculate the total reward:
-
The function returns two values:
failedTransactions
: Count of failed payment attemptssuccessfulTransactions
: Count of successful payments