Skip to main content

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 TypeSupported Chains
MainnetXRP (XRP Ledger)
TestnettestXRP (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 Payment and 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 both SUCCESS and RECEIVER_FAILURE qualify, mirroring the XRPL behavior of IReferencedPaymentNonexistence).
  • If checkFirstMemoData is true: the standard hash of the first Memo's MemoData equals firstMemoDataHash.
  • If checkDestinationTag is true: the transaction has a DestinationTag and it equals destinationTag.

The request is confirmed if no transaction in the search range matches all applicable criteria.

At least one match field is required

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 (0x09 for XRPPaymentNonexistence)
  • sourceId: ID of the data source (XRP or testXRP)
  • messageIntegrityCode: MessageIntegrityCode derived from the expected response
  • requestBody: Data defining the request

Response

Top-level response structure.

Parameters

  • attestationType: Extracted from the request
  • sourceId: Extracted from the request
  • votingRound: The ID of the FDC round in which the request was considered
  • lowestUsedTimestamp: The lowest timestamp used to generate the response (set to minimalBlockTimestamp)
  • requestBody: Extracted from the request
  • responseBody: Data defining the response

Proof

Top-level proof structure for verification.

Parameters

  • merkleProof: Merkle proof corresponding to the attestation response
  • data: Attestation response

RequestBody

Parameters

  • minimalBlockNumber: First ledger of the search range (inclusive)
  • deadlineBlockNumber: Ledger to be included as the end of the search range
  • deadlineTimestamp: Timestamp to be included as the end of the search range
  • destinationAddressHash: Standard address hash of the address that should have received the payment
  • amount: Minimum amount in drops that should have been received
  • checkFirstMemoData: When true, only transactions whose first Memo's MemoData hash equals firstMemoDataHash qualify as a match
  • firstMemoDataHash: Hash of the expected first Memo's MemoData
  • checkDestinationTag: When true, only transactions whose DestinationTag equals destinationTag qualify as a match
  • destinationTag: Expected destination tag (XRPL only supports uint32 values)
  • proofOwner: EVM address authorized to use the proof; lower-cased by the verifier

ResponseBody

Parameters

  • minimalBlockTimestamp: Timestamp of the ledger at minimalBlockNumber
  • firstOverflowBlockNumber: First ledger past deadlineBlockNumber and deadlineTimestamp
  • firstOverflowBlockTimestamp: Timestamp of firstOverflowBlockNumber

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 lowestUsedTimestamp parameter uses the value of minimalBlockTimestamp
  • The lutlimit (Lowest Used Timestamp limit) is 0x127500 (1,209,600 seconds = 14 days)
  • At least one of checkFirstMemoData or checkDestinationTag must be true
  • Request is rejected if the verifier lacks visibility of all ledgers in the search range
  • Request is rejected if firstOverflowBlockNumber cannot be determined or lacks sufficient confirmations