Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 90 additions & 36 deletions XLS-0065-single-asset-vault/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,11 @@ A vault has the following fields:

The `Vault` object supports the following flags:

| Flag Name | Flag Value | Modifiable? | Description |
| ----------------- | :----------: | :---------: | :------------------------------------------: |
| `lsfVaultPrivate` | `0x00010000` | No | If set, indicates that the vault is private. |
| Flag Name | Flag Value | Modifiable? | Description |
| ------------------------------ | :----------: | :---------: | :---------------------------------------------------------: |
| `lsfVaultPrivate` | `0x00010000` | `No` | If set, indicates that the vault is private. |
| `lsfVaultDepositBlocked` | `0x00020000` | `No` | If set, indicates that deposits to a vault are blocked. |
| `lsfVaultOwnerCanBlockDeposit` | `0x00040000` | `No` | If set, indicates that the Vault Owner can block a deposit. |

#### 3.1.3 Vault `_pseudo-account_`

Expand Down Expand Up @@ -389,6 +391,7 @@ The `VaultCreate` transaction creates a new `Vault` object.
| ----------------------------- | :----------: | :--------------------------------------------------------------------------------------- |
| `tfVaultPrivate` | `0x00010000` | Indicates that the vault is private. It can only be set during Vault creation. |
| `tfVaultShareNonTransferable` | `0x00020000` | Indicates the vault share is non-transferable. It can only be set during Vault creation. |
| `tfVaultOwnerCanBlockDeposit` | `0x00040000` | Indicates the vault owner can block deposits. It can only be set during Vault creation. |

##### 3.2.3 WithdrawalPolicy

Expand Down Expand Up @@ -472,37 +475,59 @@ The `VaultSet` updates an existing `Vault` ledger object.
| ----------------- | :------: | :-------: | :-----------: | :-----------: | :-------------------------------------------------------------------------------------------------------------------------------------- |
| `TransactionType` | Yes | `string` | `Uint16` | `59` | The transaction type. |
| `VaultID` | Yes | `string` | `Hash256` | `N/A` | The ID of the Vault to be modified. Must be included when updating the Vault. |
| `Flags` | No | `number` | `UINT32` | 0 | Specifies the flags for the Vault. |
| `Data` | No | `string` | `Blob` | | Arbitrary Vault metadata, limited to 256 bytes. |
| `AssetsMaximum` | No | `number` | `Number` | | 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` | No | `string` | `Hash256` | | The `PermissionedDomain` object ID associated with the shares of this Vault. |

#### 3.3.2 Failure Conditions
#### 3.3.2 Flags

1. `Vault` object with the specified `VaultID` does not exist on the ledger.
2. The submitting account is not the `Owner` of the vault.
3. The `Data` field is larger than 256 bytes.
4. If `Vault.AssetsMaximum` > `0` AND `AssetsMaximum` > 0 AND:
1. The `AssetsMaximum` < `Vault.AssetsTotal` (new `AssetsMaximum` cannot be lower than the current `AssetsTotal`).
5. The `sfVaultPrivate` flag is not set and the `DomainID` is provided (Vault Owner is attempting to set a PermissionedDomain to a public Vault).
6. The `PermissionedDomain` object does not exist with the provided `DomainID`.
7. The transaction is attempting to modify an immutable field.
8. The transaction does not specify any of the modifiable fields.
| Flag Name | Flag Value | Description |
| ----------------------- | :----------: | :------------------------------- |
| `tfVaultDepositBlock` | `0x00010000` | Block deposits into the vault. |
| `tfVaultDepositUnblock` | `0x00020000` | Unblock deposits into the vault. |

### 3.3.3 Failure Conditions

#### 3.3.3.1 Data Verification

1. `VaultID` is empty. (`temMALFORMED`)
2. The `Data` field is larger than 256 bytes (`temMALFORMED`)
3. `AssetsMaximum` is negative integer (`temMALFORMED`)
4. The transaction does not specify any of the modifiable fields. (`temMALFORMED`)
5. Both `tfVaultDepositBlock` and `tfVaultDepositUnblock` are set. (`temMALFORMED`)

#### 3.3.3.2 Protocol-Level Failures

#### 3.3.3 State Changes
1. `Vault` object with the specified `VaultID` does not exist on the ledger. (`tecNO_ENTRY`)
2. The submitting account is not the `Owner` of the vault. (`tecNO_PERMISSION`)
3. The `sfVaultPrivate` flag is not set and the `DomainID` is provided. (`tecNO_PERMISSION`)
4. The `PermissionedDomain` object does not exist with the provided `DomainID`. (`tecNO_OBJECT_NOT_FOUND`)
5. If `Vault.AssetsMaximum` > `0` AND `AssetsMaximum` > 0 AND:
1. The `AssetsMaximum` < `Vault.AssetsTotal` (new `AssetsMaximum` cannot be lower than the current `AssetsTotal`). (`tecLIMIT_EXCEEDED`)
6. `Vault.lsfVaultDepositBlocked` is set and `tfVaultDepositBlock` is set (cannot block an already blocked vault). (`tecNO_PERMISSION`)
7. `Vault.lsfVaultDepositBlocked` is **not** set and `tfVaultDepositUnblock` is set (cannot unblock an already unblocked vault). (`tecNO_PERMISSION`)
8. `Vault.lsfVaultOwnerCanBlockDeposit` is **not** set, and `tfVaultDepositBlock` or `tfVaultDepositUnblock` are set. (`tecNO_PERMISSION`)

#### 3.3.4 State Changes

1. Update mutable fields in the `Vault` ledger object.
2. If `DomainID` is provided:
1. Set `MPTokenIssuance(Vault.ShareMPTID).DomainID = DomainID` (Set the Permissioned Domain).
3. If `tfVaultDepositBlock` is provided:
1. Set `Vault.Flags |= lsfVaultDepositBlocked` flag (Block Deposits).
4. If `tfVaultDepositUnblock` is provided:
1. Set `Vault.Flags &= ~lsfVaultDepositBlocked` flag (Unblock Deposits).

#### 3.3.4 Invariants
#### 3.3.5 Invariants

- The _pseudo-account_ asset balance must not change.
- `<Vault>.AssetsTotal == <Vault>'.AssetsTotal` (assets total must not change).
- `<Vault>.AssetsAvailable == <Vault>'.AssetsAvailable` (assets available must not change).
- `IF <Vault>'.AssetsMaximum > 0 THEN <Vault>'.AssetsTotal <= <Vault>'.AssetsMaximum`.
- `MPTokenIssuance(Vault.ShareMPTID).OutstandingAmount` must not change.

