Compare commits

...

2 Commits

Author SHA1 Message Date
Maria Shodunke
0313ee2c07 Fix amendment error on MPT page 2026-04-13 18:49:30 +01:00
Maria Shodunke
045d8e147b Document updates for MPT DEX 2026-04-09 14:23:50 +01:00
30 changed files with 564 additions and 112 deletions

View File

@@ -216,7 +216,8 @@
[MPTokenIssuanceCreate transaction]: /docs/references/protocol/transactions/types/mptokenissuancecreate.md
[MPTokenIssuanceDestroy transaction]: /docs/references/protocol/transactions/types/mptokenissuancedestroy.md
[MPTokenIssuanceSet transaction]: /docs/references/protocol/transactions/types/mptokenissuanceset.md
[MPTokensV1_1 amendment]: /resources/known-amendments.md#priceoracle
[MPTokensV1_1 amendment]: /resources/known-amendments.md#mptokensv1
[MPTokensV2 amendment]: /resources/known-amendments.md#mptokensv2
[RFC-1751]: https://tools.ietf.org/html/rfc1751
[RequireFullyCanonicalSig amendment]: /resources/known-amendments.md#requirefullycanonicalsig
[Require Destination Tag]: docs/tutorials/compliance-features/require-destination-tags.md

View File

