Skip to main content

dispersePay Function

Function Type: external
Function Signature: dispersePay(address,(uint256,address,string)[],address,uint256,uint256,uint256,bool,address,bytes) Function Selector: 0xef83c1d6

Facilitates batch payments, enabling a single transaction to distribute a specified token from one sender (from) to multiple recipients defined in toData. This function supports both synchronous and asynchronous execution modes. The signature structure for these payments is detailed in the Disperse Payment Signature Structure section.

Parameters

ParameterTypeDescription
fromaddressThe address initiating the payment and whose funds will be dispersed.
toDataDispersePayMetadata[]An array detailing each recipient's address/identity and the amount they should receive. See struct below.
tokenaddressThe contract address of the token being dispersed.
amountuint256The total amount of token to be distributed across all recipients in toData. Must equal the sum of individual amounts in toData.
priorityFeeuint256An additional fee paid in the specified token to the executor processing the transaction.
nonceuint256A user-specific nonce for replay protection. Usage depends on the priority flag (see Workflow.
priorityboolDetermines execution mode: true for asynchronous (uses async nonce), false for synchronous (uses sync nonce).
executoraddressThe address authorized to submit this transaction to the contract. Can be address(0) for unrestricted execution.
signaturebytesA cryptographic signature (EIP-191) from the from address, authorizing the entire disperse operation.
info

If you want to know more about the signature structure, refer to the Disperse Payment Signature Structure section.

DispersePayMetadata Struct

Defines the payment details for a single recipient within the toData array.

struct DispersePayMetadata {
uint256 amount;
address to_address;
string to_identity;
}
FieldTypeDescription
amountuint256The amount of token to be sent to this recipient.
to_addressaddressThe recipient's direct address. Used if to_identity is empty.
to_identitystringAn alternative identifier for the recipient. If provided, the contract will attempt to resolve it to an address.
note

If to_identity is an empty string (""), the to_address field will be used as the recipient's destination address. Otherwise, the contract attempts to resolve the to_identity to its owner address.

Execution Methods

The function can be executed in two ways:

Fisher Execution

When the executor is the fisher:

  1. Multiple users send payment requests to the fishing spot
  2. The fisher captures these transactions and validates all parameters
  3. The fisher submits the consolidated transaction to the contract for processing

Direct Execution

When the executor is the user or a service:

  1. The user/service submits a set of transactions directly to the contract
tip

If using a service as the direct executor, we recommend specifying the service's address as the executor parameter.

Workflow

  1. Signature Verification: Validates the provided signature against the reconstructed message hash and the from address using verifyMessageSignedForPay. If priority is false (synchronous), this verification also implicitly checks the nonce against the expected synchronous nonce as part of the signed message. Reverts if the signature is invalid.

  2. Executor Validation: Checks if the executor parameter matches the transaction sender (msg.sender). If executor is address(0), this check is bypassed, allowing anyone to submit the transaction (provided the signature is valid). Reverts if executor is non-zero and doesn't match msg.sender.

  3. Nonce Check (Asynchronous): If priority is true (asynchronous), checks if the provided nonce has already been used by consulting the asyncUsedNonce mapping for the from address. Reverts if the nonce is already marked as used.

  4. Balance Check: Verifies that the from address has a sufficient balance of the token to cover the amount plus the priorityFee. Reverts if balance is insufficient.

  5. Substract balance: Subtracts the amount and priorityFee from the from address' balance.

  6. Payment Distribution Loop: Iterates through each DispersePayMetadata entry in the toData array:

    a. Initialize accumulatedAmount: A running total (accumulatedAmount) is maintained, starting at zero.

    b. Resolve Recipient Address:

    • If to_identity is provided (not empty), it attempts to resolve the identity to an owner address using verifyStrictAndGetOwnerOfIdentity from the MateNameService contract.
    • If to_identity is empty, it uses the provided to_address.

    c. Transfer to Recipient: Transfers the amount specified in the current DispersePayMetadata entry from this contract to the resolved recipient address.

    d. Update Accumulated Amount: Adds the recipient's amount to the accumulatedAmount tracker.

  7. Total Amount Verification: After the loop, verifies that the final accumulatedAmount exactly equals the amount parameter initially provided. Reverts if there is a mismatch.

  8. Executor Reward (Optional): If the executor (msg.sender) holds sMATE tokens, the contract may trigger a reward distribution using _giveMateReward, typically equivalent to one getReward() plus the priorityFee, the reward amount is given in MATE tokens and the priorityFee is given in the token specified in the token parameter.

  9. Nonce Update: Marks the nonce as used for the from address to prevent replays.

    • If priority was true, updates the asynchronous nonce tracking (asyncUsedNonce).
    • If priority was false, updates the synchronous nonce tracking adding one to the nextSyncUsedNonce mapping for the from address.

DispersePay with Fisher

DispersePay Direct