IXRPPaymentNonexistence
An interface to verify that no XRP Ledger Payment transaction matching the supplied destination, amount, memo, and/or destination tag was confirmed within a given ledger range.
Sourced from IXRPPaymentNonexistence.sol on GitHub.
Overview
Where IReferencedPaymentNonexistence matches transactions by a standard payment reference, IXRPPaymentNonexistence matches them by the first Memo's MemoData hash and/or the DestinationTag — the two correlating fields native XRPL applications already use.
This is useful for invoicing flows where each payer is assigned a destination tag, and for memo-based protocols.
Supported Chains
| Network Type | Supported Chains |
|---|---|
| Mainnet | XRP (XRP Ledger) |
| Testnet | testXRP (XRPL Testnet) |
Verification Criteria
A transaction is considered a match (and would invalidate the nonexistence claim) if all of the following hold:
- The transaction is of type
Paymentand produces a successful payment summary with one sender and one receiver. - The receiver's standard address hash equals
destinationAddressHash. - The intended receiving amount is greater than or equal to the requested
amount. - The transaction did not fail with
SENDER_FAILURE(so bothSUCCESSandRECEIVER_FAILUREqualify, mirroring the XRPL behavior ofIReferencedPaymentNonexistence). - If
checkFirstMemoDataistrue: the standard hash of the first Memo'sMemoDataequalsfirstMemoDataHash. - If
checkDestinationTagistrue: the transaction has aDestinationTagand it equalsdestinationTag.
The request is confirmed if no transaction in the search range matches all applicable criteria.
At least one of checkFirstMemoData or checkDestinationTag must be true.
Interface Definition
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6 <0.9;
/**
* @custom:name IXRPPaymentNonexistence
* @custom:id 0x09
* @custom:supported XRP, testXRP
* @author Flare
* @notice Assertion that an agreed-upon XRP payment has not been made by a certain deadline.
* A confirmed request shows that a transaction meeting certain criteria (address, amount, reference) did not appear
* in the specified block range.
*
* This type of attestation can be used to e.g. provide grounds to liquidate funds locked by a smart contract on
* Flare when a payment is missed.
*
* @custom:verification If `firstOverflowBlock` cannot be determined or does not have a sufficient number of
* confirmations, the attestation request is rejected.
*
* If `firstOverflowBlockNumber` is higher or equal to `minimalBlockNumber`, the request is rejected.
* The search range are blocks between heights including `minimalBlockNumber` and excluding `firstOverflowBlockNumber`.
* If the verifier does not have a view of all blocks from `minimalBlockNumber` to `firstOverflowBlockNumber`,
* the attestation request is rejected.
*
* The request is confirmed if no transaction meeting the specified criteria is found in the search range.
*
* Criteria for the transaction:
* - The transaction is of type payment.
* - The destination address hash matches the hash of the destination address of the transaction.
* - If `checkFirstMemoData` is true, the hash of the MemoData field of the first Memo in the transaction
* matches `firstMemoDataHash`.
* - If `checkDestinationTag` is true, the destination tag of the transaction matches `destinationTag`.
* At least one of the fields `checkFirstMemoData` and `checkDestinationTag` must be true for the request
* to be valid.
* - One of the following is true:
* - Transaction status is `SUCCESS` and the amount received by the specified destination address is greater
* than the specified `value`.
* - Transaction status is `RECEIVER_FAILURE` and the specified destination address would receive an amount
* greater than the specified `value` had the transaction been successful.
*
* Timestamp is `close_time` converted to UNIX time.
*
* @custom:lut `minimalBlockTimestamp`
* @custom:lutlimit `0x127500`
*/
interface IXRPPaymentNonexistence {
struct Request {
bytes32 attestationType;
bytes32 sourceId;
bytes32 messageIntegrityCode;
RequestBody requestBody;
}
struct Response {
bytes32 attestationType;
bytes32 sourceId;
uint64 votingRound;
uint64 lowestUsedTimestamp;
RequestBody requestBody;
ResponseBody responseBody;
}
struct Proof {
bytes32[] merkleProof;
Response data;
}
struct RequestBody {
uint64 minimalBlockNumber;
uint64 deadlineBlockNumber;
uint64 deadlineTimestamp;
bytes32 destinationAddressHash;
uint256 amount;
bool checkFirstMemoData;
bytes32 firstMemoDataHash;
bool checkDestinationTag;
uint256 destinationTag;
address proofOwner;
}
struct ResponseBody {
uint64 minimalBlockTimestamp;
uint64 firstOverflowBlockNumber;
uint64 firstOverflowBlockTimestamp;
}
}
Structs
Request
Top-level request structure.
Parameters
attestationType: ID of the attestation type (0x09forXRPPaymentNonexistence)sourceId: ID of the data source (XRPortestXRP)messageIntegrityCode:MessageIntegrityCodederived from the expected responserequestBody: Data defining the request
Response
Top-level response structure.
Parameters
attestationType: Extracted from the requestsourceId: Extracted from the requestvotingRound: The ID of the FDC round in which the request was consideredlowestUsedTimestamp: The lowest timestamp used to generate the response (set tominimalBlockTimestamp)requestBody: Extracted from the requestresponseBody: Data defining the response
Proof
Top-level proof structure for verification.
Parameters
merkleProof: Merkle proof corresponding to the attestation responsedata: Attestation response
RequestBody
Parameters
minimalBlockNumber: First ledger of the search range (inclusive)deadlineBlockNumber: Ledger to be included as the end of the search rangedeadlineTimestamp: Timestamp to be included as the end of the search rangedestinationAddressHash: Standard address hash of the address that should have received the paymentamount: Minimum amount in drops that should have been receivedcheckFirstMemoData: Whentrue, only transactions whose first Memo'sMemoDatahash equalsfirstMemoDataHashqualify as a matchfirstMemoDataHash: Hash of the expected first Memo'sMemoDatacheckDestinationTag: Whentrue, only transactions whoseDestinationTagequalsdestinationTagqualify as a matchdestinationTag: Expected destination tag (XRPL only supportsuint32values)proofOwner: EVM address authorized to use the proof; lower-cased by the verifier
ResponseBody
Parameters
minimalBlockTimestamp: Timestamp of the ledger atminimalBlockNumberfirstOverflowBlockNumber: First ledger pastdeadlineBlockNumberanddeadlineTimestampfirstOverflowBlockTimestamp: Timestamp offirstOverflowBlockNumber
Block Range Definition
The search range is [minimalBlockNumber, firstOverflowBlockNumber).
firstOverflowBlockNumber is the first ledger that has both a height greater than deadlineBlockNumber and a timestamp later than deadlineTimestamp.
Implementation Notes
- Attestation ID:
0x09 - The
lowestUsedTimestampparameter uses the value ofminimalBlockTimestamp - The
lutlimit(Lowest Used Timestamp limit) is0x127500(1,209,600 seconds = 14 days) - At least one of
checkFirstMemoDataorcheckDestinationTagmust betrue - Request is rejected if the verifier lacks visibility of all ledgers in the search range
- Request is rejected if
firstOverflowBlockNumbercannot be determined or lacks sufficient confirmations