Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rippling redux #2856

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 22 additions & 62 deletions docs/concepts/tokens/fungible-tokens/rippling.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
---
html: rippling.html
parent: trust-lines-and-issuing.html
seo:
description: Rippling is automatic multi-party net settlement of token balances.
labels:
Expand All @@ -9,92 +7,54 @@ labels:
---
# Rippling

In the XRP Ledger, "rippling" describes a process of atomic net settlement between multiple connected parties who have [trust lines](index.md) for the same token. Rippling is essential, because it enables token holders to transfer funds directly to each other, without any issuer involvement in the debiting and crediting process. In a sense, rippling is like a passive, two-way [exchange order](../decentralized-exchange/offers.md) with no limit and a 1:1 exchange rate for two tokens with the same currency code but different issuers.

Rippling only occurs along the [paths](paths.md) of a payment. [Direct XRP-to-XRP payments](../../payment-types/direct-xrp-payments.md) do not involve rippling.

For non-issuing accounts, rippling can be undesirable because it lets other users shift obligations between tokens with the same currency code but different issuers. The [No Ripple Flag](#the-no-ripple-flag) disables rippling by default when others open trust lines to your account, unless you enable rippling by default using the [Default Ripple flag](#the-default-ripple-flag).

{% admonition type="warning" name="Caution" %}When you create a trust line, you must explicitly enable the `tfSetNoRipple` flag to block rippling on your side of that trust line.{% /admonition %}
Rippling occurs when one holder sends issued currency to another holder of the same currency.

## Example of Rippling

"Rippling" occurs when more than one trust line is adjusted to make a payment. For example, if Alice owes Charlie money, and Alice also owes Bob money, then you could represent that in the XRP Ledger with trust lines like so:

[{% inline-svg file="/docs/img/noripple-01.svg" /%}](/docs/img/noripple-01.svg "Charlie --($10)-- Alice -- ($20) -- Bob")

If Bob wants to pay $3 to Charlie, then he could say, "Alice, take $3 of the money you owe me, and pay it to Charlie." Alice transfers some of the debt from Bob to Charlie. In the end, the trust lines work out like so:

[{% inline-svg file="/docs/img/noripple-02.svg" /%}](/docs/img/noripple-02.svg "Charlie --($13)-- Alice --($17)-- Bob")

We call this process, where two addresses pay each other by adjusting the balances of trust lines in between them, "rippling". This is a useful and important feature of the XRP Ledger. Rippling occurs when addresses are linked by trust lines that use the same currency code. The issuer does not need to be the same: in fact, larger chains always involve changing issuers.
Issuers distribute currency to holders over trust lines. When a holder creates a trust line to an issuer for a specific currency, they are willing to accept payments of that issued currency. For example, in the chart below, Holder A and Holder B both have trust lines to the Issuer of the token USD.

## The No Ripple Flag
[![Issuer with trust lines to two holders.](/docs/img/cpt-rippling1.png "Issuer with trust lines to two holders.")](/docs/img/cpt-rippling1.png)

Non-issuing accounts, especially liquidity providers who may hold balances from different issuers with different fees and policies, usually do not want their balances to ripple.
The Issuer transfers 50 USD to Holder A, and 10 USD to Holder B. For these trust lines, the Issuer has a net balance of -60 USD.

The **No Ripple** flag is a setting on a trust line. When two trust lines both have No Ripple enabled by the same address, payments from third parties cannot ripple through that address on those trust lines. This protects liquidity providers from having balances shift unexpectedly between different issuers using the same currency code.
[![Issuer sends currency to holders.](/docs/img/cpt-rippling2.png "Issuer sends currency to holders.")](/docs/img/cpt-rippling2.png)

An account can disable No Ripple on a single trust line, which can allow rippling through any pair that includes that trust line. The account can also enable rippling by default by enabling the [Default Ripple flag](#the-default-ripple-flag).
Since both accounts are willing to accept payments in USD tokens, Holder A can send a payment of 20 USD to Holder B. This appears to be a single transaction, but it actually involves two steps. Holder A sees their balance go down by 20 USD, Holder B sees their balance go up by 20 USD. Behind the scenes, though, Holder A’s side of the trust line to the Issuer is reduced by 20 USD. The Issuer’s side of the trust line is increased by 20 USD, bringing its net balance to -40 USD.

For example, imagine Emily has money issued by two different financial institutions, like so
[![Holder A sends currency through the Issuer.](/docs/img/cpt-rippling3.png "Holder A sends currency through the Issuer.")](/docs/img/cpt-rippling3.png)

[{% inline-svg file="/docs/img/noripple-03.svg" /%}](/docs/img/noripple-03.svg "Charlie --($10)-- Institution A --($1)-- Emily --($100)-- Institution B --($2)-- Daniel")
Then the Issuer side of the trust line to Holder B is reduced by 20 USD, and the account of Holder B is increased by 20 USD.

Now Charlie can pay Daniel by rippling through Emily's address. For example, if Charlie pays Daniel $10:
[![Holder B receives currency through the Issuer.](/docs/img/cpt-rippling4.png "Holder B receives currency through the Issuer.")](/docs/img/cpt-rippling4.png)

[{% inline-svg file="/docs/img/noripple-04.svg" /%}](/docs/img/noripple-04.svg "Charlie --($0)-- Institution A --($11)-- Emily --($90)-- Institution B --($12)-- Daniel")
The funds are transferred through the Issuer, but ultimately the Issuer’s balance doesn’t change. This flow of funds is known as _rippling_. Issuing accounts must allow rippling so that their holders can transfer funds to one another.

This may surprise Emily, who does not know Charlie or Daniel. Even worse, if Institution A charges her higher fees to withdraw her money than Institution B, this could cost Emily money. The No Ripple flag exists to avoid this scenario. If Emily sets it on both trust lines, then payments cannot ripple through her address using those two trust lines.
Rippling can involve several accounts as the XRPL server finds a path to transfer the funds. For example, the funds might flow between two issuer accounts that have a trust line between them.

For example:
[![Holder A transfers currency through Issuers A and B to get to Holder B.](/docs/img/cpt-rippling5.png "Holder A transfers currency through Issuers A and B to get to Holder B.")](/docs/img/cpt-rippling5.png)

[{% inline-svg file="/docs/img/noripple-05.svg" /%}](/docs/img/noripple-05.svg "Charlie --($10)-- Institution A --($1, No Ripple)-- Emily --($100, No Ripple)-- Institution B --($2)-- Daniel")
Other accounts such as liquidity providers and normal holders should not allow rippling. Rippling can lead to exploits where balances shift unexpectedly, funds are allocated at higher rates, and the holder ends up losing money on a transaction where they played no part.

Now the above scenario, where Charlie pays Daniel while rippling through Emily's address, is no longer possible.
# The Default Ripple Flag

### Specifics
The Default Ripple flag is an account level setting that enables rippling for all incoming trust lines. The default setting of the Default Ripple flag is false. Issuers must enable this flag for their customers to be able to send tokens to one another.

The No Ripple flag makes certain paths invalid, so that they cannot be used to make payments. A path is considered invalid if and only if it enters **and** exits an address node through trust lines where No Ripple has been enabled for that address.
The Default Ripple setting doesn’t affect trust lines created by your account, only trust lines others open to your account. If you change the setting, trust lines that were created before the change keep their existing No Ripple settings. You can use a TrustSet transaction to change the No Ripple setting of a trust line to match your account’s new default.

[{% inline-svg file="/docs/img/noripple-06.svg" /%}](/docs/img/noripple-06.svg "Diagram demonstrating that No Ripple has to be set on both trust lines by the same address to do anything")


## The Default Ripple Flag

The **Default Ripple** flag is an account setting that enables rippling on all _incoming_ trust lines by default. Issuers MUST enable this flag for their customers to be able to send tokens to each other.

The Default Ripple setting of your account does not affect trust lines that you create; only trust lines that others open to you. If you change the Default Ripple setting of your account, trust lines that were created before the change keep their existing No Ripple settings. You can use a [TrustSet transaction][] to change the No Ripple setting of a trust line to match your address's new default.
# The No Ripple Flag

Accounts that do not want to allow rippling can set the No Ripple flag. If you set the No Ripple flag on two of its trust lines, other accounts cannot use those trust lines to ripple payments through your account.

## Using No Ripple
<!--{# TODO: move these things into their own tutorials #}-->

### Enabling / Disabling No Ripple

The No Ripple flag can only be enabled on a trust line if the address has a positive or zero balance on that trust line. This is so that the feature cannot be abused to default on the obligation the trust line balance represents. (Of course, you can still default by abandoning the address.)

To enable the No Ripple flag, send a [TrustSet transaction][] with the `tfSetNoRipple` flag. You can disable the No Ripple flag (that is, allow rippling) with the `tfClearNoRipple` flag instead.
The No Ripple flag can only be enabled on a trust line if the address has a positive or zero balance. This is so that the feature cannot be abused to remove the obligation the trust line balance represents.

To enable the No Ripple flag, send a `TrustSet` transaction with the `tfSetNoRipple` flag. To disable the No Ripple flag, send a `TrustSet` transaction with the `tfClearNoRipple` flag.

### Looking Up No Ripple Status
## Looking up No Ripple status

In the case of two accounts that mutually trust each other, the No Ripple flag is tracked separately for each account.

Using the [HTTP / WebSocket APIs](../../../references/http-websocket-apis/index.md) or your preferred [client library](../../../references/client-libraries.md), look up trust lines with the [account_lines method][]. For each trust line, the `no_ripple` field shows whether the current address has enabled the No Ripple flag on that trust line, and the `no_ripple_peer` field shows whether the counterparty has enabled the No Ripple flag.

## See Also

- **Concepts:**
- [Paths](paths.md)
- **Tutorials:**
- [Stablecoin Issuer](../../../use-cases/tokenization/stablecoin-issuer.md)
- **References:**
- [account_lines method][]
- [account_info method][]
- [AccountSet transaction][]
- [TrustSet transaction][]
- [AccountRoot Flags](../../../references/protocol/ledger-data/ledger-entry-types/accountroot.md#accountroot-flags)
- [RippleState (trust line) Flags](../../../references/protocol/ledger-data/ledger-entry-types/ripplestate.md#ripplestate-flags)
Using the HTTP / WebSocket APIs or your preferred client library, look up trust lines with the `account_lines` method. For each trust line, the `no_ripple` field shows whether the current address has enabled the No Ripple flag on that trust line. The `no_ripple_peer` field shows whether the counterparty has enabled the No Ripple flag.

{% raw-partial file="/docs/_snippets/common-links.md" /%}
Binary file added docs/img/cpt-rippling1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/cpt-rippling2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/cpt-rippling3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/cpt-rippling4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/cpt-rippling5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.