diff --git a/docs/xls-65d-single-asset-vault/concepts/pseudo-account.md b/docs/xls-65d-single-asset-vault/concepts/pseudo-account.md index ce5d1674..f7bc26cb 100644 --- a/docs/xls-65d-single-asset-vault/concepts/pseudo-account.md +++ b/docs/xls-65d-single-asset-vault/concepts/pseudo-account.md @@ -3,25 +3,31 @@ seo: description: A pseudo-account is a special type of XRPL account that holds assets on behalf of an on-chain protocol. labels: - Single Asset Vault + - AMM + - Lending Protocol status: not_enabled --- # Pseudo-Account -The XRP Ledger is an account-based blockchain where assets like XRP, Fungible Tokens, and Multi-Purpose Tokens (MPTs) are held by accounts, and are represented on-chain by an [AccountRoot](https://xrpl.org/docs/references/protocol/ledger-data/ledger-entry-types/accountroot) ledger entry. However, certain use cases require assets to be transferable to and from an object, which is why a pseudo-account is needed. +The XRP Ledger is an account-based blockchain where assets like XRP, trust line tokens, and Multi-Purpose Tokens (MPTs) are held by accounts, and are represented on-chain by an [AccountRoot](https://xrpl.org/docs/references/protocol/ledger-data/ledger-entry-types/accountroot) ledger entry. However, certain use cases require assets to be transferable to and from an object, which is why a pseudo-account is needed. -A pseudo-account is a special type of account that holds assets on behalf of an on-chain protocol, and is used in the following use cases: +A pseudo-account is a special type of account with its own `AccountRoot` ledger entry, but only holds assets on behalf of an on-chain protocol. Use cases for pseudo-accounts include: - **Automated Market Makers (AMM)**: The [XLS-30 amendment](https://xrpl.org/resources/known-amendments#amm) introduced pseudo-accounts for AMMs by adding the `AMMID` field to the `AccountRoot` ledger entry. This field links a pseudo-account to an AMM instance, allowing it to track XRP and token balances in the pool and issue `LPTokens` on behalf of the AMM instance. - **Single Asset Vaults**: A single asset vault pseudo-account is used to store deposited funds and issue MPT shares. A new `VaultID` field is introduced in the `AccountRoot` ledger entry, which links the pseudo-account with the vault. -- **Lending Protocol**: While still in development, this protocol is expected to use pseudo-accounts to hold loan funds. +- **Lending Protocol**: The Lending Protocol also uses the single asset vault's pseudo-account, with each `LoanBroker` tracked in the pseudo-account's owner directory. The pseudo-account holds first-loss capital that protects vault depositors from loan defaults, as well as the loan funds themselves. A pseudo-account has strict limitations. It cannot receive payments from other accounts, cannot send transactions since it has no signing authority, and exists solely to store or issue assets. -## Transaction Cost +## Reserve Requirements -A transaction that creates a pseudo-account incurs a higher than usual [transaction cost](https://xrpl.org/docs/concepts/transactions/transaction-cost) to deter ledger spam. Instead of the standard minimum of 0.00001 XRP, the transaction must destroy an [incremental owner reserve](https://xrpl.org/docs/concepts/accounts/reserves#base-reserve-and-owner-reserve), currently 0.2 XRP. +The cost of creating a pseudo-account depends on whether it is owned and controlled by another account: + +- **Owned pseudo-accounts**: For objects like a `Vault` where a single account owns and controls the associated pseudo-account, the creation transaction increases the owner's XRP reserve by one [incremental owner reserve](https://xrpl.org/docs/concepts/accounts/reserves#base-reserve-and-owner-reserve) (currently 0.2 XRP). This is in addition to any other reserve requirements of the transaction (for example, the Vault object itself). + +- **Unowned pseudo-accounts**: For objects like an `AMM` that are not owned by any account, the creation transaction charges a special, higher-than-normal transaction fee. This fee must be at least the value of one incremental owner reserve. This amount is burned, compensating for the permanent ledger space without tying the reserve to a specific owner. {% raw-partial file="/docs/_snippets/common-links.md" /%} diff --git a/docs/xls-65d-single-asset-vault/concepts/single-asset-vault.md b/docs/xls-65d-single-asset-vault/concepts/single-asset-vault.md index 1088851b..7a0386a3 100644 --- a/docs/xls-65d-single-asset-vault/concepts/single-asset-vault.md +++ b/docs/xls-65d-single-asset-vault/concepts/single-asset-vault.md @@ -8,7 +8,7 @@ status: not_enabled # Single Asset Vault -A single asset vault is an XRP Ledger primitive that aggregates assets from multiple depositors and makes them available to other on-chain protocols, such as the Lending Protocol (currently in development). A vault asset can be [XRP](https://xrpl.org/docs/introduction/what-is-xrp), a [Fungible Token](https://xrpl.org/docs/concepts/tokens/fungible-tokens), or an [MPT (Multi-Purpose Token)](https://xrpl.org/docs/concepts/tokens/fungible-tokens/multi-purpose-tokens). +A single asset vault is an XRP Ledger primitive that aggregates assets from multiple depositors and makes them available to other on-chain protocols, such as the Lending Protocol (currently in development). A vault asset can be [XRP](https://xrpl.org/docs/introduction/what-is-xrp), a [trust line token](https://xrpl.org/docs/concepts/tokens/fungible-tokens/trust-line-tokens), or an [MPT (Multi-Purpose Token)](https://xrpl.org/docs/concepts/tokens/fungible-tokens/multi-purpose-tokens). A Vault Owner account manages the vault and can create, update, or delete it as needed. When creating a vault, the Vault Owner can also specify whether shares are transferable or non-transferable. Non-transferable shares cannot be transferred to any other account, and can only be redeemed. @@ -34,9 +34,15 @@ Depositors can deposit assets to receive shares, which represent their proportio Since the XRP Ledger is an account-based blockchain, all assets must be held by an account. A `Vault` ledger entry cannot hold assets directly, so a [pseudo-account](pseudo-account.md) is created to hold assets on its behalf. This stand-alone account cannot receive funds or send transactions, and exists solely to store assets and issue shares. -Each share is represented on-chain as an MPT, issued by the vault's pseudo-account. +Each share is represented on-chain as an MPT, issued by the vault's pseudo-account. Since MPTs can only exist as whole number units, the vault uses a `Scale` setting to convert fractional asset amounts into whole number shares. -Depending on the connected protocol, vault shares may be yield-bearing, meaning shareholders could redeem shares for more or less liquidity than they originally deposited. This is because the total asset balance in the vault can grow or shrink over time, affecting the value of each share. However, the vault asset (e.g., USDC or XRP) does not generate yield on its own. +The scale behavior varies based on the type of asset held by the vault: + +- **XRP**: Uses a fixed scale that aligns with XRP's native structure, where one share represents one drop. +- **Trust Line Token**: Allows configurable precision (default preserves 6 decimal places). +- **MPT**: Uses a 1-to-1 relationship between MPT units and shares. + +Depending on the connected protocol, vault shares may be yield-bearing, meaning shareholders could redeem shares for more or less liquidity than they originally deposited. This is because the total asset balance in the vault can grow or shrink over time, depending on connected protocols such as lending, which affects the value of each share. However, the vault asset (e.g., USDC, XRP) does not generate yield on its own. The value of each share depends on the total assets in the vault: @@ -57,7 +63,7 @@ To prevent depositors from exploiting potential losses by redeeming shares early Because the unrealized loss temporarily decreases the vault's value, a malicious depositor may take advantage of this by depositing assets at a lowered price and redeeming shares once the price increases. -For example, consider a vault with a total value of $1.0m and total shares of $1.0m. Let's assume the unrealized loss for the vault is $900k: +For example, consider a vault with a total value of $1.0m and total shares of 1.0m. Let's assume the unrealized loss for the vault is $900k: 1. The new exchange rate is calculated as: @@ -85,35 +91,48 @@ To mitigate this, the vault uses separate exchange rates for deposits and redemp A single asset vault uses **two distinct exchange rates**: -- **Deposit Exchange Rate**: When a depositor adds assets to the vault, they receive shares based on the current exchange rate. This ensures that new deposits do not unfairly impact the value of existing shares. - -- **Withdrawal Exchange Rate**: When shares are redeemed, the vault ensures that unrealized losses are accounted for, so depositors cannot withdraw more than the vault’s true asset value. - - **Redemptions**: If a depositor redeems a specific number of shares, the vault calculates the asset amount based on the ratio of _total assets_ to _total shares_, adjusted for unrealized losses. - - **Withdrawals**: If a depositor requests a specific asset amount, the vault determines how many shares must be _burned_ to fulfill the request, ensuring that unrealized losses are accounted for in the calculation. +- **Deposit Exchange Rate**: Protects new depositors from prior losses and ensures fair share allocation. +- **Withdrawal Exchange Rate**: Ensures all shareholders share losses proportionally. Whether redeeming shares or withdrawing assets, the vault always calculates payouts using the actual current value (total assets minus losses), so depositors get their fair share of what's actually in the vault. + - **Redemptions**: The vault burns shares so the depositor can receive proportional assets. + - **Withdrawals**: The vault determines the shares to burn based on the requested asset amount. These exchange rates ensure fairness and prevent manipulation, maintaining the integrity of deposits and redemptions. To understand how the exchange rates are applied, here are the key variables used in the calculations: -- `T_share`: The total number of shares issued by the vault. -- `T_asset`: The total assets in the vault, including any future yield. -- `Δ_asset`: The change in the total amount of assets after a deposit, withdrawal, or redemption. -- `Δ_share`: The change in the total amount of shares after a deposit, withdrawal, or redemption. -- `l`: The unrealized loss of the vault. +- `Γ_assets`: The total balance of assets held within the vault. +- `Γ_shares`: The total number of shares currently issued by the vault. +- `Δ_assets`: The amount of assets being deposited, withdrawn, or redeemed. +- `Δ_shares`: The number of shares being issued or burned. +- `l`: The vault's total unrealized loss. +- `σ`: The scaling factor (σ = 10Scale) used to convert fractional assets into whole number shares. {% tabs %} {% tab label="Deposit" %} The vault computes the number of shares a depositor will receive as follows: + - **Initial Deposit (Empty Vault)**: For the first deposit into an empty vault, shares are calculated using the scaling factor to properly represent fractional assets as whole numbers. + + ```js + Δ_shares = Δ_assets * σ // σ = 10^Scale + ``` + + - **Subsequent Deposits**: For all other deposits, shares are calculated proportionally. The resulting share value is rounded **down** to the nearest whole number. + + ```js + Δ_shares = (Δ_assets * Γ_shares) / Γ_assets + ``` + Because the share amount is rounded down, the actual assets taken from the depositor are recalculated. This ensures the depositor isn't overcharged and that new shares are valued against the vault's true value, accounting for any unrealized loss: + ```js - Δ_share = Δ_asset * (T_share / T_asset) + Δ_assets = (Δ_shares * (Γ_assets - l)) / Γ_shares ``` - After a successful deposit, the _total asset_ and _total share_ values are updated like so: + After a successful deposit, the _total assets_ and _total shares_ values are updated like so: ```js - T_asset = T_asset + Δ_asset // New balance of assets in the vault. - T_share = T_share + Δ_share // New share balance in the vault. + Γ_assets = Γ_assets + Δ_assets // New balance of assets in the vault. + Γ_shares = Γ_shares + Δ_shares // New share balance in the vault. ``` {% /tab %} @@ -121,31 +140,44 @@ To understand how the exchange rates are applied, here are the key variables use The vault computes the number of assets returned by burning shares as follows: ```js - Δ_asset = Δ_share * ((T_asset - l) / T_share) + Δ_assets = (Δ_shares * (Γ_assets - l)) / Γ_shares ``` - After a successful redemption, the _total asset_ and _total share_ values are updated like so: + After a successful redemption, the _total assets_ and _total shares_ values are updated like so: ```js - T_asset = T_asset - Δ_asset // New balance of assets in the vault. - T_share = T_share - Δ_share // New share balance in the vault. + Γ_assets = Γ_assets - Δ_assets // New balance of assets in the vault. + Γ_shares = Γ_shares - Δ_shares // New share balance in the vault. ``` {% /tab %} {% tab label="Withdraw" %} - The vault computes the number of shares to burn for a withdrawal as follows: + When a depositor requests a specific asset amount, the vault uses a two-step process to determine the final payout: - ```js - Δ_share = Δ_asset * (T_share / (T_asset - l)) - ``` + 1. The requested asset amount (`Δ_assets_requested`) is converted into shares. + + ```js + Δ_shares = (Δ_assets_requested * Γ_shares) / (Γ_assets - l) + ``` + + The calculated share amount is rounded to the **nearest** whole number. + + 2. The rounded number of shares is used to calculate the final asset payout (`Δ_assets_out`), using the same logic as a redemption. + + ```js + Δ_assets_out = (Δ_shares * (Γ_assets - l)) / Γ_shares + ``` + + Due to rounding in step 1, the final payout may differ slightly from the requested amount. After a successful withdrawal, the _total asset_ and _total share_ values are updated like so: ```js - T_asset = T_asset - Δ_asset // New balance of assets in the vault. - T_share = T_share - Δ_share // New share balance in the vault. + Γ_assets = Γ_assets - Δ_assets_out // New balance of assets in the vault. + Γ_shares = Γ_shares - Δ_shares // New share balance in the vault. ``` + {% /tab %} {% /tabs %} @@ -155,28 +187,34 @@ Vault shares are a first-class asset, meaning that they can be transferred and u For example, if a private vault holds USDC, the destination account must belong to the vault’s Permissioned Domain and have permission to hold USDC. Any compliance mechanisms applied to USDC also apply to the shares. If the USDC issuer freezes the payee’s trust line, the payee cannot receive shares representing USDC. -It is important to remember that a vault must be configured to allow share transfers, or this will not be possible. +{% admonition type="info" name="Note" %} +It is important to remember that a vault must be **configured** to allow share transfers, or this will not be possible. +{% /admonition %} -A depositor can transfer vault shares to another account by making a [payment](https://xrpl.org/docs/references/protocol/transactions/types/payment) transaction. Nothing changes in the way the payment transaction is submitted for transferring vault shares. However, there are new failure scenarios to watch out for if the transaction fails: +A depositor can transfer vault shares to another account by making a [Payment](https://xrpl.org/docs/references/protocol/transactions/types/payment) transaction. Nothing changes in the way the payment transaction is submitted for transferring vault shares. However, there are new failure scenarios to watch out for if the transaction fails: -- The trust line or MPT is frozen between the payer and the issuer. -- There is a global freeze or lock. -- The vault pseudo-account is frozen. -- The underlying asset is an MPT and is locked for the payer, destination, or vault pseudo-account. -- The underlying asset is a Fungible Token and the trust line is frozen between the issuer and the payer, destination, or vault pseudo-account. +- The vault is private and the payee lacks credentials in the vault's permissioned domain. +- The vault shares are configured as non-transferable. +- There is a global freeze (trust line tokens) or lock (MPTs) on the underlying asset. +- The underlying asset is an MPT and is locked for the payer, payee, or vault pseudo-account. +- The underlying asset is a trust line token and the trust line is frozen between the issuer and the payer, payee, or vault pseudo-account. If the transfer succeeds and the payee already holds vault shares, their balance increases. Otherwise, a new MPT entry is created for their account. -## Frozen Assets +## Compliance -When the asset of a vault is frozen, its corresponding shares also cannot be transferred. +### Frozen Assets -The issuer of a vault asset can enact a freeze either through a [global freeze](https://xrpl.org/docs/tutorials/how-tos/use-tokens/enact-global-freeze#enact-global-freeze) for fungible tokens or by [locking MPTs](https://github.com/XRPLF/XRPL-Standards/tree/master/XLS-0033d-multi-purpose-tokens#21122-flags). When a vault asset is frozen: +The issuer of a vault asset can enact a [freeze](https://xrpl.org/docs/concepts/tokens/fungible-tokens/freezes) for trust line tokens or [lock an MPT](https://xrpl.org/docs/concepts/tokens/fungible-tokens/deep-freeze#how-does-mpt-freeze/lock-behavior-differ-from-iou). When a vault asset is frozen: 1. Withdrawals can only be made to the asset’s issuer. -2. Frozen assets cannot be deposited into the vault. +2. The asset cannot be deposited into the vault. 3. Its corresponding shares also cannot be transferred. +### Clawback + +An asset issuer can perform a [clawback](https://xrpl.org/docs/use-cases/tokenization/stablecoin-issuer#clawback) on vault assets by forcing redemption of shares held by an account. This exchanges the holder's shares for the underlying assets, which are sent directly to the issuer. This mechanism allows asset issuers to recover their issued assets from vault depositors when necessary for fraud prevention or regulatory compliance. + ## Why Use a Single Asset Vault? With a single asset vault you don't have to manage liquidity at the protocol level. Instead, you can use the vault to handle deposits, redemptions, and asset tracking separately. @@ -190,6 +228,6 @@ Depending on the connected on-chain protocol, vaults can be applied to various u - Yield-bearing tokens - Asset management -The only supported use cases right now are _asset management_ and _lending markets_, with lending currently in development through the [XLS-66d: Lending Protocol](https://github.com/XRPLF/XRPL-Standards/discussions/190). +The only supported use cases right now are _asset management_ and [_lending markets_](https://github.com/XRPLF/XRPL-Standards/discussions/190). {% raw-partial file="/docs/_snippets/common-links.md" /%} diff --git a/docs/xls-65d-single-asset-vault/index.page.tsx b/docs/xls-65d-single-asset-vault/index.page.tsx index 341c9f94..94e4bed8 100644 --- a/docs/xls-65d-single-asset-vault/index.page.tsx +++ b/docs/xls-65d-single-asset-vault/index.page.tsx @@ -42,7 +42,7 @@ export default function Page() { /> diff --git a/docs/xls-65d-single-asset-vault/reference/api/vault-info.md b/docs/xls-65d-single-asset-vault/reference/api/vault-info.md index 8d9cde5a..d298141f 100644 --- a/docs/xls-65d-single-asset-vault/reference/api/vault-info.md +++ b/docs/xls-65d-single-asset-vault/reference/api/vault-info.md @@ -7,7 +7,7 @@ labels: # vault_info -[[Source]](https://github.com/XRPLF/rippled/blob/develop/src/xrpld/rpc/handlers/VaultInfo.cpp "Source")
+[[Source]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/rpc/handlers/VaultInfo.cpp "Source")
The `vault_info` command retrieves information about a vault, its owner, available assets, and details on issued shares. All information retrieved is relative to a particular version of the ledger. @@ -26,7 +26,7 @@ An example of the request format: ```json { "command": "vault_info", - "vault_id": "C043BB1B350FFC5FED21E40535609D3D95BC0E3CE252E2F69F85BE0157020A52" + "vault_id": "45E6742527EDE6A2B537AE8A77B8D8CCFEFE115A22B3BF664A39407631F9A166" } ``` {% /tab %} @@ -37,7 +37,7 @@ An example of the request format: "method": "vault_info", "params": [ { - "vault_id": "C043BB1B350FFC5FED21E40535609D3D95BC0E3CE252E2F69F85BE0157020A52" + "vault_id": "45E6742527EDE6A2B537AE8A77B8D8CCFEFE115A22B3BF664A39407631F9A166" } ] } @@ -47,7 +47,7 @@ An example of the request format: {% tab label="Commandline" %} ```sh #Syntax: vault_info [] -rippled vault_info C043BB1B350FFC5FED21E40535609D3D95BC0E3CE252E2F69F85BE0157020A52 +rippled vault_info 45E6742527EDE6A2B537AE8A77B8D8CCFEFE115A22B3BF664A39407631F9A166 ``` {% /tab %} @@ -76,39 +76,43 @@ An example of a successful response: ```json { "result": { - "ledger_hash": "31E9E3738E9A07219E49BC7B71E2CD9490AC3CDFB6CB2FD4F173FB8AE1619B34", - "ledger_index": 11, - "validated": true, + "ledger_current_index": 222403, + "validated": false, "vault": { - "Account": "rhXGX3ecZ8Gqxj9cCZBnJHzcoHfzMJijtV", + "Account": "rwCNM7SeUHTajEBQDiNqxDG8p1Mreizw85", "Asset": { - "mpt_issuance_id": "000000065E7AE0F677CFC3478DD710CD900EE92B99AB5B7A" + "currency": "USD", + "issuer": "rXJSJiZMxaLuH3kQBUV5DLipnYtrE6iVb" }, "AssetsAvailable": "0", + "AssetsMaximum": "1000000", "AssetsTotal": "0", + "Data": "5661756C74206D65746164617461", "Flags": 0, "LedgerEntryType": "Vault", "LossUnrealized": "0", - "Owner": "rwhaYGnJMexktjhxAKzRwoCcQ2g6hvBDWu", + "Owner": "rNGHoQwNG753zyfDrib4qDvvswbrtmV8Es", "OwnerNode": "0", - "PreviousTxnID": "B1F81724FA751966AC1B6A257815D8135F608A74A75C6ED3E29C3E9F5D8DB2D7", - "PreviousTxnLgrSeq": 10, - "Sequence": 4, - "ShareMPTID": "0000000126A1CFADAB543B2A1D81D2ACC22FBEC14231F81D", + "PreviousTxnID": "39CBBE3629AD9ADF9BA5CBAC5BF18665E785D0B199D2B2773A8A1EAA6CBC622B", + "PreviousTxnLgrSeq": 219033, + "Scale": 6, + "Sequence": 200370, + "ShareMPTID": "0000000169F415C9F1AB6796AB9224CE635818AFD74F8175", "WithdrawalPolicy": 1, - "index": "C043BB1B350FFC5FED21E40535609D3D95BC0E3CE252E2F69F85BE0157020A52", + "index": "45E6742527EDE6A2B537AE8A77B8D8CCFEFE115A22B3BF664A39407631F9A166", "shares": { - "DomainID": "3B61A239626565A3FBEFC32863AFBF1AD3325BD1669C2C9BC92954197842B564", + "AssetScale": 6, "Flags": 56, - "Issuer": "rhXGX3ecZ8Gqxj9cCZBnJHzcoHfzMJijtV", + "Issuer": "rwCNM7SeUHTajEBQDiNqxDG8p1Mreizw85", "LedgerEntryType": "MPTokenIssuance", + "MPTokenMetadata": "7B2274223A225473745368617265222C226E223A2254657374205661756C74205368617265222C2264223A22412074657374207661756C742073686172652E222C2269223A226578616D706C652E6F72672F73686172652D69636F6E2E706E67222C226163223A22727761222C226173223A22657175697479222C22696E223A224D53205465737420497373756572222C227573223A5B7B2275223A226578616D706C657969656C642E636F2F7473747368617265222C2263223A2277656273697465222C2274223A2250726F647563742050616765227D2C7B2275223A226578616D706C657969656C642E636F2F646F6373222C2263223A22646F6373222C2274223A225969656C6420546F6B656E20446F6373227D5D2C226169223A7B22766F6C6174696C697479223A226C6F77227D7D", "OutstandingAmount": "0", "OwnerNode": "0", - "PreviousTxnID": "B1F81724FA751966AC1B6A257815D8135F608A74A75C6ED3E29C3E9F5D8DB2D7", - "PreviousTxnLgrSeq": 10, + "PreviousTxnID": "39CBBE3629AD9ADF9BA5CBAC5BF18665E785D0B199D2B2773A8A1EAA6CBC622B", + "PreviousTxnLgrSeq": 219033, "Sequence": 1, - "index": "5D316FC6A8C5D2344F5A85E256DCBF06A9596C79B2F450ED7BF4E7E8442F8668", - "mpt_issuance_id": "0000000126A1CFADAB543B2A1D81D2ACC22FBEC14231F81D" + "index": "10D193CFF4619D2C7D552746A8C9F76AD6335E6D4452712CB39F8C7F096AE474", + "mpt_issuance_id": "0000000169F415C9F1AB6796AB9224CE635818AFD74F8175" } } }, @@ -124,43 +128,47 @@ An example of a successful response: { "result": { - "ledger_hash": "31E9E3738E9A07219E49BC7B71E2CD9490AC3CDFB6CB2FD4F173FB8AE1619B34", - "ledger_index": 11, - "validated": true, + "ledger_current_index": 222403, + "status": "success", + "validated": false, "vault": { - "Account": "rhXGX3ecZ8Gqxj9cCZBnJHzcoHfzMJijtV", + "Account": "rwCNM7SeUHTajEBQDiNqxDG8p1Mreizw85", "Asset": { - "mpt_issuance_id": "000000065E7AE0F677CFC3478DD710CD900EE92B99AB5B7A" + "currency": "USD", + "issuer": "rXJSJiZMxaLuH3kQBUV5DLipnYtrE6iVb" }, "AssetsAvailable": "0", + "AssetsMaximum": "1000000", "AssetsTotal": "0", + "Data": "5661756C74206D65746164617461", "Flags": 0, "LedgerEntryType": "Vault", "LossUnrealized": "0", - "Owner": "rwhaYGnJMexktjhxAKzRwoCcQ2g6hvBDWu", + "Owner": "rNGHoQwNG753zyfDrib4qDvvswbrtmV8Es", "OwnerNode": "0", - "PreviousTxnID": "B1F81724FA751966AC1B6A257815D8135F608A74A75C6ED3E29C3E9F5D8DB2D7", - "PreviousTxnLgrSeq": 10, - "Sequence": 4, - "ShareMPTID": "0000000126A1CFADAB543B2A1D81D2ACC22FBEC14231F81D", + "PreviousTxnID": "39CBBE3629AD9ADF9BA5CBAC5BF18665E785D0B199D2B2773A8A1EAA6CBC622B", + "PreviousTxnLgrSeq": 219033, + "Scale": 6, + "Sequence": 200370, + "ShareMPTID": "0000000169F415C9F1AB6796AB9224CE635818AFD74F8175", "WithdrawalPolicy": 1, - "index": "C043BB1B350FFC5FED21E40535609D3D95BC0E3CE252E2F69F85BE0157020A52", + "index": "45E6742527EDE6A2B537AE8A77B8D8CCFEFE115A22B3BF664A39407631F9A166", "shares": { - "DomainID": "3B61A239626565A3FBEFC32863AFBF1AD3325BD1669C2C9BC92954197842B564", + "AssetScale": 6, "Flags": 56, - "Issuer": "rhXGX3ecZ8Gqxj9cCZBnJHzcoHfzMJijtV", + "Issuer": "rwCNM7SeUHTajEBQDiNqxDG8p1Mreizw85", "LedgerEntryType": "MPTokenIssuance", + "MPTokenMetadata": "7B2274223A225473745368617265222C226E223A2254657374205661756C74205368617265222C2264223A22412074657374207661756C742073686172652E222C2269223A226578616D706C652E6F72672F73686172652D69636F6E2E706E67222C226163223A22727761222C226173223A22657175697479222C22696E223A224D53205465737420497373756572222C227573223A5B7B2275223A226578616D706C657969656C642E636F2F7473747368617265222C2263223A2277656273697465222C2274223A2250726F647563742050616765227D2C7B2275223A226578616D706C657969656C642E636F2F646F6373222C2263223A22646F6373222C2274223A225969656C6420546F6B656E20446F6373227D5D2C226169223A7B22766F6C6174696C697479223A226C6F77227D7D", "OutstandingAmount": "0", "OwnerNode": "0", - "PreviousTxnID": "B1F81724FA751966AC1B6A257815D8135F608A74A75C6ED3E29C3E9F5D8DB2D7", - "PreviousTxnLgrSeq": 10, + "PreviousTxnID": "39CBBE3629AD9ADF9BA5CBAC5BF18665E785D0B199D2B2773A8A1EAA6CBC622B", + "PreviousTxnLgrSeq": 219033, "Sequence": 1, - "index": "5D316FC6A8C5D2344F5A85E256DCBF06A9596C79B2F450ED7BF4E7E8442F8668", - "mpt_issuance_id": "0000000126A1CFADAB543B2A1D81D2ACC22FBEC14231F81D" + "index": "10D193CFF4619D2C7D552746A8C9F76AD6335E6D4452712CB39F8C7F096AE474", + "mpt_issuance_id": "0000000169F415C9F1AB6796AB9224CE635818AFD74F8175" } } - }, - "status": "success" + } } ``` {% /tab %} @@ -172,39 +180,43 @@ Connecting to 127.0.0.1:5005 { "result": { - "ledger_hash": "31E9E3738E9A07219E49BC7B71E2CD9490AC3CDFB6CB2FD4F173FB8AE1619B34", - "ledger_index": 11, - "validated": true, + "ledger_current_index": 222403, + "validated": false, "vault": { - "Account": "rhXGX3ecZ8Gqxj9cCZBnJHzcoHfzMJijtV", + "Account": "rwCNM7SeUHTajEBQDiNqxDG8p1Mreizw85", "Asset": { - "mpt_issuance_id": "000000065E7AE0F677CFC3478DD710CD900EE92B99AB5B7A" + "currency": "USD", + "issuer": "rXJSJiZMxaLuH3kQBUV5DLipnYtrE6iVb" }, "AssetsAvailable": "0", + "AssetsMaximum": "1000000", "AssetsTotal": "0", + "Data": "5661756C74206D65746164617461", "Flags": 0, "LedgerEntryType": "Vault", "LossUnrealized": "0", - "Owner": "rwhaYGnJMexktjhxAKzRwoCcQ2g6hvBDWu", + "Owner": "rNGHoQwNG753zyfDrib4qDvvswbrtmV8Es", "OwnerNode": "0", - "PreviousTxnID": "B1F81724FA751966AC1B6A257815D8135F608A74A75C6ED3E29C3E9F5D8DB2D7", - "PreviousTxnLgrSeq": 10, - "Sequence": 4, - "ShareMPTID": "0000000126A1CFADAB543B2A1D81D2ACC22FBEC14231F81D", + "PreviousTxnID": "39CBBE3629AD9ADF9BA5CBAC5BF18665E785D0B199D2B2773A8A1EAA6CBC622B", + "PreviousTxnLgrSeq": 219033, + "Scale": 6, + "Sequence": 200370, + "ShareMPTID": "0000000169F415C9F1AB6796AB9224CE635818AFD74F8175", "WithdrawalPolicy": 1, - "index": "C043BB1B350FFC5FED21E40535609D3D95BC0E3CE252E2F69F85BE0157020A52", + "index": "45E6742527EDE6A2B537AE8A77B8D8CCFEFE115A22B3BF664A39407631F9A166", "shares": { - "DomainID": "3B61A239626565A3FBEFC32863AFBF1AD3325BD1669C2C9BC92954197842B564", + "AssetScale": 6, "Flags": 56, - "Issuer": "rhXGX3ecZ8Gqxj9cCZBnJHzcoHfzMJijtV", + "Issuer": "rwCNM7SeUHTajEBQDiNqxDG8p1Mreizw85", "LedgerEntryType": "MPTokenIssuance", + "MPTokenMetadata": "7B2274223A225473745368617265222C226E223A2254657374205661756C74205368617265222C2264223A22412074657374207661756C742073686172652E222C2269223A226578616D706C652E6F72672F73686172652D69636F6E2E706E67222C226163223A22727761222C226173223A22657175697479222C22696E223A224D53205465737420497373756572222C227573223A5B7B2275223A226578616D706C657969656C642E636F2F7473747368617265222C2263223A2277656273697465222C2274223A2250726F647563742050616765227D2C7B2275223A226578616D706C657969656C642E636F2F646F6373222C2263223A22646F6373222C2274223A225969656C6420546F6B656E20446F6373227D5D2C226169223A7B22766F6C6174696C697479223A226C6F77227D7D", "OutstandingAmount": "0", "OwnerNode": "0", - "PreviousTxnID": "B1F81724FA751966AC1B6A257815D8135F608A74A75C6ED3E29C3E9F5D8DB2D7", - "PreviousTxnLgrSeq": 10, + "PreviousTxnID": "39CBBE3629AD9ADF9BA5CBAC5BF18665E785D0B199D2B2773A8A1EAA6CBC622B", + "PreviousTxnLgrSeq": 219033, "Sequence": 1, - "index": "5D316FC6A8C5D2344F5A85E256DCBF06A9596C79B2F450ED7BF4E7E8442F8668", - "mpt_issuance_id": "0000000126A1CFADAB543B2A1D81D2ACC22FBEC14231F81D" + "index": "10D193CFF4619D2C7D552746A8C9F76AD6335E6D4452712CB39F8C7F096AE474", + "mpt_issuance_id": "0000000169F415C9F1AB6796AB9224CE635818AFD74F8175" } } }, @@ -232,7 +244,7 @@ The `vault` field is an object describing the current status of a Vault entry in | `Field` | Type | Description | | :--------------------- | :------------------- | :---------- | | `Account` | String - [Address][] | The address of the vault's pseudo-account. | -| `Asset` | Object | The [Asset](#asset-object) of the vault. An asset can be XRP, a Fungible Token, or an MPT. | +| `Asset` | Object | The [Asset](#asset-object) of the vault. An asset can be XRP, a trust line token, or an MPT. | | `AssetsAvailable` | Number | The asset amount that is available in the vault. | | `AssetsMaximum` | Number | The maximum asset amount that can be held in the vault. If set to 0, this indicates there is no cap. | | `AssetsTotal` | Number | The total value of the vault. | @@ -242,6 +254,7 @@ The `vault` field is an object describing the current status of a Vault entry in | `WithdrawalPolicy` | String | Indicates the withdrawal strategy used by the vault. | | `index` | String | The unique index of the vault ledger entry. | | `shares` | Object | A [**Shares Object**](#shares-object) containing details about the vault's issued shares. | +| `Scale` | Number | Specifies decimal precision for share calculations. Assets are multiplied by 10Scale to convert fractional amounts into whole number shares. For example, with a `Scale` of `6`, depositing 20.3 units creates 20,300,000 shares (20.3 × 10Scale). For **trust line tokens** this can be configured at vault creation, and valid values are between 0-18, with the default being `6`. For **XRP** and **MPTs**, this is fixed at `0`. | ### Asset Object @@ -251,7 +264,7 @@ The `asset` object contains the following nested fields: | :--------------------- | :------------------- | :---------- | | `currency` | String | _(Omitted if the asset is an MPT)_ The currency code of the asset stored in the vault. | | `issuer` | String - [Address][] | _(Omitted if the asset is XRP or an MPT)_ The address of the asset issuer. | -| `mpt_issuance_id` | String | _(Omitted if the asset is XRP or a Fungible Token)_ The identifier of the asset's `MPTokenIssuance` object. | +| `mpt_issuance_id` | String | _(Omitted if the asset is XRP or a trust line token)_ The identifier of the asset's `MPTokenIssuance` object. | ### Shares Object @@ -270,6 +283,7 @@ The `shares` object contains the following nested fields: | `Sequence` | Number | The transaction sequence number that created the shares. | | `index` | String | The unique index of the shares ledger entry. | | `mpt_issuance_id` | String | The identifier of the `MPTokenIssuance` object. This is always equal to the vault's `ShareMPTID`. | +| `AssetScale` | Number | The decimal precision for share calculations. | ## Possible Errors diff --git a/docs/xls-65d-single-asset-vault/reference/mptoken.md b/docs/xls-65d-single-asset-vault/reference/mptoken.md index af761f61..fa8fd4e3 100644 --- a/docs/xls-65d-single-asset-vault/reference/mptoken.md +++ b/docs/xls-65d-single-asset-vault/reference/mptoken.md @@ -20,7 +20,7 @@ There are no changes to the fields in the {% code-page-name /%} object. See [MPT ## {% $frontmatter.seo.title %} Flags -The following flags are set based on whether the vault is public or private: +The following flags are set based on whether the shares are transferable, and if the vault is public or private: | **Condition** | **Transferable** | **Non-Transferable** | | ----------------- | ------------------ | -------------------- | diff --git a/docs/xls-65d-single-asset-vault/reference/transactions/vaultclawback.md b/docs/xls-65d-single-asset-vault/reference/transactions/vaultclawback.md index 88764979..df482e61 100644 --- a/docs/xls-65d-single-asset-vault/reference/transactions/vaultclawback.md +++ b/docs/xls-65d-single-asset-vault/reference/transactions/vaultclawback.md @@ -1,6 +1,6 @@ --- seo: - description: Allows the issuer of a Fungible Token or MPT to claw back funds from the vault. + description: Allows the issuer of a trust line token or MPT to claw back funds from the vault. labels: - Transactions - Single Asset Vault @@ -8,7 +8,7 @@ labels: # VaultClawback -[[Source]](https://github.com/Bronek/rippled/blob/vault/src/xrpld/app/tx/detail/VaultClawback.cpp "Source") +[[Source]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/VaultClawback.cpp "Source") Performs a [Clawback](https://xrpl.org/docs/use-cases/tokenization/stablecoin-issuer#clawback) from the vault, exchanging the shares of an account for assets. @@ -57,7 +57,7 @@ Besides errors that can occur for all transactions, {% code-page-name /%} transa | Error Code | Description | | :---------------------- | :---------- | | `tecNO_ENTRY` | The `Vault` object with the specified `VaultID` does not exist on the ledger. | -| `tecNO_PERMISSION` | The transaction attempts to claw back XRP, or the asset is a Fungible Token or MPT and the transaction isn't submitted by the issuing account. | +| `tecNO_PERMISSION` | The transaction attempts to claw back XRP, or the asset is a trust line token or MPT and the transaction isn't submitted by the issuing account. | | `tecWRONG_ASSET` | The asset in the transaction does not match the vault's asset type. | | `tecINSUFFICIENT_FUNDS` | The `MPToken` object for the vault share of the `Holder` account does not exist, or the `MPToken.MPTAmount` is 0. | | `temDISABLED` | The Single Asset Vault amendment is not enabled. | diff --git a/docs/xls-65d-single-asset-vault/reference/transactions/vaultcreate.md b/docs/xls-65d-single-asset-vault/reference/transactions/vaultcreate.md index 562698f8..24507dce 100644 --- a/docs/xls-65d-single-asset-vault/reference/transactions/vaultcreate.md +++ b/docs/xls-65d-single-asset-vault/reference/transactions/vaultcreate.md @@ -8,7 +8,7 @@ labels: # VaultCreate -[[Source]](https://github.com/Bronek/rippled/blob/vault/src/xrpld/app/tx/detail/VaultCreate.cpp "Source") +[[Source]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/VaultCreate.cpp "Source") Creates a new `Vault` ledger entry, an `MPTokenIssuance` ledger entry for the vault’s shares, and an `AccountRoot` for the vault’s [pseudo-account](../../concepts/pseudo-account.md). @@ -25,20 +25,19 @@ _(Requires the [Single Asset Vault amendment][] {% not-enabled /%})_ ```json { "TransactionType": "VaultCreate", - "Account": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX", - "Fee": "12", - "Flags": 0, - "LastLedgerSequence": 7108682, - "Sequence": 8, - "Data": "5468697320697320617262697472617279206D657461646174612061626F757420746865207661756C742E", + "Account": "rNGHoQwNG753zyfDrib4qDvvswbrtmV8Es", "Asset": { "currency": "USD", - "issuer": "rIssuer1234567890abcdef1234567890abcdef", + "issuer": "rXJSJiZMxaLuH3kQBUV5DLipnYtrE6iVb" }, - "AssetsMaximum": 0, - "MPTokenMetadata": "5468697320697320617262697472617279206d657461646174612061626f757420746865204d50542073686172652e", - "WithdrawalPolicy": "1", - "DomainID": "77D6234D074E505024D39C04C3F262997B773719AB29ACFA83119E4210328776" + "AssetsMaximum": "1000000", + "Data": "5661756C74206D65746164617461", + "Fee": "5000000", + "Flags": 0, + "MPTokenMetadata": "7B2274223A225473745368617265222C226E223A2254657374205661756C74205368617265222C2264223A22412074657374207661756C742073686172652E222C2269223A226578616D706C652E6F72672F73686172652D69636F6E2E706E67222C226163223A22727761222C226173223A22657175697479222C22696E223A224D53205465737420497373756572222C227573223A5B7B2275223A226578616D706C657969656C642E636F2F7473747368617265222C2263223A2277656273697465222C2274223A2250726F647563742050616765227D2C7B2275223A226578616D706C657969656C642E636F2F646F6373222C2263223A22646F6373222C2274223A225969656C6420546F6B656E20446F6373227D5D2C226169223A7B22766F6C6174696C697479223A226C6F77227D7D", + "Scale": 6, + "Sequence": 200370, + "WithdrawalPolicy": 1 } ``` @@ -49,11 +48,12 @@ In addition to the [common fields](https://xrpl.org/docs/references/protocol/tra | Field Name | JSON Type | [Internal Type][] | Required? |Description | |:-------------------|:--------------|:------------------|:----------|:------------------| | `Data` | String | Blob | No | Arbitrary vault metadata, in hex format, limited to 256 bytes. | -| `Asset` | Object | Issue | Yes | The asset to be held in the vault. This can be XRP, a Fungible Token, or an MPT. If the asset is a Fungible Token, the transaction creates a [trust line](https://xrpl.org/docs/concepts/tokens/fungible-tokens#trust-lines) between the vault's pseudo-account and the issuer of the asset. If the asset is an MPT, the transaction creates an `MPToken` object for the vault's pseudo-account. | -| `AssetsMaximum` | Number | UInt64 | No | The maximum asset amount that can be held in a vault. | -| `MPTokenMetadata` | String | Blob | No | Arbitrary metadata about the share `MPToken`, in hex format, limited to 1024 bytes. Use this field if the vault's asset is an MPT. | +| `Asset` | Object | Issue | Yes | The asset to be held in the vault. This can be XRP, a trust line token, or an MPT. If the asset is a trust line token, the transaction creates a [trust line](https://xrpl.org/docs/concepts/tokens/fungible-tokens#trust-lines) between the vault's pseudo-account and the issuer of the asset. If the asset is an MPT, the transaction creates an `MPToken` object for the vault's pseudo-account. | +| `AssetsMaximum` | Number | UInt64 | No | The maximum asset amount that can be held in a vault. | +| `MPTokenMetadata` | String | Blob | No | Arbitrary metadata about the share `MPToken`, in hex format, limited to 1024 bytes. | | `WithdrawalPolicy` | Number | UInt8 | No | Indicates the withdrawal strategy used by the vault. The default value is `0x0001`, mapped to the string `vaultStrategyFirstComeFirstServe`. See [WithdrawalPolicy](#withdrawalpolicy). | | `DomainID` | String | Hash256 | No | The [PermissionedDomain](https://github.com/XRPLF/XRPL-Standards/blob/master/XLS-0080-permissioned-domains/) object ID associated with the shares of this vault. If provided, the transaction creates a private vault, which restricts access to accounts with [credentials](https://github.com/XRPLF/XRPL-Standards/tree/master/XLS-0070-credentials) in the specified Permissioned Domain. | +| `Scale` | Number | UInt8 | No | _(Trust line tokens only)_ Specifies decimal precision for share calculations. Assets are multiplied by 10Scale to convert fractional amounts into whole number shares. For example, with a `Scale` of `6`, depositing 20.3 units creates 20,300,000 shares (20.3 × 10Scale). For **trust line tokens** this can be configured at vault creation, and valid values are between 0-18, with the default being `6`. For **XRP** and **MPTs**, this is fixed at `0`.| ## {% $frontmatter.seo.title %} Flags diff --git a/docs/xls-65d-single-asset-vault/reference/transactions/vaultdelete.md b/docs/xls-65d-single-asset-vault/reference/transactions/vaultdelete.md index 14c4e48f..336a2f0b 100644 --- a/docs/xls-65d-single-asset-vault/reference/transactions/vaultdelete.md +++ b/docs/xls-65d-single-asset-vault/reference/transactions/vaultdelete.md @@ -8,9 +8,9 @@ labels: # VaultDelete -[[Source]](https://github.com/Bronek/rippled/blob/vault/src/xrpld/app/tx/detail/VaultDelete.cpp "Source") +[[Source]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/VaultDelete.cpp "Source") -Permanently deletes an existing `Vault` object from the ledger, removes all associated ledger entries, and returns the owner reserve to the Vault Owner. +Permanently deletes an existing `Vault` object from the ledger, removes all associated ledger entries, and frees up the reserve requirement for the Vault Owner. Only the Vault Owner can initiate this transaction, and the vault must be completely empty before deletion. diff --git a/docs/xls-65d-single-asset-vault/reference/transactions/vaultdeposit.md b/docs/xls-65d-single-asset-vault/reference/transactions/vaultdeposit.md index 14fcb5b6..c07fe5cd 100644 --- a/docs/xls-65d-single-asset-vault/reference/transactions/vaultdeposit.md +++ b/docs/xls-65d-single-asset-vault/reference/transactions/vaultdeposit.md @@ -8,7 +8,7 @@ labels: # VaultDeposit -[[Source]](https://github.com/Bronek/rippled/blob/vault/src/xrpld/app/tx/detail/VaultDeposit.cpp "Source") +[[Source]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/VaultDeposit.cpp "Source") Deposits a specified number of assets into a vault in exchange for shares. @@ -20,7 +20,7 @@ Public vaults require no authorization, and anyone can deposit as long as they m A depositor cannot deposit assets into the vault if: - The asset is frozen for the depositor. -- The trust line or the `MPToken` between the pseudo-account and the issuer of the vault asset is frozen or locked. +- The trust line between the pseudo-account and the issuer is frozen, or the `MPToken` is locked. - The vault is private and the depositor's credentials have expired. {% /admonition %} @@ -59,7 +59,7 @@ In addition to the [common fields](https://xrpl.org/docs/references/protocol/tra The deposited asset must match the vault’s designated asset for the transaction to succeed. Depending on the asset type, the following changes occur: - **XRP**: The vault’s pseudo-account balance increases, and the depositor’s balance decreases. -- **Fungible Token**: The [trust line](https://xrpl.org/docs/concepts/tokens/fungible-tokens#trust-lines) balance between the vault's pseudo-account and the asset issuer is adjusted. +- **Trust line token**: The [trust line](https://xrpl.org/docs/concepts/tokens/fungible-tokens#trust-lines) balance between the vault's pseudo-account and the asset issuer is adjusted. - **MPT**: The `MPToken.MPTAmount` of both the depositor and the vault's pseudo-account is updated. ## {% $frontmatter.seo.title %} Flags diff --git a/docs/xls-65d-single-asset-vault/reference/transactions/vaultset.md b/docs/xls-65d-single-asset-vault/reference/transactions/vaultset.md index 1bda0aef..ffe4cbd1 100644 --- a/docs/xls-65d-single-asset-vault/reference/transactions/vaultset.md +++ b/docs/xls-65d-single-asset-vault/reference/transactions/vaultset.md @@ -8,7 +8,7 @@ labels: # VaultSet -[[Source]](https://github.com/Bronek/rippled/blob/vault/src/xrpld/app/tx/detail/VaultSet.cpp "Source") +[[Source]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/VaultSet.cpp "Source") Modifies a single asset vault that you own. This transaction allows the Vault Owner to update certain mutable fields, including vault metadata and the maximum asset amount. @@ -44,7 +44,7 @@ In addition to the [common fields](https://xrpl.org/docs/references/protocol/tra | :---------------- | :-------- | :------------ | :-------- | :-------------------| | `VaultID` | String | Hash256 | Yes | The unique identifier of the vault that needs to be updated. | | `Data` | String | Blob | No | Arbitrary vault metadata, limited to 256 bytes. | -| `AssetsMaximum` | Number | UInt64 | No | The maximum asset amount that can be held in a vault. The value cannot be lower than the current `AssetsTotal`, unless the value is 0. | +| `AssetsMaximum` | Number | Number | No | The maximum asset amount that can be held in a vault. The value cannot be lower than the current `AssetsTotal`, unless the value is 0. | | `DomainID` | String | Hash256 | No | The [PermissionedDomain](https://github.com/XRPLF/XRPL-Standards/blob/master/XLS-0080-permissioned-domains/) object ID associated with the shares of this vault. The `DomainID` is only required when updating a private vault. | ## {% $frontmatter.seo.title %} Flags diff --git a/docs/xls-65d-single-asset-vault/reference/transactions/vaultwithdraw.md b/docs/xls-65d-single-asset-vault/reference/transactions/vaultwithdraw.md index f945a566..09f2411d 100644 --- a/docs/xls-65d-single-asset-vault/reference/transactions/vaultwithdraw.md +++ b/docs/xls-65d-single-asset-vault/reference/transactions/vaultwithdraw.md @@ -8,15 +8,15 @@ labels: # VaultWithdraw -[[Source]](https://github.com/Bronek/rippled/blob/vault/src/xrpld/app/tx/detail/VaultWithdraw.cpp "Source") +[[Source]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/VaultWithdraw.cpp "Source") -Redeem vault shares for assets. The amount of assets received depends on the [exchange rate](../../concepts/single-asset-vault.md#exchange-algorithm), which adjusts based on the vault’s total assets and any [unrealized losses](../../concepts/single-asset-vault.md#paper-loss-unrealized-loss). +Redeem vault shares for assets. The amount of assets received depends on the [exchange rate](../../concepts/single-asset-vault.md#exchange-algorithm), which adjusts based on the vault’s total assets and any [unrealized losses](../../concepts/single-asset-vault.md#unrealized-loss). {% admonition type="info" name="Note" %} The `VaultWithdraw` transaction does not respect the Permissioned Domain rules. In other words, any account that holds the shares of the vault can redeem them. This is to avoid a situation where a depositor deposits assets to a private vault to then have their access revoked by invalidating their credentials, and thus losing access to their funds. {% /admonition %} -A depositor cannot redeem liquidity if the trust line or the `MPToken` between the pseudo-account and the issuer of the vault asset is frozen or locked. +A depositor cannot redeem liquidity if the trust line between the pseudo-account and the issuer of the vault asset is frozen, or the `MPToken` is locked. _(Requires the [Single Asset Vault amendment][] {% not-enabled /%})_ @@ -25,14 +25,16 @@ _(Requires the [Single Asset Vault amendment][] {% not-enabled /%})_ ```json { "TransactionType": "VaultWithdraw", - "Account": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX", + "Account": "rGFBE8WA2ZKfqGGB7CFkLusVt7hsVT4r8H", + "Amount": { + "mpt_issuance_id": "000000016E1417CA9DFD23400B05E43FDE5BB8D8FFA817CA", + "value": "5" + }, + "Destination": "rGFBE8WA2ZKfqGGB7CFkLusVt7hsVT4r8H", "Fee": "12", "Flags": 0, - "LastLedgerSequence": 7108682, - "Sequence": 8, - "VaultID": "77D6234D074E505024D39C04C3F262997B773719AB29ACFA83119E4210328776", - "Amount" : "10000", - "Destination": "ruazs5h1qEsqpke88pcqnaseXdm6od2xc" + "Sequence": 200380, + "VaultID": "A7B7B3ED3F5BD8E58C9064278EB29519CD6475D87A4517707DE108E65AE9C08C", } ``` @@ -45,6 +47,7 @@ In addition to the [common fields](https://xrpl.org/docs/references/protocol/tra | `VaultID` | String | Hash256 | Yes | The unique identifier of the vault to which the assets are deposited. | | `Amount` | Number | Amount | Yes | The exact amount of vault asset to withdraw or vault share to redeem. | | `Destination` | String | AccountID | No | An account to receive the assets. This account must be able to receive the vault asset or the transaction fails. | +| `DestinationTag` | Number | UInt32 | No | Arbitrary tag identifying the reason for the withdrawal to the destination. | There are two ways to specify the transaction `Amount` field: diff --git a/docs/xls-65d-single-asset-vault/reference/vault.md b/docs/xls-65d-single-asset-vault/reference/vault.md index 95bdc497..3a6eb7f3 100644 --- a/docs/xls-65d-single-asset-vault/reference/vault.md +++ b/docs/xls-65d-single-asset-vault/reference/vault.md @@ -8,7 +8,7 @@ labels: # Vault -[[Source]](https://github.com/Bronek/rippled/blob/vault/include/xrpl/protocol/detail/ledger_entries.macro#L465-L486 "Source") +[[Source]](https://github.com/XRPLF/rippled/blob/master/include/xrpl/protocol/detail/ledger_entries.macro#L484-L504 "Source") A {% code-page-name /%} object defines the state of a tokenized vault. It contains key details such as available assets, shares, total value, and other relevant information. You can create a {% code-page-name /%} object with the [VaultCreate](./transactions/vaultcreate.md) transaction. @@ -22,24 +22,23 @@ _(Requires the [Single Asset Vault amendment][] {% not-enabled /%})_ ```json { "LedgerEntryType": "Vault", - "LedgerIndex": "E123F4567890ABCDE123F4567890ABCDEF1234567890ABCDEF1234567890ABCD", - "Flags": "0", - "PreviousTxnID": "9A8765B4321CDE987654321CDE987654321CDE987654321CDE987654321CDE98", - "PreviousTxnLgrSeq": 12345678, - "Sequence": 1, - "OwnerNode": 2, - "Owner": "rEXAMPLE9AbCdEfGhIjKlMnOpQrStUvWxYz", - "Account": "rPseudoAcc1234567890abcdef1234567890abcdef", - "Data": "5468697320697320617262697472617279206D657461646174612061626F757420746865207661756C742E", + "Account": "rwCNM7SeUHTajEBQDiNqxDG8p1Mreizw85", "Asset": { - "currency": "USD", - "issuer": "rIssuer1234567890abcdef1234567890abcdef", + "currency": "USD", + "issuer": "rXJSJiZMxaLuH3kQBUV5DLipnYtrE6iVb" }, - "AssetsTotal": 1000000, - "AssetsAvailable": 800000, - "LossUnrealized": 200000, - "AssetsMaximum": 0, - "WithdrawalPolicy": "1" + "AssetsAvailable": "0", + "AssetsMaximum": "1000000", + "AssetsTotal": "0", + "Data": "5661756C74206D65746164617461", + "Flags": 0, + "LossUnrealized": "0", + "Owner": "rNGHoQwNG753zyfDrib4qDvvswbrtmV8Es", + "OwnerNode": "0", + "Scale": 6, + "Sequence": 200370, + "ShareMPTID": "0000000169F415C9F1AB6796AB9224CE635818AFD74F8175", + "WithdrawalPolicy": 1, } ``` @@ -59,14 +58,30 @@ In addition to the [common ledger entry fields](https://xrpl.org/docs/references | `Owner` | String | AccountID | Yes | The account address of the Vault Owner. | | `Account` | String | AccountID | Yes | The address of the vault's pseudo-account. | | `Data` | String | Blob | No | Arbitrary metadata about the vault. Limited to 256 bytes. | -| `Asset` | Object | Issue | Yes | The asset of the vault. The vault supports XRP, Fungible Tokens, and MPTs. | +| `Asset` | Object | Issue | Yes | The asset of the vault. The vault supports XRP, trust line tokens, and MPTs. | | `AssetsTotal` | Number | Number | Yes | The total value of the vault. | | `AssetsAvailable` | Number | Number | Yes | The asset amount that is available in the vault. | | `AssetsMaximum` | Number | Number | No | The maximum asset amount that can be held in the vault. If set to 0, this indicates there is no cap. | | `LossUnrealized` | Number | Number | Yes | The potential loss amount that is not yet realized, expressed as the vault's asset. Only a protocol connected to the vault can modify this attribute. | -| `MPTokenIssuanceID` | String | UInt192 | Yes | The identifier of the share `MPTokenIssuance` object. | +| `ShareMPTID` | String | UInt192 | Yes | The identifier of the share `MPTokenIssuance` object. | | `WithdrawalPolicy` | String | UInt8 | Yes | Indicates the withdrawal strategy used by the vault. | +| `Scale` | Number | UInt8 | No | Specifies decimal precision for share calculations. Assets are multiplied by 10Scale to convert fractional amounts into whole number shares. For example, with a `Scale` of `6`, depositing 20.3 units creates 20,300,000 shares (20.3 × 10Scale). For **trust line tokens** this can be configured at vault creation, and valid values are between 0-18, with the default being `6`. For **XRP** and **MPTs**, this is fixed at `0`. | +### Scaling Factor + +The **`Scale`** field enables the vault to accurately represent fractional asset values using integer-only MPT shares, which prevents the loss of value from decimal truncation. It defines a scaling factor, calculated as 10Scale, that converts a decimal asset amount into a corresponding whole number of shares. + +The scaling factor behavior varies by asset type: + +- **Trust line token**: When a vault holds a trust line token, the `Scale` is configurable by the Vault Owner when creating the vault. The value can range from **0** to a maximum of **18**, with a default of **6**. This flexibility allows issuers to set a level of precision appropriate for their specific token. + +- **XRP**: When a vault holds XRP, the `Scale` is fixed at **0**. This aligns with XRP's native structure, where one share represents one drop, and one XRP equals 1,000,000 drops. Therefore, a deposit of 10 XRP to an empty vault will result in the issuance of 10,000,000 shares. + +- **MPT**: When a vault holds an MPT, its `Scale` is fixed at **0**. This creates a 1-to-1 relationship between deposited MPT units and the shares issued. For example, depositing 10 MPTs to an empty vault issues 10 shares. The value of a single MPT is determined at the issuer's discretion. + + {% admonition type="warning" name="Warning" %} + If an MPT is set to represent a large value, the vault owner and the depositor must be cautious. Since only whole MPT units are used in calculations, any value that is not a multiple of a single MPT's value may be lost due to rounding during a transaction. + {% /admonition %} ## {% $frontmatter.seo.title %} Flags @@ -81,7 +96,7 @@ In addition to the [common ledger entry fields](https://xrpl.org/docs/references The ID of a {% code-page-name /%} entry is the [`SHA512-Half`](https://xrpl.org/docs/references/protocol/data-types/basic-data-types#hashes) of the following values, concatenated in order: - The {% code-page-name /%} space key `0x0056` (capital V). -- The [AccountID](https://xrpl.org/docs/references/protocol/binary-format/#accountid-fields) of the account submitting the `VaultSet` transaction (i.e., `VaultOwner`). +- The [AccountID](https://xrpl.org/docs/references/protocol/binary-format/#accountid-fields) of the account submitting the transaction (for example, the vault owner) . - The transaction `Sequence` number. If the transaction used a [Ticket](https://xrpl.org/docs/concepts/accounts/tickets), use the `TicketSequence` value. {% raw-partial file="/docs/_snippets/common-links.md" /%}