From 95fdc2eb8622b89780ace09e93d5758fa5adbb91 Mon Sep 17 00:00:00 2001 From: Vito <5780819+Tapanito@users.noreply.github.com> Date: Thu, 12 Feb 2026 14:11:32 +0100 Subject: [PATCH 1/5] adds VaultDepositBlock flag --- XLS-0065-single-asset-vault/README.md | 90 ++++++++++++++++++--------- 1 file changed, 62 insertions(+), 28 deletions(-) diff --git a/XLS-0065-single-asset-vault/README.md b/XLS-0065-single-asset-vault/README.md index 8496c717..d684d48f 100644 --- a/XLS-0065-single-asset-vault/README.md +++ b/XLS-0065-single-asset-vault/README.md @@ -137,9 +137,10 @@ 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. | ### 2.3 Vault `_pseudo-account_` @@ -429,35 +430,55 @@ The transaction creates an `AccountRoot` object for the `_pseudo-account_`. Ther The `VaultSet` updates an existing `Vault` ledger object. -### 4.1 Fields +### 4.1. Fields | Field Name | Required | JSON Type | Internal Type | Default Value | Description | | ----------------- | :------: | :-------: | :-----------: | :-----------: | :-------------------------------------------------------------------------------------------------------------------------------------- | | `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. | -### 4.2 Failure Conditions +### 4.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. | + +### 4.3. Failure Conditions + +#### 4.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`) -### 4.3 State Changes +#### 4.3.2. Protocol-Level Failures + +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. (`tecNO_PERMISSION`) + +### 4.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). -### 4.4 Invariants +### 4.5. Invariants **TBD** @@ -509,22 +530,35 @@ The `VaultDeposit` transaction adds Liqudity in exchange for vault shares. ### 6.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 + +1. `VaultID` is has a zero value. (`temMALFORMED`) +2. `Amount` is less or equal to zero. (`temBAD_AMOUNT`) + +#### 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. 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`) 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. `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`) 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). + 1. `lsfDefaultRipple` flag is not set on either the issuer or the depositor. (`terNO_RIPPLE`) + 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`) + +8. `Account` is not `Vault.Owner` and `Vault.lsfVaultDepositBlocked` flag is set (`tecNO_PERMISSION`) ### 6.3 State Changes From 71c23a3455d64e7dee61032d56a6699aa4776cae Mon Sep 17 00:00:00 2001 From: Vito <5780819+Tapanito@users.noreply.github.com> Date: Thu, 19 Feb 2026 12:06:24 +0100 Subject: [PATCH 2/5] fixes indexes --- XLS-0065-single-asset-vault/README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/XLS-0065-single-asset-vault/README.md b/XLS-0065-single-asset-vault/README.md index d684d48f..83e41fea 100644 --- a/XLS-0065-single-asset-vault/README.md +++ b/XLS-0065-single-asset-vault/README.md @@ -546,19 +546,21 @@ The `VaultDeposit` transaction adds Liqudity in exchange for vault shares. 1. If `Account` credentials are expired. (`tecEXPIRED`) 2. If `Account` does not have valid credentials. (`tecNO_AUTH`) -6. The `Vault.Asset` is `MPT`: +6. If vault is insolvent, `Vault.AssetsTotal = 0` and `MPTokenIssuance(Vault.ShareMPTID).OutstandingAmount > 0`. (`tecLOCKED`) + +7. 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`) -7. The `Asset` is an `IOU`: +8. The `Asset` is an `IOU`: 1. `lsfDefaultRipple` flag is not set on either the issuer or the depositor. (`terNO_RIPPLE`) 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`) -8. `Account` is not `Vault.Owner` and `Vault.lsfVaultDepositBlocked` flag is set (`tecNO_PERMISSION`) +9. `Account` is not `Vault.Owner` and `Vault.lsfVaultDepositBlocked` flag is set (`tecNO_PERMISSION`) ### 6.3 State Changes From ffa44a4c6a8826a7d176bdbb2d6e84bfd84a8895 Mon Sep 17 00:00:00 2001 From: Vito <5780819+Tapanito@users.noreply.github.com> Date: Thu, 19 Feb 2026 12:21:03 +0100 Subject: [PATCH 3/5] adds dnation functionality to vaultDeposit transaction --- XLS-0065-single-asset-vault/README.md | 36 +++++++++++++++++++-------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/XLS-0065-single-asset-vault/README.md b/XLS-0065-single-asset-vault/README.md index 83e41fea..e5041de1 100644 --- a/XLS-0065-single-asset-vault/README.md +++ b/XLS-0065-single-asset-vault/README.md @@ -527,6 +527,13 @@ 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. | ### 6.2 Failure conditions @@ -542,43 +549,50 @@ The `VaultDeposit` transaction adds Liqudity in exchange for vault shares. 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. The `Vault` `lsfVaultPrivate` flag is set and the `Account` is not `Vault.Owner`: +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`) -6. If vault is insolvent, `Vault.AssetsTotal = 0` and `MPTokenIssuance(Vault.ShareMPTID).OutstandingAmount > 0`. (`tecLOCKED`) +7. If vault is insolvent, `Vault.AssetsTotal = 0` and `MPTokenIssuance(Vault.ShareMPTID).OutstandingAmount > 0`. (`tecLOCKED`) -7. The `Vault.Asset` is `MPT`: +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`) -8. The `Asset` is an `IOU`: +9. The `Asset` is an `IOU`: 1. `lsfDefaultRipple` flag is not set on either the issuer or the depositor. (`terNO_RIPPLE`) 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`) -9. `Account` is not `Vault.Owner` and `Vault.lsfVaultDepositBlocked` flag is set (`tecNO_PERMISSION`) +10. `Account` is not `Vault.Owner` and `Vault.lsfVaultDepositBlocked` flag is set (`tecNO_PERMISSION`) +11. `Vault.AssetsTotal + Amount > Vault.AssetsMaximum`, deposit would exceed the maximum allowed amount. (`tecLIMIT_EXCEEDED`) ### 6.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`. From fcf415f41c38699170c57458e68eb3735294554f Mon Sep 17 00:00:00 2001 From: Vito <5780819+Tapanito@users.noreply.github.com> Date: Wed, 25 Feb 2026 13:05:53 +0100 Subject: [PATCH 4/5] adds lsfVaultOwnerCanBlockDeposit flag --- XLS-0065-single-asset-vault/README.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/XLS-0065-single-asset-vault/README.md b/XLS-0065-single-asset-vault/README.md index e5041de1..f9eb66fb 100644 --- a/XLS-0065-single-asset-vault/README.md +++ b/XLS-0065-single-asset-vault/README.md @@ -137,10 +137,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. | -| `lsfVaultDepositBlocked` | `0x00020000` | `No` | If set, indicates that deposits to a vault are blocked. | +| 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. | ### 2.3 Vault `_pseudo-account_` @@ -373,6 +374,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.3 WithdrawalPolicy @@ -466,7 +468,9 @@ The `VaultSet` updates an existing `Vault` ledger object. 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. (`tecNO_PERMISSION`) +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`) ### 4.4. State Changes @@ -571,7 +575,7 @@ The `VaultDeposit` transaction adds Liqudity in exchange for vault shares. 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. `Account` is not `Vault.Owner` and `Vault.lsfVaultDepositBlocked` flag is set (`tecNO_PERMISSION`) +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`) ### 6.3 State Changes From 676ae8d56c90344b123d31f33c419f0bb0070b7f Mon Sep 17 00:00:00 2001 From: Vito <5780819+Tapanito@users.noreply.github.com> Date: Wed, 25 Feb 2026 14:15:58 +0100 Subject: [PATCH 5/5] formatting --- XLS-0065-single-asset-vault/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/XLS-0065-single-asset-vault/README.md b/XLS-0065-single-asset-vault/README.md index 5dc0ab7c..8617bc25 100644 --- a/XLS-0065-single-asset-vault/README.md +++ b/XLS-0065-single-asset-vault/README.md @@ -116,7 +116,6 @@ The `Vault` object supports the following flags: | `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_` An AccountRoot entry holds the XRP, IOU or MPT deposited into the vault. It also acts as the issuer of the vault's shares. The _pseudo-account_ follows the XLS-64 specification for pseudo accounts. The `AccountRoot` object is created when creating the `Vault` object.