pay Function
Function Type: external
Function Signature: pay(address,address,string,address,uint256,uint256,uint256,bool,address,bytes)
The pay function executes a payment from one address to a single recipient address or identity. This is EVVM's core single payment function with intelligent staker detection and reward distribution.
Key features:
- Single Payment: Transfers tokens from one sender to one recipient (address or username)
- Staker Detection: Automatically detects if the executor is a staker and distributes rewards accordingly
- Flexible Nonce Management: Supports both synchronous and asynchronous nonce patterns
- Identity Resolution: Can send payments to usernames which are resolved to addresses via NameService
The function supports both synchronous and asynchronous nonce management through the priorityFlag parameter, making it flexible for various execution patterns and use cases. For details on nonce types, see Nonce Types in EVVM. For signature details, see Payment Signature Structure.
Parameters
| Field | Type | Description |
|---|---|---|
from | address | The address of the payment sender whose funds are being transferred and whose signature/nonce are validated. |
to_address | address | Direct recipient address. Used when to_identity is empty. |
to_identity | string | Username/identity of the recipient. If provided, the contract resolves it to an address via the NameService. |
token | address | The token contract address for the transfer. |
amount | uint256 | The quantity of tokens to transfer from from to the recipient. |
priorityFee | uint256 | Additional fee for transaction priority. If the executor is a staker, they receive this fee as a reward. |
nonce | uint256 | Transaction nonce value. Usage depends on priorityFlag: if false (sync), this value is ignored and automatic nonce is used. |
priorityFlag | bool | Execution type flag: false = synchronous nonce (sequential), true = asynchronous nonce (custom). |
executor | address | Address authorized to execute this transaction. Use address(0) to allow any address to execute. |
signature | bytes | Cryptographic signature (EIP-191) from the from address authorizing this payment. |
The nonce parameter usage depends on priorityFlag: when false (synchronous), the nonce is automatically managed and the provided value is ignored; when true (asynchronous), the provided nonce value is used for custom ordering.
Execution Methods
The function can be executed in multiple ways:
Fisher Execution
- A user signs the payment details and sends the request (parameters + signature) to a fishing spot.
- A fisher (preferably a staker for rewards) captures the transaction and validates the request.
- The fisher submits the transaction to the function for processing and receives rewards if they are a staker.
Direct Execution
- The user or any authorized service directly calls the
payfunction. - If an
executoraddress is specified, only that address can submit the transaction. - If
executoris set toaddress(0), anyone can execute the transaction with a valid signature.
When using a service as the executor, we recommend specifying the service's address in the executor parameter for additional security.
Workflow
- Signature Verification: Validates the
signatureagainst thefromaddress and other parameters usingverifyMessageSignedForPay. For synchronous payments (priorityFlag = false), usesnextSyncUsedNonce[from]as the nonce; for asynchronous payments (priorityFlag = true), uses the providednonceparameter. Reverts withInvalidSignatureon failure. - Executor Validation: If
executoris notaddress(0), checks thatmsg.sendermatches theexecutoraddress. Reverts withSenderIsNotTheExecutorif they don't match. - Asynchronous Nonce Verification: For asynchronous payments only (
priorityFlag = true), checks if the providednoncehas already been used for thefromaddress by consulting theasyncUsedNoncemapping. Reverts withInvalidAsyncNonceif the nonce has already been used. - Resolve Recipient Address: Determines the final recipient address:
- If
to_identityis provided (not empty), resolves the identity to an owner address usingverifyStrictAndGetOwnerOfIdentityfrom the NameService contract. - If
to_identityis empty, uses the providedto_address.
- If
- Balance Update: Executes the payment transfer using the
_updateBalancefunction, sendingamountoftokenfrom thefromaddress to the resolved recipient address. Reverts withUpdateBalanceFailedon transfer failure. - Staker Benefits Distribution: If the executor (
msg.sender) is a registered staker:- Priority Fee Transfer: If
priorityFee > 0, transfers thepriorityFeeamount oftokenfrom thefromaddress to themsg.sender(executor) as a staker reward. - Principal Token Reward: Grants 1x reward amount in principal tokens to the
msg.sender(executor) using the_giveRewardfunction.
- Priority Fee Transfer: If
- Nonce Management: Updates nonce tracking based on execution type:
- Asynchronous (
priorityFlag = true): Marks the specificnonceas used (true) for thefromaddress in theasyncUsedNoncemapping. - Synchronous (
priorityFlag = false): Increments the synchronous nonce counter for thefromaddress to prevent replay attacks.
- Asynchronous (
For more information about the signature structure, refer to the Payment Signature Structure section.
Need to send from one user to multiple recipients?
Use dispersePay to send tokens from a single sender to multiple different addresses or identities in one transaction.
Need to execute multiple separate payments?
Use payMultiple to process several individual pay operations within a single transaction, each with their own sender, recipient, and parameters.