Skip to main content

ReferencedPaymentNonexistence

Assertion that a specific payment, agreed upon to be completed by a certain deadline, has not been made. If confirmed, it shows that no transaction meeting the specified criteria (address, amount, reference) was found within the given block range.

This Information can be used, for example, to justify the liquidation of funds locked in a smart contract on Songbird if a payment is missed.

Supported Chains:

  • BTC (Bitcoin)
  • DOGE (Dogecoin)
  • XRP (XRP Ledger)
  • Test networks: testBTC (Bitcoin Testnet v3), testDOGE, testXRP

Request

FieldSolidity TypeDescription
minimalBlockNumberuint64The block number to start the search range.
deadlineBlockNumberuint64The block number to include as the end of the search range.
deadlineTimestampuint64The timestamp to include as the end of the search range.
destinationAddressHashbytes32The standard hash of the address where the payment was expected.
amountuint256The required payment amount in minimal units.
standardPaymentReferencebytes32The standard payment reference associated with the payment. Must not be zero.
checkSourceAddressesboolIf true, the source addresses root is checked.
sourceAddressesRootbytes32The root of the Merkle tree of the source addresses.
note

Standard Addresses Root is the root of the Merkle tree build on double keccak256 hashes of the all source addresses of the transaction.

Response

FieldSolidity TypeDescription
minimalBlockTimestampuint64The timestamp of the block at minimalBlockNumber.
firstOverflowBlockNumberuint64The block number immediately after the deadlineBlockNumber.
firstOverflowBlockTimestampuint64The timestamp of the firstOverflowBlockNumber.
  • firstOverflowBlockNumber: This is the first block with a height greater than deadlineBlockNumber and a timestamp later than deadlineTimestamp.
  • The search range includes blocks from minimalBlockNumber (inclusive) to firstOverflowBlockNumber (exclusive).

Verification process

  1. Block Confirmation:

    • If the firstOverflowBlock cannot be determined or lacks the required number of confirmations, the request is rejected.
    • The request is also rejected if firstOverflowBlockNumber is less than or equal to minimalBlockNumber.
  2. Search Range:

    • The search range includes blocks from minimalBlockNumber to firstOverflowBlockNumber (exclusive).
    • If the verifier does not have complete visibility of all blocks in this range, the request is rejected.
  3. Transaction Validation:

    • The request is confirmed if no transaction meeting the specified criteria (address, source addresses root, amount, reference) is found within the specified block range.
    • The criteria and timestamp interpretation are specific to each chain.

The verification process is chain-specific, with details described below.

UTXO chains (Bitcoin and Dogecoin)

  • Transaction Criteria:
    • The transaction must not be a coinbase transaction.
    • The transaction must include the specified standard payment reference.
    • If checkSourceAddresses is set to true, the sourceAddressesRoot of the transaction must match the specified sourceAddressesRoot.
    • The sum of all output values sent to the specified address minus the sum of all input values from the same address must be greater than the specified amount.
      • Typically, the sum of input values for the specified address is zero.
  • Timestamp: Uses the mediantime of the block.

Account-based chains (XRPL)

  • Transaction Criteria:

    • The transaction must be of type Payment.
    • The transaction must include the specified standard payment reference.
    • If checkSourceAddresses is set to true, the sourceAddressesRoot of the transaction must match the specified sourceAddressesRoot.
    • One of the following conditions must hold:
      • The transaction status is SUCCESS and the amount received by the specified address is greater than the specified amount.
      • The transaction status is RECEIVER_FAILURE and the specified address would have received an amount greater than the specified amount if the transaction had succeeded.
  • Timestamp: Uses the close_time of the ledger, converted to UNIX time.

Lowest used timestamp

For the lowestUsedTimestamp parameter, the value of minimalBlockTimestamp is used.

Standard payment reference

A standard payment reference is defined as a 32-byte sequence that can be added to a payment transaction, in the same way that a payment reference is attached to a traditional banking transaction.

Bitcoin and Dogecoin

  • Uses OP_RETURN to store references.
  • A transaction is considered to have a standardPaymentReference defined if it has:
    • Exactly one output UTXO with OP_RETURN script, and
    • The script is of the form OP_RETURN <reference\> or 6a<lengthOfReferenceInHex\><reference\> in hex, where the length of the reference is 32 bytes.
  • Then 0x<reference\> is the standardPaymentReference.