@@ -28,7 +28,14 @@ LP tokens enable liquidity providers to:
## How the AMM Works
An AMM holds two different assets: at most one of these can be XRP, and one or both of them can be [tokens](../index.md).
An AMM holds two different assets: at most one of these can be XRP, and one or both of them can be [tokens](../index.md). Valid token combinations are:
- XRP/Trust Line Token
- Trust Line Token/Trust Line Token
- XRP/MPT
- Trust Line Token/MPT
- MPT/MPT (each with a unique `mpt_issuance_id`)
For any given pair of assets, there can be up to one AMM in the ledger. Anyone can create the AMM for an asset pair if it doesn't exist, or deposit to an AMM if it already exists.
When you want to trade in the decentralized exchange, your [offers](offers.md) and [cross-currency payments](../../payment-types/cross-currency-payments.md) can automatically use AMMs to complete the trade. A single transaction might execute by matching offers, AMMs, or a mix of both, depending on what's cheaper. You can [read a transaction's metadata](../../transactions/finality-of-results/look-up-transaction-results.md) to see what liquidity it consumed.
@@ -47,7 +54,9 @@ The XRP Ledger implements a _geometric mean_ AMM with a weight parameter of 0.5,
### Token Issuers
Tokens with different issuers are considered different assets. This means that there can be an AMM for two tokens with the same currency code but different issuers. For example, _FOO_ issued by WayGate is different than _FOO_ issued by StableFoo. Similarly, the tokens can have the same issuer but different currency codes. The trade direction doesn't matter; the AMM for FOO.WayGate to XRP is the same as the AMM for XRP to FOO.WayGate.
Trust Line Tokens with different issuers are considered different assets. This means that there can be an AMM for two Trust Line Tokens with the same currency code but different issuers. For example, _FOO_ issued by WayGate is different than _FOO_ issued by StableFoo. Trust Line Tokens can also have the same issuer but different currency codes. The trade direction doesn't matter; the AMM for FOO.WayGate to XRP is the same as the AMM for XRP to FOO.WayGate.
For MPTs, each issuance has a unique `mpt_issuance_id` that identifies it, so there is no ambiguity between issuers.
### Currency Risk
@@ -82,8 +91,9 @@ The diagram below illustrates how an offer interacts with other offers and AMM l
To prevent misuse, some restrictions apply to the assets used in an AMM. If you try to create an AMM with an asset that does not meet these restrictions, the transaction fails. The rules are as follows:
- The asset must not be an LP token from another AMM.
- If the asset is a token whose issuer uses [Authorized Trust Lines](../fungible-tokens/authorized-trust-lines.md), the creator of the AMM must be authorized to hold those tokens. Only your authorized trust lines can deposit that token into the AMM or withdraw it; however, you can still deposit or withdraw the other asset.
- If the [Clawback amendment][] is enabled, the issuer of the token must not have enabled the ability to claw back their tokens.
- If the asset is a Trust Line Token whose issuer uses [Authorized Trust Lines](../fungible-tokens/authorized-trust-lines.md), the creator of the AMM must be authorized to hold those tokens. Similarly, if the asset is an MPT with the **Require Auth** flag enabled, the creator must be authorized to hold that MPT. Only authorized holders can deposit that token into the AMM or withdraw it; however, you can still deposit or withdraw the other asset.
- The issuer must not be able to claw back the asset. For Trust Line Tokens, this means the issuer has not enabled **Allow Trust Line Clawback** on their account. For MPTs, the **Can Clawback** flag must not be enabled on the MPT issuance.
- If the asset is an MPT, the **Can Trade** flag must be enabled on the issuance, and the **Can Transfer** flag must also be enabled if the account is not the issuer.
## AMM and LP Tokens
@@ -173,7 +183,7 @@ In the ledger's state data, an AMM consists of multiple [ledger entries](../../.
The address of this AccountRoot is chosen somewhat randomly when the AMM is created, and it is different if the AMM is deleted and re-created. This is to prevent people from funding the AMM account with excess XRP in advance.
- [Trust lines](../fungible-tokens/index.md) to the special AMM Account for the tokens in the AMM's pool.
- [RippleState entries](../../../references/protocol/ledger-data/ledger-entry-types/ripplestate.md) for any Trust Line Tokens in the AMM's pool, or [MPToken entries](../../../references/protocol/ledger-data/ledger-entry-types/mptoken.md) for any MPTs.
These ledger entries are not owned by any account, so the [reserve requirement](../../accounts/reserves.md) does not apply to them. However, to prevent spam, the transaction to create an AMM has a special [transaction cost](../../transactions/transaction-cost.md) that requires the sender to burn a larger than usual amount of XRP.
@@ -185,9 +195,9 @@ An AMM is deleted when an [AMMWithdraw transaction][] withdraws all assets from
- AMM
- AccountRoot
- Trust lines for the AMM's LP tokens. Those trust lines would have a balance of 0 but may have other details, such as the limit, set to a non-default value.
- Trust lines for the tokens that were in the AMM pool.
- Trust lines for any Trust Line Tokens that were in the AMM pool, or MPToken objects for any MPTs.
If there are more than 512 trust lines attached to the AMM account when it would be deleted, the withdraw succeeds and deletes as many trust lines as it can, but leaves the AMM in the ledger with no assets in its pool.
If there are more than 512 trust lines attached to the AMM account when it would be deleted, the withdraw succeeds and deletes as many as it can, but leaves the AMM in the ledger with no assets in its pool.
While an AMM has no assets in its pool, anyone can delete it by sending an [AMMDelete transaction][]; if the remaining number of trust lines is still greater than the limit, multiple AMMDelete transactions might be necessary to fully delete the AMM. Alternatively, anyone can perform a [special deposit](../../../references/protocol/transactions/types/ammdeposit.md#empty-amm-special-case) to fund the AMM as if it were new. No other operations are valid on an AMM with an empty asset pool.

View File

@@ -13,7 +13,9 @@ targets:
The XRP Ledger has possibly the world's oldest _decentralized exchange_ (sometimes abbreviated "DEX"), operating continuously since the XRP Ledger's launch in 2012. The exchange allows users to buy and sell [tokens](../index.md) for XRP or other tokens, with minimal [fees](../../transactions/fees.md) charged to the network itself (not paid out to any party).
{% admonition type="warning" name="Caution" %}Anyone can [issue a token](../../../tutorials/tokens/fungible-tokens/issue-a-fungible-token.md) with any currency code or ticker symbol they want and sell it in the decentralized exchange. Always perform due diligence before buying a token, and pay attention to the issuer. Otherwise, you might give up something of value and receive worthless tokens in exchange.{% /admonition %}
{% admonition type="warning" name="Caution" %}Anyone can issue a token ([trust line token](../../../tutorials/tokens/fungible-tokens/issue-a-fungible-token.md) or [MPT](../../../tutorials/tokens/mpts/issue-a-multi-purpose-token.md)) with any currency code or ticker symbol they want and sell it in the decentralized exchange. Always perform due diligence before buying a token, and pay attention to the issuer. Otherwise, you might give up something of value and receive worthless tokens in exchange.{% /admonition %}
<!-- {% amendment-disclaimer name="MPTokensV2" mode="updated" /%} -->
## What is a Decentralized Exchange?
@@ -43,7 +45,7 @@ The XRP Ledger's CLOB DEX is unique in that it does **not require** AMMs to swap
## DEX Structure
The XRP Ledger's decentralized exchange consists of an unlimited number of currency pairs, tracked on-demand when users make trades. A currency pair can consist of XRP and a token or two different tokens; tokens are always identified by the combination of an issuer and a currency code. It is possible to trade between two tokens with the same currency code and different issuers, or the same issuer and different currency codes. <!-- STYLE_OVERRIDE: limited number -->
The XRP Ledger's decentralized exchange consists of an unlimited number of currency pairs, tracked on-demand when users make trades. A currency pair can consist of XRP and a token or two different tokens. Trust line tokens are identified by the combination of an issuer and a currency code. Multi-Purpose Tokens (MPTs) are identified by a unique `mpt_issuance_id`. You can trade between any combination of XRP, trust line tokens, and MPTs. <!-- STYLE_OVERRIDE: limited number -->
As with all changes to the XRP Ledger, you need to send a [transaction](../../transactions/index.md) to make a trade. A trade in the XRP Ledger is called an [Offer](offers.md). An Offer is effectively a [_limit order_](https://en.wikipedia.org/wiki/Order_(exchange)#Limit_order) to buy or sell a specific amount of one currency (XRP or a token) for a specific amount of another. When the network executes an Offer, if there are any matching Offers for the same currency pair, they are consumed starting with the best exchange rate first.
@@ -80,12 +82,14 @@ Because trades are only executed each time a new ledger closes (approximately ev
The XRP Ledger does not natively represent concepts such as market orders, stop orders, or trading on leverage. Some of these may be possible with creative use of custom tokens and Offer properties.
As a decentralized system, the XRP Ledger does not have any personal information on the actual people and organizations behind the [accounts](../../accounts/index.md) involved in trading. The ledger itself cannot implement restrictions around who can or cannot participate in trading, and users and issuers must take care to follow any relevant laws to regulate trading tokens that represent various types of underlying assets. Features such as [freezes](../fungible-tokens/freezes.md) and [authorized trust lines](../fungible-tokens/authorized-trust-lines.md) are intended to help issuers comply with relevant laws and regulations.
As a decentralized system, the XRP Ledger does not have any personal information on the actual people and organizations behind the [accounts](../../accounts/index.md) involved in trading. The ledger itself cannot implement restrictions around who can or cannot participate in trading, and users and issuers must take care to follow any relevant laws to regulate trading tokens that represent various types of underlying assets. The following features help issuers comply with relevant laws and regulations:
- Trust line tokens can use **[Freezes](../fungible-tokens/freezes.md)** to freeze balances globally or individually, and **[Authorized Trust Lines](../fungible-tokens/authorized-trust-lines.md)** to require holders to be approved.
- MPTs can use the **[Can Lock](../fungible-tokens/multi-purpose-tokens.md#compliance-controls)** flag to freeze balances globally or per-holder, and **[Require Auth](../fungible-tokens/multi-purpose-tokens.md#transferability-controls)** to require holders to be approved.
## See Also
- **Concepts:**
- See [Offers](offers.md) for details on how trades work in the XRP Ledger.
- See [Tokens](../index.md) for an overview of how various types of value can be represented in the XRP Ledger.
- **References:**
- [account_offers method][] to look up Offers placed by an account

View File

@@ -8,7 +8,7 @@ labels:
---
# Offers
In the XRP Ledger's [decentralized exchange](index.md), trade orders are called "Offers". Offers can trade XRP with [tokens](../index.md), or tokens for other tokens, including tokens with the same currency code but different issuers. (Tokens with the same code but different issuers can also sometimes be exchanged through [rippling](../fungible-tokens/rippling.md).)
In the XRP Ledger's [decentralized exchange](index.md), trade orders are called "Offers". Offers can trade XRP with [tokens](../index.md), or tokens for other tokens. For Trust Line Tokens, this includes tokens with the same currency code but different issuers, which can also sometimes be exchanged through [rippling](../fungible-tokens/rippling.md). For MPTs, each issuance has a unique `mpt_issuance_id`, so different MPTs can be traded against each other.
- To create an Offer, send an [OfferCreate transaction][].
- Offers that aren't fully filled immediately become [Offer objects](../../../references/protocol/ledger-data/ledger-entry-types/offer.md) in the ledger data. Later Offers and Payments can consume the Offer object from the ledger.
@@ -41,7 +41,7 @@ When you try to place an Offer, the transaction is rejected as "unfunded" if you
However, you don't need to hold the full amount specified in the Offer. Placing an Offer does not lock up your funds, so you can place multiple Offers to sell the same tokens (or XRP), or place an Offer and hope to get enough tokens or XRP to fully fund it later.
**To sell XRP,** you must hold enough XRP to meet all the [reserve requirements](../../accounts/reserves.md), including the reserve for the Offer object to be placed in the ledger and for the trust line to hold the token you are buying. As long as you have any XRP left over after setting aside the reserve amount, you can place the Offer.
**To sell XRP,** you must hold enough XRP to meet all the [reserve requirements](../../accounts/reserves.md), including the reserve for the Offer object to be placed in the ledger and for the trust line or MPToken object to hold the token you are buying. As long as you have any XRP left over after setting aside the reserve amount, you can place the Offer.
When another Offer matches yours, both Offers execute to the extent that their owners' funds allow at the the time. If there are matching Offers and you run out of funds before yours is fully filled, the rest of your Offer is canceled. An Offer can't make your balance of a token negative, unless you are the issuer of that token. (If you are the issuer, you can use Offers to issue new tokens up to the total amount specified in your Offers; tokens you issue are represented as negative balances from your perspective.)
@@ -51,9 +51,15 @@ It is possible for an Offer to become temporarily or permanently _unfunded_ in t
- If the owner no longer has any of the sell asset.
- The Offer becomes funded again when the owner obtains more of that asset.
- If the sell asset is a token in a [frozen trust line](../fungible-tokens/freezes.md).
- If the sell asset is a Trust Line Token in a [frozen trust line](../fungible-tokens/freezes.md).
- The Offer becomes funded again when the trust line is no longer frozen.
- If the Offer needs to create a new trust line, but the owner does not have enough XRP for the increased [reserve](../../accounts/reserves.md). (See [Offers and Trust](#offers-and-trust).)
- If the sell asset is an MPT and the holder's [MPToken object is locked](../../../concepts/tokens/fungible-tokens/deep-freeze#how-does-mpt-freezelock-behavior-differ-from-iou).
- The Offer becomes funded again when the MPToken is unlocked.
- If the sell asset is an MPT and the **Can Transfer** flag is cleared on the MPT Issuance.
- The Offer cannot become funded unless the issuer enables the **Can Transfer** flag.
- If the sell asset is an MPT and the **Can Trade** flag is cleared on the MPT Issuance.
- The Offer cannot become funded unless the issuer enables the **Can Trade** flag.
- If the Offer needs to create a new trust line or MPToken object, but the owner does not have enough XRP for the increased [reserve](../../accounts/reserves.md). (See [Offers and Trust](#offers-and-trust).)
- The offer becomes funded again when the owner obtains more XRP, or the reserve requirements decrease.
- If the Offer is expired. (See [Offer Expiration](#offer-expiration).)
@@ -74,11 +80,14 @@ A client application can locally track the funding status of Offers. To do this,
## Offers and Trust
The limit values of [trust lines](../fungible-tokens/index.md) do not affect Offers. In other words, you can use an Offer to acquire more than the maximum amount you trust an issuer for.
Before you can hold a token, you need a ledger object to track your balance:
However, holding tokens still requires a trust line to the issuer. When an Offer is consumed, it automatically creates any necessary trust lines, setting their limits to 0. Because [trust lines increase the reserve an account must hold](../../accounts/reserves.md), any Offers that would require a new trust line also require the address to have enough XRP to meet the reserve for that trust line.
- **Trust Line Tokens** require a [trust line](../fungible-tokens/index.md) to the issuer.
- **MPTs** require an [MPToken object](../fungible-tokens/multi-purpose-tokens.md).
Trust line limits protect you from receiving more of a token as payment than you want. Offers can go beyond those limits because they are an explicit statement of how much of the token you want.
When an Offer is consumed, the ledger automatically creates the necessary trust line or MPToken object if one doesn't exist. Trust lines created this way have their limit set to 0. Because these objects count toward your [reserve requirement](../../accounts/reserves.md), any Offer that would create a new trust line or MPToken object also requires enough XRP to cover the additional reserve.
Trust lines have a configurable limit that caps how much of a token you're willing to receive as payment. However, Offers can exceed this limit because placing an Offer is an explicit statement of how much you want. MPTs do not have per-holder limits—only an issuance-wide [supply cap](../fungible-tokens/multi-purpose-tokens.md#supply-cap).
## Offer Preference

View File

@@ -9,11 +9,27 @@ labels:
---
# Tick Size
When an Offer is placed into an order book, its exchange rate is truncated based on the `TickSize` values set by the issuers of the currencies involved in the Offer. When trading XRP and a token, the `TickSize` from the token's issuer applies. When trading two tokens, the Offer uses the smaller `TickSize` value (that is, the one with fewer significant digits). If neither token has a `TickSize` set, the default behavior applies.
When an Offer is placed into an order book, its exchange rate is truncated based on the `TickSize` values set by the issuers of the Trust Line Tokens involved in the Offer. Unlike tick sizes in traditional finance, the XRP Ledger's `TickSize` applies to the **exchange rate's significant digits**, not the trade amounts directly. After truncating the exchange rate, the ledger recalculates one of the amounts to match the new rate:
The `TickSize` value truncates the number of _significant digits_ in the exchange rate of an offer when it gets placed in an order book. Issuers can set `TickSize` to an integer from `3` to `15` using an [AccountSet transaction][]. The exchange rate is represented as significant digits and an exponent; the `TickSize` does not affect the exponent. This allows the XRP Ledger to represent exchange rates between assets that vary greatly in value (for example, a highly inflated currency compared to a rare commodity). The lower the `TickSize` an issuer sets, the larger the increment traders must offer to be considered a higher exchange rate than the existing Offers.
- **Buy offers** recalculate the `TakerGets` amount.
- **Sell offers** recalculate the `TakerPays` amount.
The `TickSize` does not affect the part of an Offer that can be executed immediately. (For that reason, OfferCreate transactions with `tfImmediateOrCancel` are unaffected by `TickSize` values.) If the Offer cannot be fully executed, the transaction processing engine calculates the exchange rate and truncates it based on `TickSize`. Then, the engine rounds the remaining amount of the Offer from the "less important" side to match the truncated exchange rate. For a default OfferCreate transaction (a "buy" Offer), the `TakerPays` amount (the amount being bought) gets rounded. If the `tfSell` flag is enabled (a "sell" Offer) the `TakerGets` amount (the amount being sold) gets rounded.
Because buy and sell offers adjust different sides, two offers that appear to have matching prices may not actually cross. This can be more problematic than the price discovery issues that `TickSize` is meant to solve.
{% admonition type="warning" name="Warning" %}
Consider carefully whether your use case benefits from a `TickSize`. In particular, stablecoins and other currency-like tokens may be better off without one, since they trade in narrow price ranges where precise matching matters more than preventing competitive price improvements.
{% /admonition %}
The `TickSize` that applies depends on the assets being traded:
- **XRP and a Trust Line Token**: The `TickSize` from the Trust Line Token's issuer applies. Either amount may be adjusted based on buy/sell direction.
- **MPT and a Trust Line Token**: The `TickSize` from the Trust Line Token's issuer applies, and only the Trust Line Token amount is adjusted (MPT amounts are never adjusted for tick size).
- **Two Trust Line Tokens**: The smaller `TickSize` value (fewer significant digits) is used. If neither issuer has set a `TickSize`, no truncation occurs.
- **XRP/MPT or MPT/MPT**: No truncation occurs. XRP and MPT do not support `TickSize`.
Trust Line Token issuers can set `TickSize` to an integer from `3` to `15` using an [AccountSet transaction][]. The exchange rate is represented as significant digits and an exponent; the `TickSize` does not affect the exponent. This allows the XRP Ledger to represent exchange rates between assets that vary greatly in value (for example, a highly inflated currency compared to a rare commodity). The lower the `TickSize` an issuer sets, the larger the increment traders must offer to be considered a higher exchange rate than the existing Offers.
The `TickSize` does not affect the part of an Offer that can be executed immediately. (For that reason, OfferCreate transactions with `tfImmediateOrCancel` are unaffected by `TickSize` values.)
When an issuer enables, disables, or changes the `TickSize`, Offers that were placed under the previous setting are unaffected.

View File

@@ -54,7 +54,6 @@ If you are creating a new token on the XRP Ledger, it may be confusing that ther
- For most new tokens, MPTs are preferred.
- Specific cases where you might prefer trust line tokens include:
- If you need **compatibility with the DEX**. <!-- Note: revisit this when MPT DEX compatibility is closer to being available. -->
- Your use case is **community credit**.
- You need compatibility with legacy software, such as an integration that already works with trust line tokens.
- You need to be able to represent very large and very small quantities of the same token (20 orders of magnitude apart).

View File

@@ -139,7 +139,9 @@ MPTs can be configured with different levels of transferability controls by adju
- **Can Transfer:** If this flag is enabled, holders can transfer the token to each other. Otherwise, the MPT is non-transferable, meaning it can only be sent directly back to the issuer.
- **Require Auth:** If this flag is enabled, holders must get explicit approval from the issuer before they can hold this token—in other words, it uses allow-listing. Otherwise, anyone can hold the token if they are willing.
- **Can Trade:** If this flag is enabled, holders are allowed to trade the token in the decentralized exchange. However, trading MPTs in the DEX is not currently implemented.
- **Can Trade:** If this flag is enabled, holders can trade the token on the [Decentralized Exchange (DEX)](../decentralized-exchange/index.md). **Can Transfer** must also be enabled, since non-transferable tokens cannot be traded. When **Can Trade** is disabled, the issuer can only directly receive tokens from holders.
_(Requires the [MPTokensV2 amendment](https://xls.xrpl.org/xls/XLS-0082-mpt-dex.html) {% not-enabled /%})_
<!-- {% amendment-disclaimer name="MPTokensV2" mode="updated" /%} -->
- **Can Escrow:** If this flag is enabled, holders are allowed to place the token in escrow. Otherwise, the token cannot be escrowed. {% amendment-disclaimer name="TokenEscrow" /%}
### Supply Cap

View File

@@ -7,20 +7,20 @@ labels:
---
# Paths
In the XRP Ledger, paths define a way for [trust line tokens](trust-line-tokens.md) to flow through intermediary steps as part of a payment. Paths enable [cross-currency payments](../../payment-types/cross-currency-payments.md) by connecting sender and receiver through orders and [automated market makers (AMM)](../../../concepts/tokens/decentralized-exchange/automated-market-makers.md) in the XRP Ledger's [decentralized exchange](../decentralized-exchange/index.md). Paths also enable complex settlement of offsetting debts.
In the XRP Ledger, paths define a way for [tokens](../index.md) to flow through intermediary steps as part of a payment. Paths enable [cross-currency payments](../../payment-types/cross-currency-payments.md) by connecting sender and receiver through orders and [automated market makers (AMM)](../../../concepts/tokens/decentralized-exchange/automated-market-makers.md) in the XRP Ledger's [decentralized exchange](../decentralized-exchange/index.md). Paths also enable complex settlement of offsetting debts.
A single Payment transaction in the XRP Ledger can use multiple paths, combining liquidity from different sources to deliver the desired amount. Thus, a transaction includes a _path set_, which is a collection of possible paths to take. All paths in a path set must start with the same currency, and must also end with the same currency as each other.
[XRP-to-XRP transactions](../../payment-types/direct-xrp-payments.md) and MPT transfers are always sent directly, and do not use any paths.
[XRP-to-XRP transactions](../../payment-types/direct-xrp-payments.md) are always sent directly and do not use paths. MPT-to-MPT transfers of the same issuance are also direct, but MPTs can be included in paths for cross-currency payments.
## Path Steps
A path is made of steps that connect the sender to the receiver of the payment. Every step is either:
* Rippling through another address with the same currency.
* Rippling through another address with the same currency (Trust Line Tokens only).
* Trading tokens or XRP using an order book or AMM.
[Rippling](rippling.md) is the process of exchanging equivalent tokens using the same currency code. In the typical case, rippling through an issuer involves reducing the tokens issued to one party and increasing the tokens issued to another party by an equal amount. The path step specifies which account to ripple through.
[Rippling](rippling.md) is the process of exchanging equivalent Trust Line Tokens using the same currency code. In the typical case, rippling through an issuer involves reducing the tokens issued to one party and increasing the tokens issued to another party by an equal amount. The path step specifies which account to ripple through.
[Trading tokens and possibly XRP](../decentralized-exchange/index.md) involves going to an order book or AMM and finding the best exchange rate between the assets involved for the amount being sent. The path step specifies which currency to change to, but does not record the state of the Offers in the order book. The canonical order of transactions is not final until a ledger is validated, so you cannot know for certain which Offers or AMMs a transaction will take, until after the transaction has been validated. (You can make an educated guess, since each transaction takes the best available exchange rates at the time it executes in the final ledger.) <!-- STYLE_OVERRIDE: will -->
@@ -78,9 +78,10 @@ A path set is an array. Each member of the path set is another array that repres
| Field | Value | Description |
|:-----------|:-----------------------|:---------------------------------------|
| `account` | String - Address | _(Optional)_ If present, this path step represents rippling through the specified address. MUST NOT be provided if this step specifies the `currency` or `issuer` fields. |
| `currency` | String - Currency Code | _(Optional)_ If present, this path step represents changing currencies through an order book or AMM. The currency specified indicates the new currency. MUST NOT be provided if this step specifies the `account` field. |
| `issuer` | String - Address | _(Optional)_ If present, this path step represents changing currencies and this address defines the issuer of the new currency. If omitted in a step with a non-XRP `currency`, a previous step of the path defines the issuer. If present when `currency` is omitted, indicates a path step that uses an order book or AMM between same-named currencies with different issuers. MUST be omitted if the `currency` is XRP. MUST NOT be provided if this step specifies the `account` field. |
| `account` | String - Address | _(Optional)_ If present, this path step represents rippling through the specified address. MUST NOT be provided if this step specifies the `currency`, `issuer`, or `mpt_issuance_id` fields. |
| `currency` | String - Currency Code | _(Optional)_ If present, this path step represents changing currencies through an order book or AMM. The currency specified indicates the new currency. MUST NOT be provided if this step specifies the `account` or `mpt_issuance_id` field. |
| `issuer` | String - Address | _(Optional)_ If present, this path step represents changing currencies and this address defines the issuer of the new currency. If omitted in a step with a non-XRP `currency`, a previous step of the path defines the issuer. If present when `currency` is omitted, indicates a path step that uses an order book or AMM between same-named currencies with different issuers. MUST be omitted if the `currency` is XRP. MUST NOT be provided if this step specifies the `account` or `mpt_issuance_id` field. |
| `mpt_issuance_id` | String | _(Optional)_ If present, this path step represents changing to an MPT through an order book or AMM. MUST NOT be provided if this step specifies the `account`, `currency`, or `issuer` fields. |
| `type` | Integer | **DEPRECATED** _(Optional)_ An indicator of which other fields are present. |
| `type_hex` | String | **DEPRECATED**: _(Optional)_ A hexadecimal representation of the `type` field. |
@@ -90,8 +91,9 @@ In summary, the following combination of fields are valid, optionally with `type
- `currency` by itself
- `currency` and `issuer` as long as the `currency` is not XRP
- `issuer` by itself
- `mpt_issuance_id` by itself
Any other use of `account`, `currency`, and `issuer` fields in a path step is invalid.
Any other use of `account`, `currency`, `issuer`, and `mpt_issuance_id` fields in a path step is invalid.
The `type` field, used for the binary serialization of a path set, is actually constructed through bitwise operations on a single integer. The bits are defined as follows:
@@ -100,6 +102,7 @@ The `type` field, used for the binary serialization of a path set, is actually c
| `0x01` | 1 | A change of address (rippling): the `account` field is present. |
| `0x10` | 16 | A change of currency: the `currency` field is present. |
| `0x20` | 32 | A change of issuer: the `issuer` field is present. |
| `0x40` | 64 | A change to an MPT: the `mpt_issuance_id` field is present. |
## See Also

View File

@@ -182,6 +182,7 @@ rippled json ledger_entry '{ "amendments": "7DB0788C020F02780A673DC74757F23823FA
<a id="get-amm-object"></a><!-- legacy ID -->
{% amendment-disclaimer name="AMM" /%}
<!-- {% amendment-disclaimer name="MPTokensV2" mode="updated" /%} -->
Retrieve an Automated Market-Maker (AMM) object from the ledger. This is similar to [amm_info method][], but the `ledger_entry` version returns only the ledger entry as stored.
@@ -240,6 +241,24 @@ rippled json ledger_entry '{ "amm": { "asset": { "currency": "XRP" }, "asset2":
```
{% /tab %}
{% tab label="WebSocket - MPT" %}
```json
{
"id": 3,
"command": "ledger_entry",
"amm": {
"asset": {
"mpt_issuance_id": "000000045C488AAC5813270850685FFD89F4A4A8F4CD4C83"
},
"asset2": {
"mpt_issuance_id": "000000055C488AAC5813270850685FFD89F4A4A8F4CD4C83"
}
},
"ledger_index": "validated"
}
```
{% /tab %}
{% /tabs %}
{% try-it method="ledger_entry-amm" server="testnet" /%}

View File

@@ -12,6 +12,7 @@ labels:
The {% code-page-name /%} method gets information about an [Automated Market Maker (AMM)](/docs/concepts/tokens/decentralized-exchange/automated-market-makers) instance.
{% amendment-disclaimer name="AMM" /%}
<!-- {% amendment-disclaimer name="MPTokensV2" mode="updated" /%} -->
### Request Format
@@ -64,8 +65,8 @@ The request includes the following parameters:
|:--------------|:-----------------|:----------|-------------|
| `account` | String - [Address][] | No | Show only LP Tokens held by this liquidity provider. |
| `amm_account` | String - [Address][] | No | The address of the AMM's special AccountRoot. (This is the `issuer` of the AMM's LP Tokens.) |
| `asset` | Object | No | One of the assets of the AMM to look up, as an object with `currency` and `issuer` fields (omit `issuer` for XRP), like [currency amounts][Currency Amount]. |
| `asset2` | Object | No | The other of the assets of the AMM, as an object with `currency` and `issuer` fields (omit `issuer` for XRP), like [currency amounts][Currency Amount]. |
| `asset` | Object | No | One of the assets of the AMM to look up. For Trust Line Tokens, use an object with `currency` and `issuer` fields (omit `issuer` for XRP). For MPTs, use an object with `mpt_issuance_id` field. |
| `asset2` | Object | No | The other of the assets of the AMM. For Trust Line Tokens, use an object with `currency` and `issuer` fields (omit `issuer` for XRP). For MPTs, use an object with `mpt_issuance_id` field. |
You must specify _either_ `amm_account` or both `asset` and `asset2`.

View File

@@ -8,6 +8,8 @@ labels:
# book_offers
[[Source]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/rpc/handlers/BookOffers.cpp "Source")
<!-- {% amendment-disclaimer name="MPTokensV2" mode="updated" /%} -->
The `book_offers` method retrieves a list of [offers](../../../../concepts/tokens/decentralized-exchange/offers.md) between two currencies, also known as an _order book_. The response omits [unfunded offers](../../../../concepts/tokens/decentralized-exchange/offers.md#lifecycle-of-an-offer) and reports how much of each remaining offer's total is currently funded.
## Request Format

View File

@@ -22,6 +22,8 @@ There are three different modes, or sub-commands, of the path_find command. Spec
Although the `rippled` server tries to find the cheapest path or combination of paths for making a payment, it is not guaranteed that the paths returned by this method are, in fact, the best paths. Due to server load, pathfinding may not find the best results. Additionally, you should be careful with the pathfinding results from untrusted servers. A server could be modified to return less-than-optimal paths to earn money for its operators. If you do not have your own server that you can trust with pathfinding, you should compare the results of pathfinding from multiple servers run by different parties, to minimize the risk of a single server returning poor results. (**Note:** A server returning less-than-optimal results is not necessarily proof of malicious behavior; it could also be a symptom of heavy server load.)
<!-- {% amendment-disclaimer name="MPTokensV2" mode="updated" /%} -->
## path_find create
The `create` sub-command of `path_find` creates an ongoing request to find possible paths along which a payment transaction could be made from one specified account such that another account receives a desired amount of some currency. The initial response contains a suggested path between the two addresses that would result in the desired amount being received. After that, the server sends additional messages, with `"type": "path_find"`, with updates to the potential paths. The frequency of updates is left to the discretion of the server, but it usually means once every few seconds when there is a new ledger version.
@@ -33,7 +35,7 @@ An example of the request format:
{% tabs %}
{% tab label="WebSocket" %}
{% tab label="WebSocket - Trust Line Token" %}
```json
{
"id": 8,
@@ -50,6 +52,22 @@ An example of the request format:
```
{% /tab %}
{% tab label="WebSocket - MPT" %}
```json
{
"command": "path_find",
"subcommand": "create",
"destination_account": "rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK",
"destination_amount": {
"mpt_issuance_id": "000000045C488AAC5813270850685FFD89F4A4A8F4CD4C83",
"value": "-1"
},
"send_max": "100000000000000",
"source_account": "rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn"
}
```
{% /tab %}
{% /tabs %}
{% try-it method="path_find" /%}
@@ -61,10 +79,10 @@ The request includes the following parameters:
| `subcommand` | String | Yes | Use `"create"` to send the create sub-command |
| `source_account` | String - [Address][] | Yes | The account to find a path from. (In other words, the account that would be sending a payment.) |
| `destination_account` | String - [Address][] | Yes | The account to find a path to. (In other words, the account that would receive a payment.) |
| `destination_amount` | [Currency Amount][] | Yes | How much the destination account would receive. **Special case:** You can specify `"-1"` (for XRP) or provide -1 as the contents of the `value` field (for tokens). This requests a path to deliver as much as possible, while spending no more than the amount specified in `send_max` (if provided). |
| `destination_amount` | [Currency Amount][] | Yes | How much the destination account would receive. Can be XRP or a fungible token. **Special case:** You can specify `"-1"` (for XRP) or provide -1 as the contents of the `value` field (for tokens). This requests a path to deliver as much as possible, while spending no more than the amount specified in `send_max` (if provided). |
| `domain` | String - [Hash][] | No | The ledger entry ID of a permissioned domain. If provided, only return paths that use the corresponding [permissioned DEX](../../../../concepts/tokens/decentralized-exchange/permissioned-dexes.md). {% amendment-disclaimer name="PermissionedDEX" /%} |
| `paths` | Array | No | Array of arrays of objects, representing [payment paths](../../../../concepts/tokens/fungible-tokens/paths.md) to check. You can use this to keep updated on changes to particular paths you already know about, or to check the overall cost to make a payment along a certain path. |
| `send_max` | [Currency Amount][] | No | Maximum amount that would be spent. Not compatible with `source_currencies`. |
| `send_max` | [Currency Amount][] | No | Maximum amount that would be spent. Can be XRP or a fungible token. Not compatible with `source_currencies`. |
The server also recognizes the following fields, but the results of using them are not guaranteed: `source_currencies`, `bridges`. These fields should be considered reserved for future use.
@@ -74,10 +92,41 @@ An example of a successful response:
{% tabs %}
{% tab label="WebSocket" %}
{% tab label="WebSocket - Trust Line Token" %}
{% code-snippet file="/_api-examples/path_find/create-response.json" /%}
{% /tab %}
{% tab label="WebSocket - MPT" %}
```json
{
"id": 1,
"result": {
"alternatives": [
{
"paths_computed": [
[
{
"mpt_issuance_id": "000000045C488AAC5813270850685FFD89F4A4A8F4CD4C83"
}
]
],
"source_amount": "100000000"
}
],
"destination_account": "rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK",
"destination_amount": {
"mpt_issuance_id": "000000045C488AAC5813270850685FFD89F4A4A8F4CD4C83",
"value": "100"
},
"full_reply": true,
"source_account": "rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn"
},
"status": "success",
"type": "response"
}
```
{% /tab %}
{% /tabs %}
The initial response follows the [standard format](../../api-conventions/response-formatting.md), with a successful result containing the following fields:

View File

@@ -8,6 +8,8 @@ labels:
# ripple_path_find
[[Source]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/rpc/handlers/RipplePathFind.cpp "Source")
<!-- {% amendment-disclaimer name="MPTokensV2" mode="updated" /%} -->
The `ripple_path_find` method is a simplified version of the [path_find method][] that provides a single response with a [payment path](../../../../concepts/tokens/fungible-tokens/paths.md) you can use right away. It is available in both the WebSocket and JSON-RPC APIs. However, the results tend to become outdated as time passes. Instead of making multiple calls to stay updated, you should instead use the [path_find method][] to subscribe to continued updates where possible.
Although the `rippled` server tries to find the cheapest path or combination of paths for making a payment, it is not guaranteed that the paths returned by this method are, in fact, the best paths.
@@ -77,6 +79,21 @@ rippled ripple_path_find '{"source_account": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59
```
{% /tab %}
{% tab label="WebSocket - MPT" %}
```json
{
"command": "ripple_path_find",
"destination_account": "rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK",
"destination_amount": {
"mpt_issuance_id": "000000045C488AAC5813270850685FFD89F4A4A8F4CD4C83",
"value": "-1"
},
"send_max": "100000000000000",
"source_account": "rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn"
}
```
{% /tab %}
{% /tabs %}
{% try-it method="ripple_path_find" /%}
@@ -92,7 +109,7 @@ The request includes the following parameters:
| `ledger_hash` | String - [Hash][] | No | The unique hash of the ledger version to use. (See [Specifying Ledgers][]) |
| `ledger_index` | [Ledger Index][] | No | The ledger index of the ledger to use, or a shortcut string to choose a ledger automatically. (See [Specifying Ledgers][]) |
| `send_max` | [Currency Amount][] | No | Maximum amount that would be spent. Cannot be used with `source_currencies`. |
| `source_currencies` | Array | No | Array of currencies that the source account might want to spend. Each entry in the array should be a JSON object with a mandatory `currency` field and optional `issuer` field, like how [currency amounts][Currency Amount] are specified. Cannot contain more than **18** source currencies. By default, uses all source currencies available up to a maximum of **88** different currency/issuer pairs. |
| `source_currencies` | Array | No | Array of currencies that the source account might want to spend. Each entry in the array should be a JSON object with a mandatory `currency` field and optional `issuer` field (for Trust Line Tokens) or `mpt_issuance_id` field (for MPTs), like how [currency amounts][Currency Amount] are specified. Cannot contain more than **18** source currencies. By default, uses all source currencies available up to a maximum of **88** different currency/issuer pairs. |
## Response Format

View File

@@ -356,18 +356,22 @@ Each path consists of **1 to 8** path steps in order[[Source]](https://github.co
The following table describes the possible fields and the bitwise flags to set in the type byte to indicate them:
| Type Flag | Field Present | Field Type | Bit Size | Order |
|:----------|:--------------|:------------------|:---------|:------|
| `0x01` | `account` | [AccountID][] | 160 bits | 1st |
| `0x10` | `currency` | [Currency Code][] | 160 bits | 2nd |
| `0x20` | `issuer` | [AccountID][] | 160 bits | 3rd |
| Type Flag | Field Present | Field Type | Bit Size | Order |
|:----------|:------------------|:---------------------|:---------|:------|
| `0x01` | `account` | [AccountID][] | 160 bits | 1st |
| `0x10` | `currency` | [Currency Code][] | 160 bits | 2nd |
| `0x40` | `mpt_issuance_id` | [MPT Issuance ID][] | 192 bits | 2nd |
| `0x20` | `issuer` | [AccountID][] | 160 bits | 3rd |
[Currency Code]: data-types/currency-formats.md#standard-currency-codes
[MPT Issuance ID]: ledger-data/ledger-entry-types/mptokenissuance.md#mptokenissuanceid
Some combinations are invalid; see [Path Specifications](../../concepts/tokens/fungible-tokens/paths.md#path-specifications) for details.
The AccountIDs in the `account` and `issuer` fields are presented _without_ a length prefix. When the `currency` is XRP, the currency code is represented as 160 bits of zeroes.
The `currency` and `mpt_issuance_id` fields are mutually exclusive. A path step can contain either a `currency` or an `mpt_issuance_id`, but not both. Both occupy the 2nd position in the serialization order when present.
Each step is followed directly by the next step of the path. As described above, the last step of a path is followed by either `0xff` (if another path follows) or `0x00` (if this ends the last path).
The following example shows the serialization format for a PathSet:

View File

@@ -120,7 +120,7 @@ XRP is specified as a string containing an integer number of "drops" of XRP, whe
"Amount": "13100000"
```
- **Token** - To specify an `Amount` field with a value of 13.1 FOO issued by or to `rf1B...`:
- **Trust Line Token** - To specify an `Amount` field with a value of 13.1 FOO issued by or to `rf1B...`:
```
"Amount": {

View File

@@ -7,9 +7,10 @@ labels:
# AMM
[[Source]](https://github.com/XRPLF/rippled/blob/f64cf9187affd69650907d0d92e097eb29693945/include/xrpl/protocol/detail/ledger_entries.macro#L369-L380 "Source")
An `AMM` ledger entry describes a single [Automated Market Maker](../../../../concepts/tokens/decentralized-exchange/automated-market-makers.md) (AMM) instance. This is always paired with a [special AccountRoot entry](accountroot.md#special-amm-accountroot-entries). You can create an AMM by sending an [AMMCreate transaction][].
An `AMM` ledger entry describes a single [Automated Market Maker](../../../../concepts/tokens/decentralized-exchange/automated-market-makers.md) (AMM) instance. This is always paired with a [special AccountRoot entry](accountroot.md#special-amm-accountroot-pseudo-account). You can create an AMM by sending an [AMMCreate transaction][].
{% amendment-disclaimer name="AMM" /%}
<!-- {% amendment-disclaimer name="MPTokensV2" mode="updated" /%} -->
## Example AMM JSON
@@ -63,8 +64,8 @@ In addition to the [common fields](../common-fields.md), {% code-page-name /%} e
| Field | JSON Type | [Internal Type][] | Required? | Description |
|:-----------------|:--------------------|:------------------|:----------|--------------|
| `Asset` | Object | Issue | Yes | The definition for one of the two assets this AMM holds. In JSON, this is an object with `currency` and `issuer` fields. |
| `Asset2` | Object | Issue | Yes | The definition for the other asset this AMM holds. In JSON, this is an object with `currency` and `issuer` fields. |
| `Asset` | Object | Issue | Yes | The definition for one of the two assets this AMM holds, as a [currency without an amount](../../data-types/currency-formats.md#specifying-without-amounts). |
| `Asset2` | Object | Issue | Yes | The definition for the other asset this AMM holds, as a [currency without an amount](../../data-types/currency-formats.md#specifying-without-amounts). |
| `Account` | String - [Address][] | AccountID | Yes | The address of the [special account](accountroot.md#special-amm-accountroot-entries) that holds this AMM's assets. |
| `AuctionSlot` | Object | Object | No | Details of the current owner of the auction slot, as an [Auction Slot object](#auction-slot-object). |
| `LPTokenBalance` | [Currency Amount][] | Amount | Yes | The total outstanding balance of liquidity provider tokens from this AMM instance. The holders of these tokens can vote on the AMM's trading fee in proportion to their holdings, or redeem the tokens for a share of the AMM's assets which grows with the trading fees collected. |

View File

@@ -109,9 +109,10 @@ All types of directories are automatically updated by the protocol as necessary.
| `RootIndex` | String | UInt256 | Yes | The ID of root object for this directory. |
| `TakerGetsCurrency` | String | UInt160 | No | (Offer directories only) The currency code of the `TakerGets` amount from the offers in this directory. |
| `TakerGetsIssuer` | String | UInt160 | No | (Offer directories only) The issuer of the `TakerGets` amount from the offers in this directory. |
| `TakerGetsMPT` | String | UInt192 | No | (Offer directories only) The `mpt_issuance_id` of the `TakerGets` amount from the offers in this directory. {% amendment-disclaimer name="MPTokensV2" /%} |
| `TakerPaysCurrency` | String | UInt160 | No | (Offer directories only) The currency code of the `TakerPays` amount from the offers in this directory. |
| `TakerPaysIssuer` | String | UInt160 | No | (Offer directories only) The issuer of the `TakerPays` amount from the offers in this directory. |
| `TakerPaysMPT` | String | UInt192 | No | (Offer directories only) The `mpt_issuance_id` of the `TakerPays` amount from the offers in this directory. {% amendment-disclaimer name="MPTokensV2" /%} |
## {% $frontmatter.seo.title %} Flags

View File

@@ -10,6 +10,7 @@ status: not_enabled
An `MPToken` entry tracks [MPTs](../../../../concepts/tokens/fungible-tokens/multi-purpose-tokens.md) held by an account that is not the token issuer. You can create or delete an empty `MPToken` entry by sending an [MPTokenAuthorize transaction][]. You can send and receive MPTs using several other transaction types including [Payment][] and [OfferCreate][] transactions.
{% amendment-disclaimer name="MPTokensV1" /%}
<!-- {% amendment-disclaimer name="MPTokensV2" mode="updated" /%} -->
## Example MPToken JSON
@@ -46,7 +47,7 @@ In addition to the [common fields](../common-fields.md), {% code-page-name /%} e
|:------------------|:-----------|:--------------------------------------------|
| `lsfMPTLocked` | `0x00000001` | If enabled, indicates that the MPT owned by this account is currently locked and cannot be used in any XRP transactions other than sending value back to the issuer. |
| `lsfMPTAuthorized` | `0x00000002` | (Only applicable for allow-listing) If set, indicates that the issuer has authorized the holder for the MPT. This flag can be set using a `MPTokenAuthorize` transaction; it can also be "un-set" using a `MPTokenAuthorize` transaction specifying the `tfMPTUnauthorize` flag. |
| `lsfMPTAMM` | `0x00000004` | This MPToken is owned by an [Automated Market Maker](../../../../concepts/tokens/decentralized-exchange/automated-market-makers.md)'s pseudo-account. |
## MPToken ID Format

View File

@@ -11,6 +11,7 @@ An `Offer` ledger entry describes an [offer](../../../../concepts/tokens/decentr
An offer can become unfunded through other activities in the network, while remaining in the ledger. When processing transactions, the network automatically removes any unfunded Offers that those transactions come across. (Otherwise, unfunded Offers remain, because _only_ transactions can change the ledger state.)
<!-- {% amendment-disclaimer name="MPTokensV2" mode="updated" /%} -->
## Example {% $frontmatter.seo.title %} JSON

View File

@@ -11,13 +11,21 @@ labels:
Claw back tokens from a holder who has deposited your issued tokens into an AMM pool.
Clawback is disabled by default. To use clawback, you must send an [AccountSet transaction][] to enable the **Allow Trust Line Clawback** setting. An issuer with any existing tokens cannot enable clawback. You can only enable **Allow Trust Line Clawback** if you have a completely empty owner directory, meaning you must do so before you set up any trust lines, offers, escrows, payment channels, checks, or signer lists. After you enable clawback, it cannot reverted: the account permanently gains the ability to claw back issued assets on trust lines.
Clawback is disabled by default:
- **For Trust Line Tokens:** You must send an [AccountSet transaction][] to enable the **Allow Trust Line Clawback** setting. An issuer with any existing tokens cannot enable clawback. You can only enable **Allow Trust Line Clawback** if you have a completely empty owner directory, meaning you must do so before you set up any trust lines, offers, escrows, payment channels, checks, or signer lists. After you enable clawback, it cannot be reverted: the account permanently gains the ability to claw back issued assets on trust lines.
- **For MPTs:** The MPT issuance must have the **Can Clawback** flag enabled.
{% amendment-disclaimer name="AMMClawback" /%}
<!-- TODO: Add {% amendment-disclaimer name="MPTokensV2" mode="updated" /%} badge. -->
## Example {% $frontmatter.seo.title %} JSON
{% tabs %}
{% tab label="Trust Line Token/Trust Line Token" %}
```json
{
"TransactionType": "AMMClawback",
@@ -38,6 +46,29 @@ Clawback is disabled by default. To use clawback, you must send an [AccountSet t
}
}
```
{% /tab %}
{% tab label="MPT/MPT" %}
```json
{
"TransactionType": "AMMClawback",
"Account": "rPdYxU9dNkbzC5Y2h4jLbVJ3rMRrk7WVRL",
"Holder": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
"Asset": {
"mpt_issuance_id" : "00002403C84A0A28E0190E208E982C352BBD71B2"
},
"Asset2" : {
"mpt_issuance_id" : "00002710D5F38CCE3B43BD597D1B6CCED4AC2D5C"
},
"Amount": {
"mpt_issuance_id" : "00002403C84A0A28E0190E208E982C352BBD71B2",
"value" : "1000"
}
}
```
{% /tab %}
{% /tabs %}
{% raw-partial file="/docs/_snippets/tx-fields-intro.md" /%}
@@ -45,8 +76,8 @@ Clawback is disabled by default. To use clawback, you must send an [AccountSet t
| Field | JSON Type | [Internal Type][] | Required | Description |
|:----------|:---------------------|:------------------|:---------|:------------------|
| `Asset` | Object | Issue | Yes | The asset to claw back, which can be a trust line token or MPT (see: [Specifying Without Amounts][]). The issuer must be the sender of this transaction. |
| `Asset2` | Object | Issue | Yes | The other asset of the AMM pool to claw back from. The asset can be XRP, a trust line token, or an MPT (see: [Specifying Without Amounts][]). |
| `Asset` | Object | Issue | Yes | Specifies the asset that the issuer wants to claw back from the AMM pool. The asset can be XRP, or a fungible token. See [Specifying Without Amounts][]. |
| `Asset2` | Object | Issue | Yes | Specifies the other asset in the AMM's pool. The asset can be XRP or a fungible token. See [Specifying Without Amounts][]. |
| `Amount` | [Currency Amount][] | Amount | No | The maximum amount to claw back from the AMM account. The `currency` and `issuer` subfields should match the `Asset` subfields. If this field isn't specified, or the `value` subfield exceeds the holder's available tokens in the AMM, all of the holder's tokens are clawed back. |
| `Holder` | String - [Address][] | AccountID | Yes | The account holding the asset to be clawed back. |
@@ -64,13 +95,13 @@ Besides errors that can occur for all transactions, `AMMClawback` transactions c
| Error Code | Description |
|:-------------------|:------------|
| `tecNO_PERMISSION` | Occurs if you attempt to claw back tokens from an AMM without the `lsfAllowTrustlineClawback` flag enabled, or the `tfClawTwoAssets` flag is enabled when you didn't issue both assets in the AMM. Also occurs if the `Asset` issuer doesn't match `Account`. |
| `tecAMM_BALANCE` | Occurs if the `Holder` doesn't hold any LP tokens from the AMM pool. |
| `temDISABLED` | Occurs if the [AMMClawback amendment][] is not enabled. |
| `temBAD_AMOUNT` | Occurs if the `Amount` field in the `AMMClawback` transaction is less than or equal to 0, or the `currency` and `issuer` subfields don't match between `Amount` and `Asset`. |
| `temINVALID_FLAG` | Occurs if you try enabling flags besides `tfClawTwoAssets`. |
| `temMALFORMED` | Occurs if the `issuer` subfield doesn't match between `Asset` and `Account`, `Account` is the same as the `Holder`, or `Asset` is XRP. |
| `terNO_AMM` | Occurs if the AMM pool specified by `Asset` and `Asset2` doesn't exist. |
| `tecAMM_BALANCE` | The `Holder` doesn't hold any LP tokens from the AMM pool. |
| `tecNO_PERMISSION` | One of the following might have occurred:<ul><li>For Trust Line Tokens: the issuer account doesn't have the **Allow Trust Line Clawback** flag enabled.</li><li>For MPTs: the MPT issuance doesn't have the **Can Clawback** flag enabled, or the issuer in the MPT issuance doesn't match the `Account` field.</li><li>The `tfClawTwoAssets` flag is enabled but you didn't issue both assets in the AMM.</li></ul> |
| `temDISABLED` | At least one of the assets or the amount is an MPT, but the [MPTokensV2 amendment][] is not enabled. (Also occurs if the [AMMClawback amendment][] is not enabled.) |
| `temBAD_AMOUNT` | The `Amount` field is less than or equal to 0, or the asset in `Amount` doesn't match `Asset`. |
| `temINVALID_FLAG` | You tried enabling flags besides `tfClawTwoAssets`, or `tfClawTwoAssets` is enabled but the two assets don't have the same issuer. |
| `temMALFORMED` | The issuer in `Asset` doesn't match `Account`, `Account` is the same as `Holder`, or `Asset` is XRP. |
| `terNO_AMM` | The AMM pool specified by `Asset` and `Asset2` doesn't exist. |
## See Also

View File

@@ -9,14 +9,18 @@ labels:
Create a new [Automated Market Maker](../../../../concepts/tokens/decentralized-exchange/automated-market-makers.md) (AMM) instance for trading a pair of assets ([fungible tokens](../../../../concepts/tokens/index.md) or [XRP](../../../../introduction/what-is-xrp.md)).
Creates both an [AMM entry][] and a [special AccountRoot entry](../../ledger-data/ledger-entry-types/accountroot.md#special-amm-accountroot-entries) to represent the AMM. Also transfers ownership of the starting balance of both assets from the sender to the created `AccountRoot` and issues an initial balance of liquidity provider tokens (LP Tokens) from the AMM account to the sender.
Creates both an [AMM entry][] and a [special AccountRoot entry](../../ledger-data/ledger-entry-types/accountroot.md#special-amm-accountroot-pseudo-account) to represent the AMM. Also transfers ownership of the starting balance of both assets from the sender to the created `AccountRoot` and issues an initial balance of liquidity provider tokens (LP Tokens) from the AMM account to the sender.
{% admonition type="warning" name="Caution" %}When you create the AMM, you should fund it with (approximately) equal-value amounts of each asset. Otherwise, other users can profit at your expense by trading with this AMM ([performing arbitrage](https://www.machow.ski/posts/an_introduction_to_automated_market_makers/#price-arbitrage)). The currency risk that liquidity providers take on increases with the volatility (potential for imbalance) of the asset pair. The higher the trading fee, the more it offsets this risk, so it's best to set the trading fee based on the volatility of the asset pair.{% /admonition %}
{% amendment-disclaimer name="AMM" /%}
<!-- TODO: Add {% amendment-disclaimer name="MPTokensV2" mode="updated" /%} badge. -->
## Example {% $frontmatter.seo.title %} JSON
{% tabs %}
{% tab label="Trust Line Token/XRP" %}
```json
{
"Account": "r3qNwezAqKp2FRFteiFjhC4V1at4KePFx7",
@@ -29,19 +33,36 @@ Creates both an [AMM entry][] and a [special AccountRoot entry](../../ledger-dat
"Fee": "200000",
"Flags": 2147483648,
"LastLedgerSequence": 99502897,
"Memos": [
{
"Memo": {
"MemoData": "414D4D2063726561746520696E69746961746564207669612058506D61726B65742E636F6D"
}
}
],
"Sequence": 94041760,
"SourceTag": 20221212,
"TradingFee": 1000,
"TransactionType": "AMMCreate",
"TransactionType": "AMMCreate"
}
```
{% /tab %}
{% tab label="MPT/MPT" %}
```json
{
"Account": "r3qNwezAqKp2FRFteiFjhC4V1at4KePFx7",
"Amount": {
"mpt_issuance_id": "00002403C84A0A28E0190E208E982C352BBD9B2E24D6AF46",
"value": "5000"
},
"Amount2": {
"mpt_issuance_id": "0000240462C4CB11E68E782514A68E9684E7516D252A8004",
"value": "10000"
},
"Fee": "200000",
"Flags": 2147483648,
"LastLedgerSequence": 99502897,
"Sequence": 94041761,
"TradingFee": 500,
"TransactionType": "AMMCreate"
}
```
{% /tab %}
{% /tabs %}
{% tx-example txid="E4CC45E28421618FFEB1920B8FE152EAAB70489BD9AD52FEF24D58389C011C5E" /%}
@@ -49,11 +70,14 @@ Creates both an [AMM entry][] and a [special AccountRoot entry](../../ledger-dat
| Field | JSON Type | [Internal Type][] | Required? | Description |
|:-------------|:--------------------|:------------------|:----------|:------------|
| `Amount` | [Currency Amount][] | Amount | Yes | The first of the two assets to fund this AMM with. This must be a positive amount. |
| `Amount2` | [Currency Amount][] | Amount | Yes | The second of the two assets to fund this AMM with. This must be a positive amount. |
| `Amount` | [Currency Amount][] | Amount | Yes | The first of the two assets (XRP or fungible token) to fund this AMM with. This must be a positive amount. |
| `Amount2` | [Currency Amount][] | Amount | Yes | The second of the two assets (XRP or fungible token) to fund this AMM with. This must be a positive amount. |
| `TradingFee` | Number | UInt16 | Yes | The fee to charge for trades against this AMM instance, in units of 1/100,000; a value of 1 is equivalent to 0.001%. The maximum value is `1000`, indicating a 1% fee. The minimum value is `0`. |
One or both of `Amount` and `Amount2` can be [tokens](../../../../concepts/tokens/index.md); at most one of them can be [XRP](../../../../introduction/what-is-xrp.md). They cannot both have the same currency code and issuer. The tokens' issuers must have [Default Ripple](../../../../concepts/tokens/fungible-tokens/rippling.md#the-default-ripple-flag) enabled. The assets _cannot_ be LP tokens for another AMM.
One or both of `Amount` and `Amount2` can be [fungible tokens](../../../../concepts/tokens/index.md); at most one of them can be [XRP](../../../../introduction/what-is-xrp.md). The assets _cannot_ be LP Tokens for another AMM.
- **Trust Line Tokens:** Cannot have the same currency code and issuer. The issuers must have [Default Ripple](../../../../concepts/tokens/fungible-tokens/rippling.md#the-default-ripple-flag) enabled.
- **MPTs:** Cannot have the same `mpt_issuance_id`. The issuance must have **Can Trade** and **Can Transfer** enabled.
## Special Transaction Cost
@@ -67,12 +91,16 @@ Besides errors that can occur for all transactions, {% $frontmatter.seo.title %}
|:--------------------|:---------------------------------------------|
| `tecAMM_INVALID_TOKENS` | Either `Amount` or `Amount2` has a currency code that is the same as this AMM's LP Tokens would use. (This is very unlikely to occur.) |
| `tecDUPLICATE` | There is already another AMM for this currency pair. |
| `tecFROZEN` | At least one of the deposit assets (`Amount` or `Amount2`) is currently [frozen](../../../../concepts/tokens/fungible-tokens/freezes.md). |
| `tecFROZEN` | At least one of the deposit assets (`Amount` or `Amount2`) is a [frozen](../../../../concepts/tokens/fungible-tokens/freezes.md) Trust Line Token. |
| `tecINSUF_RESERVE_LINE` | The sender of this transaction does meet the increased [reserve requirement](../../../../concepts/accounts/reserves.md) of processing this transaction, probably because they need a new trust line to hold the LP Tokens, and they don't have enough XRP to meet the additional owner reserve for a new trust line. |
| `tecLOCKED` | At least one of the deposit assets is an MPT that is currently [locked](../../../../concepts/tokens/fungible-tokens/deep-freeze.md#how-does-mpt-freezelock-behavior-differ-from-iou). |
| `tecNO_AUTH` | At least one of the deposit assets uses [authorized trust lines](../../../../concepts/tokens/fungible-tokens/authorized-trust-lines.md) and the sender does not have authorization to hold that asset. |
| `tecNO_ISSUER` | The issuer account of at least one MPT does not exist. |
| `tecNO_LINE` | The sender does not have a trust line for at least one of the deposit assets. |
| `tecNO_PERMISSION` | At least one of the deposit assets cannot be used in an AMM. |
| `tecNO_PERMISSION` | At least one of the MPT deposit assets does not have **Can Trade** or **Can Transfer** enabled. |
| `tecOBJECT_NOT_FOUND` | At least one of the MPT issuances does not exist. |
| `tecUNFUNDED_AMM` | The sender does not hold enough of the assets specified in `Amount` and `Amount2` to fund the AMM. |
| `temDISABLED` | At least one of the amounts is an MPT, but the [MPTokensV2 amendment][] is not enabled. |
| `terNO_RIPPLE` | The issuer of at least one of the assets has not enabled the [Default Ripple flag](../../../../concepts/tokens/fungible-tokens/rippling.md#the-default-ripple-flag). |
| `temAMM_BAD_TOKENS` | The values of `Amount` and `Amount2` are not valid: for example, both refer to the same token. |
| `temBAD_FEE` | The `TradingFee` value is invalid. It must be zero or a positive integer and cannot be over 1000. |

View File

@@ -13,9 +13,13 @@ Normally, an [AMMWithdraw transaction][] automatically deletes an AMM and all as
{% amendment-disclaimer name="AMM" /%}
<!-- TODO: Add {% amendment-disclaimer name="MPTokensV2" mode="updated" /%} badge. -->
## Example {% $frontmatter.seo.title %} JSON
{% tabs %}
{% tab label="Trust Line Token/XRP" %}
```json
{
"Account" : "rJVUeRqDFNs2xqA7ncVE6ZoAhPUoaJJSQm",
@@ -32,23 +36,45 @@ Normally, an [AMMWithdraw transaction][] automatically deletes an AMM and all as
"TransactionType" : "AMMDelete"
}
```
{% /tab %}
{% tab label="MPT/MPT" %}
```json
{
"Account" : "rJVUeRqDFNs2xqA7ncVE6ZoAhPUoaJJSQm",
"Asset" : {
"mpt_issuance_id" : "00002403C84A0A28E0190E208E982C352BBD71B2"
},
"Asset2" : {
"mpt_issuance_id" : "00002710D5F38CCE3B43BD597D1B6CCED4AC2D5C"
},
"Fee" : "10",
"Flags" : 0,
"Sequence" : 10,
"TransactionType" : "AMMDelete"
}
```
{% /tab %}
{% /tabs %}
{% raw-partial file="/docs/_snippets/tx-fields-intro.md" /%}
| Field | JSON Type | [Internal Type][] | Required? | Description |
|:---------------|:--------------------|:------------------|:----------|:------------|
| `Asset` | Object | Issue | Yes | The definition for one of the assets in the AMM's pool. The asset can be XRP, a token, or an MPT (see: [Specifying Without Amounts][]). |
| `Asset2` | Object | Issue | Yes | The definition for the other asset in the AMM's pool. The asset can be XRP, a token, or an MPT (see: [Specifying Without Amounts][]). |
| `Asset` | Object | Issue | Yes | The definition for one of the assets in the AMM's pool. The asset can be XRP or a fungible token (see: [Specifying Without Amounts][]). |
| `Asset2` | Object | Issue | Yes | The definition for the other asset in the AMM's pool. The asset can be XRP or a fungible token (see: [Specifying Without Amounts][]). |
## Error Cases
Besides errors that can occur for all transactions, AMMCreate transactions can result in the following [transaction result codes](../transaction-results/index.md):
Besides errors that can occur for all transactions, AMMDelete transactions can result in the following [transaction result codes](../transaction-results/index.md):
| Error Code | Description |
|:--------------------|:---------------------------------------------|
| `tecAMM_NOT_EMPTY` | The AMM holds assets in its pools, so it cannot be deleted. If you are one of the AMM's liquidity providers, use [AMMWithdraw][] first. |
| `tecINCOMPLETE` | There were too many associated ledger entries to fully delete, so the transaction removed as many as it could, but the AMM has not been fully deleted. You can send another AMMDelete transaction to continue and possibly finish the job. |
| `temDISABLED` | At least one of the assets is an MPT, but the [MPTokensV2 amendment][] is not enabled. |
| `terNO_AMM` | The specified AMM does not exist. (It may have been deleted already, or you may have specified a wrong asset for the AMM you intended.) |
## See Also

View File

@@ -13,14 +13,20 @@ If successful, this transaction creates a [trust line](../../../../concepts/toke
{% admonition type="info" name="Note" %}
You can't deposit either asset into an AMM if:
- At least one of the pooled assets is frozen by the token issuer.
- At least one of the pooled assets is frozen or locked by the token issuer.
- You aren't authorized to hold at least one of the pooled assets.
{% /admonition %}
{% amendment-disclaimer name="AMM" /%}
<!-- TODO: Add {% amendment-disclaimer name="MPTokensV2" mode="updated" /%} badge. -->
## Example {% $frontmatter.seo.title %} JSON
{% tabs %}
{% tab label="Trust Line Token/XRP" %}
```json
{
"Account" : "rJVUeRqDFNs2xqA7ncVE6ZoAhPUoaJJSQm",
@@ -43,6 +49,35 @@ You can't deposit either asset into an AMM if:
"TransactionType" : "AMMDeposit"
}
```
{% /tab %}
{% tab label="MPT/MPT" %}
```json
{
"Account" : "rJVUeRqDFNs2xqA7ncVE6ZoAhPUoaJJSQm",
"Amount" : {
"mpt_issuance_id" : "00002403C84A0A28E0190E208E982C352BBD71B2",
"value" : "500"
},
"Amount2" : {
"mpt_issuance_id" : "00002710D5F38CCE3B43BD597D1B6CCED4AC2D5C",
"value" : "1000"
},
"Asset" : {
"mpt_issuance_id" : "00002403C84A0A28E0190E208E982C352BBD71B2"
},
"Asset2" : {
"mpt_issuance_id" : "00002710D5F38CCE3B43BD597D1B6CCED4AC2D5C"
},
"Fee" : "10",
"Flags" : 1048576,
"Sequence" : 8,
"TransactionType" : "AMMDeposit"
}
```
{% /tab %}
{% /tabs %}
{% tx-example txid="BB00ECE591DFD0F8F410C5C2C639F1C1D1D2EFD92DF567AA226C3BDBE712FDD9" /%}
@@ -135,9 +170,14 @@ Besides errors that can occur for all transactions, {% $frontmatter.seo.title %}
| `tecAMM_EMPTY` | The AMM currently holds no assets, so you cannot do a normal deposit. You must use the Empty AMM Special Case deposit instead. |
| `tecAMM_NOT_EMPTY` | The transaction specified `tfTwoAssetIfEmpty`, but the AMM was not empty. |
| `tecAMM_FAILED` | The conditions on the deposit could not be satisfied. For example, the requested effective price in the `EPrice` field is too low. |
| `tecFROZEN` | The transaction tried to deposit a [frozen](../../../../concepts/tokens/fungible-tokens/freezes.md) token, or at least one of the paired tokens is frozen. |
| `tecFROZEN` | The transaction tried to deposit a [frozen](../../../../concepts/tokens/fungible-tokens/freezes.md) Trust Line Token, or at least one of the paired tokens is frozen. |
| `tecINSUF_RESERVE_LINE` | The sender of this transaction does meet the increased [reserve requirement](../../../../concepts/accounts/reserves.md) of processing this transaction, probably because they need a new trust line to hold the LP Tokens, and they don't have enough XRP to meet the additional owner reserve for a new trust line. |
| `tecLOCKED` | At least one of the assets is an MPT that is currently [locked](../../../../concepts/tokens/fungible-tokens/deep-freeze.md#how-does-mpt-freezelock-behavior-differ-from-iou). |
| `tecNO_ISSUER` | The issuer account of at least one MPT does not exist. |
| `tecNO_PERMISSION` | At least one of the MPT assets does not have **Can Trade** or **Can Transfer** enabled. |
| `tecOBJECT_NOT_FOUND` | At least one of the MPT issuances does not exist. |
| `tecUNFUNDED_AMM` | The sender does not have a high enough balance to make the specified deposit. |
| `temDISABLED` | At least one of the assets or amounts is an MPT, but the [MPTokensV2 amendment][] is not enabled. |
| `temBAD_AMM_TOKENS` | The transaction specified the LP Tokens incorrectly. For example, the `issuer` is not the AMM's associated AccountRoot address or the `currency` is not the currency code for this AMM's LP Tokens, or the transaction specified this AMM's LP Tokens in one of the asset fields. |
| `temBAD_AMOUNT` | An amount specified in the transaction is invalid. For example, a deposit amount is negative. |
| `temBAD_FEE` | A fee value specified in the transaction is invalid. For example, the trading fee is outside the allowable range. |

View File

@@ -9,10 +9,19 @@ labels:
Withdraw assets from an [Automated Market Maker](../../../../concepts/tokens/decentralized-exchange/automated-market-makers.md) (AMM) instance by returning the AMM's liquidity provider tokens (LP Tokens).
{% admonition type="info" name="Note" %}
If you withdraw an MPT but don't already have an [MPToken entry][] for it, this transaction automatically creates one for you.
{% /admonition %}
{% amendment-disclaimer name="AMM" /%}
<!-- TODO: Add {% amendment-disclaimer name="MPTokensV2" mode="updated" /%} badge. -->
## Example {% $frontmatter.seo.title %} JSON
{% tabs %}
{% tab label="Trust Line Token/XRP" %}
```json
{
"Account" : "rJVUeRqDFNs2xqA7ncVE6ZoAhPUoaJJSQm",
@@ -35,6 +44,35 @@ Withdraw assets from an [Automated Market Maker](../../../../concepts/tokens/dec
"TransactionType" : "AMMWithdraw"
}
```
{% /tab %}
{% tab label="MPT/MPT" %}
```json
{
"Account" : "rJVUeRqDFNs2xqA7ncVE6ZoAhPUoaJJSQm",
"Amount" : {
"mpt_issuance_id" : "00002403C84A0A28E0190E208E982C352BBD71B2",
"value" : "250"
},
"Amount2" : {
"mpt_issuance_id" : "00002710D5F38CCE3B43BD597D1B6CCED4AC2D5C",
"value" : "500"
},
"Asset" : {
"mpt_issuance_id" : "00002403C84A0A28E0190E208E982C352BBD71B2"
},
"Asset2" : {
"mpt_issuance_id" : "00002710D5F38CCE3B43BD597D1B6CCED4AC2D5C"
},
"Fee" : "10",
"Flags" : 1048576,
"Sequence" : 11,
"TransactionType" : "AMMWithdraw"
}
```
{% /tab %}
{% /tabs %}
{% tx-example txid="E606F37847E012E0D71267ED18CEA8B235AD9409BB6C2383A7D53ADEC2F314D4" /%}
@@ -114,9 +152,14 @@ Besides errors that can occur for all transactions, {% $frontmatter.seo.title %}
| `tecAMM_BALANCE` | The transaction would withdraw all of one asset from the pool, or rounding would cause a "withdraw all" to leave a nonzero amount behind. |
| `tecAMM_FAILED` | The conditions on the withdrawal could not be satisfied; for example, the requested effective price in the `EPrice` field is too low. |
| `tecAMM_INVALID_TOKENS` | The AMM for this token pair does not exist, or one of the calculations resulted in a withdrawal amount rounding to zero. |
| `tecFROZEN` | The transaction tried to withdraw a [frozen](../../../../concepts/tokens/fungible-tokens/freezes.md) token. |
| `tecFROZEN` | The transaction tried to withdraw a [frozen](../../../../concepts/tokens/fungible-tokens/freezes.md) Trust Line Token. |
| `tecINSUF_RESERVE_LINE` | The sender of this transaction does not meet the increased [reserve requirement](../../../../concepts/accounts/reserves.md) of processing this transaction, probably because they need at least one new trust line to hold one of the assets to be withdrawn, and they don't have enough XRP to meet the additional owner reserve for a new trust line. |
| `tecLOCKED` | At least one of the withdrawal assets is an MPT that is currently [locked](../../../../concepts/tokens/fungible-tokens/deep-freeze.md#how-does-mpt-freezelock-behavior-differ-from-iou). |
| `tecNO_AUTH` | The sender is not authorized to hold one of the AMM assets. |
| `tecNO_ISSUER` | The issuer account of at least one MPT does not exist. |
| `tecNO_PERMISSION` | At least one of the MPT withdrawal assets does not have **Can Trade** or **Can Transfer** enabled. |
| `tecOBJECT_NOT_FOUND` | At least one of the MPT issuances does not exist. |
| `temDISABLED` | At least one of the assets or amounts is an MPT, but the [MPTokensV2 amendment][] is not enabled. |
| `temMALFORMED` | The transaction specified an invalid combination of fields. See [AMMWithdraw Modes](#ammwithdraw-modes). (This error can also occur if the transaction is malformed in other ways.) |
| `temBAD_AMM_TOKENS` | The transaction specified the LP Tokens incorrectly; for example, the `issuer` is not the AMM's associated AccountRoot address or the `currency` is not the currency code for this AMM's LP Tokens, or the transaction specified this AMM's LP Tokens in one of the asset fields. |
| `terNO_AMM` | The Automated Market Maker instance for the asset pair in this transaction does not exist. |

View File

@@ -11,10 +11,19 @@ Attempts to redeem a [check](../../../../concepts/payment-types/checks.md) to re
Since the funds for a check are not guaranteed, redeeming a check can fail because the sender does not have a high enough balance or because there is not enough liquidity to deliver the funds. If this happens, the check remains in the ledger and the destination can try to cash it again later, or for a different amount.
{% admonition type="info" name="Note" %}
If you cash a Check for an MPT but don't already have an [MPToken entry][] for it, this transaction automatically creates one for you.
{% /admonition %}
{% amendment-disclaimer name="Checks" /%}
<!-- TODO: Add {% amendment-disclaimer name="MPTokensV2" mode="updated" /%} badge. -->
## Example {% $frontmatter.seo.title %} JSON
{% tabs %}
{% tab label="XRP" %}
```json
{
"Account": "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
@@ -24,6 +33,24 @@ Since the funds for a check are not guaranteed, redeeming a check can fail becau
"Fee": "12"
}
```
{% /tab %}
{% tab label="MPT" %}
```json
{
"Account": "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
"TransactionType": "CheckCash",
"Amount": {
"mpt_issuance_id": "00000003430427B80BD2D09D36B70B969E12801065F22308",
"value": "100"
},
"CheckID": "838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334",
"Fee": "12"
}
```
{% /tab %}
{% /tabs %}
{% tx-example txid="67B71B13601CDA5402920691841AC27A156463678E106FABD45357175F9FF406" /%}
@@ -39,12 +66,20 @@ The transaction ***must*** include either `Amount` or `DeliverMin`, but not both
## Error Cases
- If the sender of the CheckCash transaction is not the `Destination` of the check, the transaction fails with the result code `tecNO_PERMISSION`.
- If the Check identified by the `CheckID` field does not exist, the transaction fails with the result `tecNO_ENTRY`.
- If the Check identified by the `CheckID` field has already expired, the transaction fails with the result `tecEXPIRED`.
- If the destination of the Check has the `RequireDest` flag enabled but the Check, as created, does not have a destination tag, the transaction fails with the result code `tecDST_TAG_NEEDED`.
- If the transaction specifies both `Amount` and `DeliverMin`, or omits both, the transaction fails with the result `temMALFORMED`.
- If the `Amount` or `DeliverMin` does not match the currency (and issuer, if not XRP) of the Check, the transaction fails with the result `temBAD_CURRENCY`.
Besides errors that can occur for all transactions, {% $frontmatter.seo.title %} transactions can result in the following [transaction result codes](../transaction-results/index.md):
| Error Code | Description |
|:-----------|:------------|
| `tecDST_TAG_NEEDED` | The destination of the Check has the `RequireDest` flag enabled but the Check, as created, does not have a destination tag. |
| `tecEXPIRED` | The Check identified by the `CheckID` field has already expired. |
| `tecFROZEN` | The destination's trust line to the issuer is frozen, or, the MPT is locked. |
| `tecNO_AUTH` | The transaction involves a token whose issuer uses [Authorized Trust Lines](../../../../concepts/tokens/fungible-tokens/authorized-trust-lines.md) and the trust line that would receive the tokens exists but has not been authorized. Or, the destination is not authorized to hold the MPT. |
| `tecNO_ENTRY` | The Check identified by the `CheckID` field does not exist. |
| `tecNO_PERMISSION` | The sender of the CheckCash transaction is not the `Destination` of the check. This can also occur when the **Can Trade** flag is not set on an `MPTokenIssuance`. |
| `tecPATH_PARTIAL` | The requested amount exceeds the Check's `SendMax`, the Check owner has insufficient available funds, or the `DeliverMin` amount could not be delivered. |
| `temBAD_CURRENCY` | The `Amount` or `DeliverMin` does not match the currency (and issuer, if not XRP) of the Check. |
| `temDISABLED` | `Amount` or `DeliverMin` specifies an MPT but the [MPTokensV2 amendment][] is not enabled. |
| `temMALFORMED` | The transaction specifies both `Amount` and `DeliverMin`, or omits both. |
## See Also

View File

@@ -11,12 +11,17 @@ Create an on-ledger [check](../../../../concepts/payment-types/checks.md), which
{% amendment-disclaimer name="Checks" /%}
<!-- TODO: Add {% amendment-disclaimer name="MPTokensV2" mode="updated" /%} badge. -->
## Example {% $frontmatter.seo.title %} JSON
{% tabs %}
{% tab label="XRP" %}
```json
{
"TransactionType": "CheckCreate",
"Account": "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
"Account": "rUn84CUYbNjRoTQ6mSW7BVJNLb1QLo",
"Destination": "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
"SendMax": "100000000",
"Expiration": 570113521,
@@ -25,6 +30,27 @@ Create an on-ledger [check](../../../../concepts/payment-types/checks.md), which
"Fee": "12"
}
```
{% /tab %}
{% tab label="MPT" %}
```json
{
"TransactionType": "CheckCreate",
"Account": "rUn84CUYbNjRoTQ6mSW7BVJNLb1QLo",
"Destination": "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
"SendMax": {
"mpt_issuance_id": "00000003430427B80BD2D09D36B70B969E12801065F22308",
"value": "100"
},
"Expiration": 570113521,
"InvoiceID": "6F1DFD1D0FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B",
"DestinationTag": 1,
"Fee": "12"
}
```
{% /tab %}
{% /tabs %}
{% tx-example txid="4E0AA11CBDD1760DE95B68DF2ABBE75C9698CEB548BEA9789053FCB3EBD444FB" /%}
@@ -44,14 +70,16 @@ Besides errors that can occur for all transactions, {% $frontmatter.seo.title %}
| Error Code | Description |
|:-----------|:------------|
| `tecNO_PERMISSION` | The `Destination` account is blocking incoming Checks. {% amendment-disclaimer name="DisallowIncoming" /%} |
| `temREDUNDANT` | The `Destination` is the sender of the transaction. |
| `tecNO_DST` | The `Destination` [account](../../../../concepts/accounts/index.md) does not exist in the ledger. |
| `tecDST_TAG_NEEDED` | The `Destination` account has the `RequireDest` flag enabled but the transaction does not include a `DestinationTag` field. |
| `tecFROZEN` | `SendMax` specifies a token which is [frozen](../../../../concepts/tokens/fungible-tokens/freezes.md). |
| `tecEXPIRED` | The `Expiration` of the transaction is in the past. |
| `tecINSUFFICIENT_RESERVE` | The sender does not have enough XRP to meet the [owner reserve](../../../../concepts/accounts/reserves.md#owner-reserves) after adding the Check. |
| `tecDIR_FULL` | Either the sender or the destination of the Check cannot own more objects in the ledger.<br>This error is effectively impossible to receive if {% amendment-disclaimer name="fixDirectoryLimit" compact=true /%} is enabled. |
| `tecDST_TAG_NEEDED` | The `Destination` account has the `RequireDest` flag enabled but the transaction does not include a `DestinationTag` field. |
| `tecEXPIRED` | The `Expiration` of the transaction is in the past. |
| `tecFROZEN` | `SendMax` specifies a token which is [frozen](../../../../concepts/tokens/fungible-tokens/freezes.md). For MPTs, this occurs when the `MPTLock` flag is set on the `MPTokenIssuance` or on the sender's `MPToken` object. |
| `tecINSUFFICIENT_RESERVE` | The sender does not have enough XRP to meet the [owner reserve](../../../../concepts/accounts/reserves.md#owner-reserves) after adding the Check. |
| `tecNO_DST` | The `Destination` [account](../../../../concepts/accounts/index.md) does not exist in the ledger. |
| `tecNO_PERMISSION` | The `Destination` account is blocking incoming Checks. {% amendment-disclaimer name="DisallowIncoming" /%}<br>For MPTs, this also occurs when the `MPTCanTrade` flag is not set on the `MPTokenIssuance`. |
| `tecOBJECT_NOT_FOUND` | The `MPTokenIssuance` object for the MPT specified in `SendMax` does not exist. |
| `temDISABLED` | `SendMax` specifies an MPT but the [MPTokensV2 amendment][] is not enabled. |
| `temREDUNDANT` | The `Destination` is the sender of the transaction. |
## See Also

View File

@@ -9,8 +9,17 @@ labels:
Place an [offer](../../../../concepts/tokens/decentralized-exchange/offers.md) to trade in the [decentralized exchange](../../../../concepts/tokens/decentralized-exchange/index.md).
{% admonition type="info" name="Note" %}
If an offer is filled with a Multi-Purpose Token (MPT) the owner doesn't already hold, the transaction automatically creates and authorizes an `MPToken` object for that account.
{% /admonition %}
<!-- TODO: Add {% amendment-disclaimer name="MPTokensV2" mode="updated" /%} badge. -->
## Example {% $frontmatter.seo.title %} JSON
{% tabs %}
{% tab label="XRP to Trust Line Token" %}
```json
{
"TransactionType": "OfferCreate",
@@ -27,6 +36,27 @@ Place an [offer](../../../../concepts/tokens/decentralized-exchange/offers.md) t
}
}
```
{% /tab %}
{% tab label="XRP to MPT" %}
```json
{
"TransactionType": "OfferCreate",
"Account": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX",
"Fee": "12",
"Flags": 0,
"LastLedgerSequence": 7108682,
"Sequence": 8,
"TakerGets": "6000000",
"TakerPays": {
"mpt_issuance_id": "000004C463C52827307480341125DA0577DEFC38405B0E3E",
"value": "100"
}
}
```
{% /tab %}
{% /tabs %}
{% tx-example txid="0CD69FD1F0A890CC57CDA430213FD294F7D65FF4A0F379A0D09D07A222D324E6" /%}
@@ -41,6 +71,12 @@ Place an [offer](../../../../concepts/tokens/decentralized-exchange/offers.md) t
| `TakerGets` | [Currency Amount][] | Amount | Yes | The amount and type of currency being sold. |
| `TakerPays` | [Currency Amount][] | Amount | Yes | The amount and type of currency being bought. |
When crossing offers with MPT amounts (`TakerGets` or `TakerPays`), the tokens can only be transferred if the **Can Transfer** flag is enabled on the MPT issuance, or if the sender or recipient is the issuer.
{% admonition type="info" name="Note" %}
MPT amounts are not adjusted for `TickSize`.
{% /admonition %}
## OfferCreate Flags
Transactions of the OfferCreate type support additional values in the [`Flags` field](../common-fields.md#flags-field), as follows:
@@ -60,10 +96,10 @@ Transactions of the OfferCreate type support additional values in the [`Flags` f
|:-------------------------|:--------------------------------------------------|
| `tecDIR_FULL` | The owner owns too many items in the ledger, or the order book contains too many Offers at the same exchange rate already.<br>This error is effectively impossible to receive if {% amendment-disclaimer name="fixDirectoryLimit" compact=true /%} is enabled. |
| `tecEXPIRED` | The transaction specifies an `Expiration` time that has already passed. |
| `tecFROZEN` | The transaction involves a token on a [frozen](../../../../concepts/tokens/fungible-tokens/freezes.md) trust line (including local and global freezes). The `TakerPays` (buy amount) token has been deep-frozen by the issuer. |
| `tecFROZEN` | The transaction involves a token on a [frozen](../../../../concepts/tokens/fungible-tokens/freezes.md) trust line (including local and global freezes), or, the MPT is locked. The `TakerPays` (buy amount) token has been deep-frozen by the issuer. |
| `tecINSUF_RESERVE_OFFER` | The owner does not have enough XRP to meet the reserve requirement of adding a new offer ledger entry, and the transaction did not convert any currency. (If the transaction successfully traded any amount, the transaction succeeds with the result code `tesSUCCESS`, but does not create an offer ledger entry for the remainder.) |
| `tecKILLED` | The transaction specifies `tfFillOrKill`, and the full amount cannot be filled. If the _[ImmediateOfferKilled amendment][]_ is enabled, this result code also occurs when the transaction specifies `tfImmediateOrCancel` and executes without moving funds (previously, an Immediate or Cancel offer would return `tesSUCCESS` even if no funds were moved). |
| `tecNO_AUTH` | The transaction involves a token whose issuer uses [Authorized Trust Lines](../../../../concepts/tokens/fungible-tokens/authorized-trust-lines.md) and the the trust line that would receive the tokens exists but has not been authorized. |
| `tecNO_AUTH` | The transaction involves a token whose issuer uses [Authorized Trust Lines](../../../../concepts/tokens/fungible-tokens/authorized-trust-lines.md) and the the trust line that would receive the tokens exists but has not been authorized. Or, the sender is not authorized to hold the MPT. |
| `tecNO_ISSUER` | The transaction specifies a token whose `issuer` value is not a funded account in the ledger. |
| `tecNO_LINE` | The transaction involves a token whose issuer uses [Authorized Trust Lines](../../../../concepts/tokens/fungible-tokens/authorized-trust-lines.md) and the necessary trust line does not exist. |
| `tecNO_PERMISSION` | The transaction uses a `DomainID` but the sender is not a member of that domain. {% amendment-disclaimer name="PermissionedDEX" /%} |
@@ -73,6 +109,7 @@ Transactions of the OfferCreate type support additional values in the [`Flags` f
| `temBAD_ISSUER` | The transaction specifies a token with an invalid `issuer` value. |
| `temBAD_OFFER` | The offer tries to trade XRP for XRP, or tries to trade an invalid or negative amount of a token. |
| `temBAD_SEQUENCE` | The transaction contains an `OfferSequence` that is not validly formatted, or is higher than the transaction's own `Sequence` number. |
| `temDISABLED` | `TakerGets` or `TakerPays` specifies an MPT but the [MPTokensV2 amendment][] is not enabled. |
| `temINVALID_FLAG` | The transaction specifies an invalid flag combination, such as both `tfImmediateOrCancel` and `tfFillOrKill`, or the transaction uses `tfHybrid` but omits the `DomainID` field. |
| `temREDUNDANT` | The transaction would trade a token for the same token (same issuer and currency code). |

View File

@@ -145,14 +145,17 @@ In the above example with a ¥95/$15 offer and a ¥5/$2 offer, the situation is
## MPT Payments
When you send a payment using [MPTs](/docs/concepts/tokens/fungible-tokens/multi-purpose-tokens), the _Amount_ field requires only the `mpt_issuance_id` and the `value`. The `MPTokenIssuanceID` is used to uniquely identify the MPT for the transaction.
When you send a payment using [MPTs](/docs/concepts/tokens/fungible-tokens/multi-purpose-tokens), the `Amount` (or `DeliverMax`), `DeliverMin`, `SendMax`, and `Paths` fields can specify MPT amounts using `mpt_issuance_id` and `value`.
Version 1 MPTokens only support direct MPT payment between accounts. They cannot be traded in the decentralized exchange.
MPTs can be used in direct payments, cross-currency payments, payment paths, and the decentralized exchange.
{% amendment-disclaimer name="MPTokensV1" /%}
<!-- {% amendment-disclaimer name="MPTokensV2" /%} -->
### Sample MPT Payment transaction
{% tabs %}
{% tab label="Direct MPT Payment" %}
```json
{
"Account": "rLWSJKbwYSzG32JuGissYd66MFTvfMk4Bt",
@@ -160,19 +163,48 @@ Version 1 MPTokens only support direct MPT payment between accounts. They cannot
"mpt_issuance_id": "006419063CEBEB49FC20032206CE0F203138BFC59F1AC578",
"value": "100"
},
"DeliverMax": {
"mpt_issuance_id": "006419063CEBEB49FC20032206CE0F203138BFC59F1AC578",
"value": "100"
},
"SendMax": {
"mpt_issuance_id": "006419063CEBEB49FC20032206CE0F203138BFC59F1AC578",
"value": "100"
},
"Destination": "raZ3wTTKiMHn3BiStvz4ET9rbCHfU1DMak",
"Fee": "120",
"Flags": 0,
"Flags": 0
}
```
{% /tab %}
{% tab label="Cross-Currency with MPT" %}
```json
{
"Account": "rJ85Mok8YRNxSo7NnxKGrPuk29uAeZQqwZ",
"DeliverMax": {
"mpt_issuance_id": "00000010A407AF5856CCF3C42619DAA925813FC955C72983",
"value": "100"
},
"DeliverMin": {
"mpt_issuance_id": "00000010A407AF5856CCF3C42619DAA925813FC955C72983",
"value": "90"
},
"Destination": "rHKBGB4vhnnVFmfrj4sUx3F9riz2CiHgCK",
"Fee": "10",
"Flags": 131072,
"Paths": [
[
{
"mpt_issuance_id": "00000004A407AF5856CCF3C42619DAA925813FC955C72983"
},
{
"mpt_issuance_id": "0000000AA407AF5856CCF3C42619DAA925813FC955C72983"
},
{
"mpt_issuance_id": "00000010A407AF5856CCF3C42619DAA925813FC955C72983"
}
]
],
"SendMax": "100000000"
}
```
{% /tab %}
{% /tabs %}
## Credential IDs
You can send money to an account that uses [Deposit Authorization](../../../../concepts/accounts/depositauth.md) by providing the `CredentialIDs` field with an exact set of credentials that are preauthorized by the recipient. The set of credentials must match a [DepositPreauth entry](../../ledger-data/ledger-entry-types/depositpreauth.md) in the ledger.

View File

@@ -225,8 +225,5 @@ The decoding utility function converts the metadata back to a JSON object and ex
- [MPTokenIssuanceCreate transaction][]
- [MPTokenIssuanceDestroy transaction][]
- [MPTokenIssuanceSet transaction][]
<!-- TODO: Add when the tutorial on sending MPTs is ready. -->
<!-- - **Tutorials**:
- [Send a Multi-Purpose Token (MPT)](./send-a-multi-purpose-token.md) -->
{% raw-partial file="/docs/_snippets/common-links.md" /%}

View File

@@ -1531,6 +1531,21 @@ Implements a new type of fungible token, called a _Multi-Purpose Token_ (MPT). T
- (New) `mpt_holders` method - Returns a list of accounts that hold a specific MPT issuance.
- (Updated) `ledger_entry` method - Can look up MPToken and MPTokenIssuance ledger entry types.
<!-- TODO: Add when MPTokensV2 is on Devnet -->
<!-- ### MPTokensV2
[MPTokensV2]: #mptokensv2
| Amendment | MPTokensV2 |
|:-------------|:-----------|
| Amendment ID | BE2D87DF21B690ED1497B593FDC013CC04276302380B1BD50A033DCF8DEFB2EB |
| Status | In Development |
| Default Vote (Latest stable release) | No |
| Pre-amendment functionality retired? | No |
Extends [Multi-Purpose Tokens (MPTs)](#mptokensv1) to work with the Decentralized Exchange (DEX) and Automated Market Makers (AMMs). This amendment enables MPTs to be traded, used in offers, and pooled in AMMs alongside XRP and Trust Line Tokens.
Specification: [XLS-82](https://github.com/XRPLF/XRPL-Standards/discussions/217).
-->
### MultiSign
[MultiSign]: #multisign