#### 3.3.5 Example JSON
#### 3.3.6 Example JSON

```json
{
Expand Down Expand Up @@ -573,43 +598,72 @@ The `VaultDeposit` transaction adds Liqudity in exchange for vault shares.
| `TransactionType` | Yes | `string` | `UINT16` | `61` | Transaction type. |
| `VaultID` | Yes | `string` | `HASH256` | `N/A` | The ID of the vault to which the assets are deposited. |
| `Amount` | Yes | `string` or `object` | `STAmount` | `N/A` | Asset amount to deposit. |
| `Flags` | No | `number` | `UINT32` | 0 | Specifies additional flags for the transaction. |

### 6.1 Flags

| Flag Name | Flag Value | Description |
| --------------- | :----------: | :------------------------------- |
| `tfVaultDonate` | `0x00010000` | Donate the funds into the vault. |

#### 3.5.2 Failure Conditions

1. `Vault` object with the `VaultID` does not exist on the ledger.
2. The asset type of the vault does not match the asset type the depositor is depositing.
3. The depositor does not have sufficient funds to make a deposit.
4. Adding the `Amount` to the `AssetsTotal` of the vault would exceed the `AssetsMaximum`.
5. The `Vault` `lsfVaultPrivate` flag is set and the `Account` depositing the assets does not have credentials in the permissioned domain of the share.
#### 6.2.1. Data Verification

6. The `Vault.Asset` is `MPT`:
1. `MPTokenIssuance.lsfMPTCanTransfer` is not set (the asset is not transferable).
2. `MPTokenIssuance.lsfMPTLocked` flag is set (the asset is globally locked).
3. `MPToken(MPTokenIssuanceID, AccountID).lsfMPTLocked` flag is set (the asset is locked for the depositor).
4. `MPToken(MPTokenIssuanceID, AccountID).MPTAmount` < `Amount` (insufficient balance).
1. `VaultID` is has a zero value. (`temMALFORMED`)
2. `Amount` is less or equal to zero. (`temBAD_AMOUNT`)

7. The `Asset` is an `IOU`:
1. The `lsfGlobalFreeze` flag is set on the issuing account (the asset is frozen).
2. The `lsfHighFreeze` or `lsfLowFreeze` flag is set on the `RippleState` object between the Asset `Issuer` and the depositor.
3. The `RippleState` object `Balance` < `Amount` (insufficient balance).
#### 6.2.2. Protocol-Level Failures

1. `Vault` object with the `VaultID` does not exist on the ledger. (`tecNO_ENTRY`)
2. `Amount.Asset` does not match the asset type of the vault. (`tecWRONG_ASSET`)
3. The depositor does not have sufficient funds to make a deposit. (`tecINSUFFICIENT_FUNDS`)
4. Adding the `Amount` to the `AssetsTotal` of the vault would exceed the `AssetsMaximum` (`tecLIMIT_EXCEEDED`)

5. `tfVaultDonate` flag is set and:
1. `Account` submitting the transaction is not the vault owner. (`tecNO_PERMISSION`)
2. `MPTokenIssuance(Vault.ShareMPTID).OutstandingAmount == 0`, the Vault is empty. (`tecNO_PERMISSION`)

6. The `Vault` `lsfVaultPrivate` flag is set and the `Account` is not `Vault.Owner`:
1. If `Account` credentials are expired. (`tecEXPIRED`)
2. If `Account` does not have valid credentials. (`tecNO_AUTH`)

7. If vault is insolvent, `Vault.AssetsTotal = 0` and `MPTokenIssuance(Vault.ShareMPTID).OutstandingAmount > 0`. (`tecLOCKED`)

8. The `Vault.Asset` is `MPT`:
1. `MPTokenIssuance.lsfMPTCanTransfer` is not set (the asset is not transferable). (`tecNO_AUTH`)
2. `MPTokenIssuance.lsfMPTLocked` flag is set (the asset is globally locked) (`tecLOCKED`)
3. `MPToken(MPTokenIssuanceID, AccountID).lsfMPTLocked` flag is set (the asset is locked for the depositor). (`tecLOCKED`)
4. `MPToken(MPTokenIssuanceID, AccountID).MPTAmount` < `Amount` (insufficient balance). (`tecINSUFFICIENT_FUNDS`)

9. The `Asset` is an `IOU`:
1. `lsfDefaultRipple` flag is not set on either the issuer or the depositor. (`terNO_RIPPLE`)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's incorrect to check the default ripple flag during a transfer. You need to check the "no ripple" flag on the relevant trustlines.

2. The `lsfGlobalFreeze` flag is set on the issuing account (the asset is frozen). (`tecFROZEN`)
3. The `lsfHighFreeze` or `lsfLowFreeze` flag is set on the `RippleState` object between the Asset `Issuer` and the depositor. (`tecFROZEN`)
4. The `RippleState` object `Balance` < `Amount` (insufficient balance). (`tecINSUFFICIENT_FUNDS`)

10. `Vault.lsfVaultDepositBlocked` flag is set (deposits are not permitted). (`tecNO_PERMISSION`)
11. `Vault.AssetsTotal + Amount > Vault.AssetsMaximum`, deposit would exceed the maximum allowed amount. (`tecLIMIT_EXCEEDED`)

#### 3.5.3 State Changes

1. If no `MPToken` object exists for the depositor, create one. For object details, see [2.1.6.2 `MPToken`](#2162-mptoken).

2. Increase the `MPTAmount` field of the share `MPToken` object of the `Account` by $\Delta_{share}$.
3. Increase the `OutstandingAmount` field of the share `MPTokenIssuance` object by $\Delta_{share}$.
4. Increase the `AssetsTotal` and `AssetsAvailable` of the `Vault` by `Amount`.
2. If `tfVaultDonate` flag is **not** set:
1. Increase the `MPTAmount` field of the share `MPToken` object of the `Account` by $\Delta_{share}$.
2. Increase the `OutstandingAmount` field of the share `MPTokenIssuance` object by $\Delta_{share}$.

3. Increase the `AssetsTotal` and `AssetsAvailable` of the `Vault` by `Amount`.

5. If the `Vault.Asset` is `XRP`:
4. If the `Vault.Asset` is `XRP`:
1. Increase the `Balance` field of _pseudo-account_ `AccountRoot` by `Amount`.
2. Decrease the `Balance` field of the depositor `AccountRoot` by `Amount`.

6. If the `Vault.Asset` is an `IOU`:
5. If the `Vault.Asset` is an `IOU`:
1. Increase the `RippleState` balance between the _pseudo-account_ `AccountRoot` and the `Issuer` `AccountRoot` by `Amount`.
2. Decrease the `RippleState` balance between the depositor `AccountRoot` and the `Issuer` `AccountRoot` by `Amount`.

7. If the `Vault.Asset` is an `MPT`:
6. If the `Vault.Asset` is an `MPT`:
1. Increase the `MPToken.MPTAmount` by `Amount` of the _pseudo-account_ `MPToken` object for the `Vault.Asset`.
2. Decrease the `MPToken.MPTAmount` by `Amount` of the depositor `MPToken` object for the `Vault.Asset`.

Expand Down
Loading