XRPL

  • Uses the memoData field.
  • A transaction has a standardPaymentReference if it has:
    • Exactly one Memo, and
    • The memoData of this field is a hex string that represents a byte sequence of exactly 32 bytes.
  • This 32-byte sequence defines the standardPaymentReference.

Finality

Blockchains have varying confirmation depths to consider blocks as final.

ChainchainIdConfirmations requiredConfirmation time
Bitcoin06≈60 mins
Dogecoin260≈60 mins
XRPL33≈12 seconds

Contract interface

Sourced from IReferencedPaymentNonexistence.sol on GitHub.

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6 <0.9;

/**
* @custom:name IReferencedPaymentNonexistence
* @custom:id 0x04
* @custom:supported BTC, DOGE, XRP
* @author Flare
* @notice Assertion that an agreed-upon 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.
* The criteria and timestamp are chain specific.
* ### UTXO (Bitcoin and Dogecoin)
*
*
* Criteria for the transaction:
*
*
* - It is not coinbase transaction.
* - The transaction has the specified standardPaymentReference.
* - The sum of values of all outputs with the specified address minus the sum of values of all inputs with
* the specified address is greater than `amount` (in practice the sum of all values of the inputs with the
* specified address is zero).
*
*
* Timestamp is `mediantime`.
* ### XRPL
*
*
*
* Criteria for the transaction:
* - The transaction is of type payment.
* - The transaction has the specified standardPaymentReference,
* - 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`, `0x127500`, `0x127500`
*/
interface IReferencedPaymentNonexistence {
/**
* @notice Toplevel request
* @param attestationType ID of the attestation type.
* @param sourceId ID of the data source.
* @param messageIntegrityCode `MessageIntegrityCode` that is derived from the expected response as defined.
* @param requestBody Data defining the request. Type and interpretation is determined by the `attestationType`.
*/
struct Request {
bytes32 attestationType;
bytes32 sourceId;
bytes32 messageIntegrityCode;
RequestBody requestBody;
}

/**
* @notice Toplevel response
* @param attestationType Extracted from the request.
* @param sourceId Extracted from the request.
* @param votingRound The ID of the State Connector round in which the request was considered.
* @param lowestUsedTimestamp The lowest timestamp used to generate the response.
* @param requestBody Extracted from the request.
* @param responseBody Data defining the response. The verification rules for the construction of the response
* body and the type are defined per specific `attestationType`.
*/
struct Response {
bytes32 attestationType;
bytes32 sourceId;
uint64 votingRound;
uint64 lowestUsedTimestamp;
RequestBody requestBody;
ResponseBody responseBody;
}

/**
* @notice Toplevel proof
* @param merkleProof Merkle proof corresponding to the attestation response.
* @param data Attestation response.
*/
struct Proof {
bytes32[] merkleProof;
Response data;
}

/**
* @notice Request body for ReferencePaymentNonexistence attestation type
* @param minimalBlockNumber The start block of the search range.
* @param deadlineBlockNumber The blockNumber to be included in the search range.
* @param deadlineTimestamp The timestamp to be included in the search range.
* @param destinationAddressHash The standard address hash of the address to which the payment had to be done.
* @param amount The requested amount in minimal units that had to be paid.
* @param standardPaymentReference The requested standard payment reference.
* @param checkSourceAddresses If true, the source address root is checked (only full match).
* @param sourceAddressesRoot The root of the Merkle tree of the source addresses.
* @custom:below The `standardPaymentReference` should not be zero (as a 32-byte sequence).
*/
struct RequestBody {
uint64 minimalBlockNumber;
uint64 deadlineBlockNumber;
uint64 deadlineTimestamp;
bytes32 destinationAddressHash;
uint256 amount;
bytes32 standardPaymentReference;
bool checkSourceAddresses;
bytes32 sourceAddressesRoot;
}

/**
* @notice Response body for ReferencePaymentNonexistence attestation type.
* @param minimalBlockTimestamp The timestamp of the minimalBlock.
* @param firstOverflowBlockNumber The height of the firstOverflowBlock.
* @param firstOverflowBlockTimestamp The timestamp of the firstOverflowBlock.
* @custom:below `firstOverflowBlock` is the first block that has block number higher than
* `deadlineBlockNumber` and timestamp later than `deadlineTimestamp`.
* The specified search range are blocks between heights including `minimalBlockNumber`
* and excluding `firstOverflowBlockNumber`.
*/
struct ResponseBody {
uint64 minimalBlockTimestamp;
uint64 firstOverflowBlockNumber;
uint64 firstOverflowBlockTimestamp;
}
}