Skip to content

Commit 1cc03db

Browse files
committed
updates the specification style to match new proposed strcuture and adds clarity around account reserves
1 parent 61c7dfa commit 1cc03db

File tree

1 file changed

+75
-61
lines changed

1 file changed

+75
-61
lines changed

XLS-0064d-pseudo-account/README.md

Lines changed: 75 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,108 @@
1-
<pre>
2-
Title: <b>Pseudo-Account</b>
3-
Type: <b>draft</b>
4-
Revision: <b>1</b> (2025-03-04)
1+
<pre>
2+
xls: 64
3+
title: Pseudo-Account
4+
description: A standard for a "pseudo-account" AccountRoot object to be associated with one or more ledger entries.
5+
author: Vito Tumas (@Tapanito)
6+
status: Draft
7+
category: Ammendment
8+
created: 2025-03-04
9+
updated: 2025-08-29
10+
</pre>
511

6-
<hr> Authors:
7-
<a href="mailto:vtumas@ripple.com">Vytautas Vito Tumas</a>
12+
### Abstract
813

9-
Affiliation:
10-
<a href="https://ripple.com">Ripple</a>
11-
</pre>
14+
This document proposes a standard for a *pseudo-account*, an `AccountRoot` ledger entry that can be associated with one or more other ledger entries. A pseudo-account is designed to hold and/or issue assets on behalf of its associated entries, enabling protocol-level functionality that requires an on-ledger entity to manage funds.
15+
16+
### Motivation
17+
18+
The XRP Ledger is an account-based system where assets (XRP, IOUs, etc.) can only be held by an `AccountRoot` entry. However, several advanced protocols, such as Automated Market Makers (AMMs), lending pools, and vaults, require a ledger *object* itself to hold and manage assets.
19+
20+
The [XLS-30 (AMM)](https://github.com/XRPLF/XRPL-Standards/tree/master/XLS-0030-automated-market-maker#readme) specification pioneered this concept by introducing a pseudo-account linked to each `AMM` instance. This allows the AMM to track its token balances and issue Liquidity Provider Tokens (`LPTokens`).
21+
22+
This specification formalizes and standardizes the requirements for an `AccountRoot` when it functions as a pseudo-account, ensuring a consistent and secure implementation across different protocols. It defines mandatory flags, a naming convention for linking fields, and the core invariants that any protocol using a pseudo-account must enforce.
23+
24+
### Specification
25+
26+
#### Ledger Entries
1227

13-
# Pseudo-Account
28+
This specification defines a set of mandatory properties and fields for an `AccountRoot` ledger entry when it is used as a pseudo-account.
1429

15-
## _Abstract_
30+
##### **`AccountRoot`**
1631

17-
In this document, we propose a standard for a _pseudo-account_, an `AccountRoot` object that can be associated with one or more other ledger entries to hold and/or issue assets on behalf of the associated entries.
32+
###### **Object Identifier**
1833

19-
## 1. Introduction
34+
The address of the pseudo-account's `AccountRoot` must be derived deterministically and be difficult to predict before creation. This prevents malicious actors from front-running the creation transaction by pre-funding the address. The protocol creating the `AccountRoot` must ensure the derived address is unoccupied.
2035

21-
The XRP Ledger is an account-based blockchain in which assets—such as XRP, IOUs, or MPT—can only be held by an account represented by an `AccountRoot` ledger entry. However, certain use cases, such as Automated Market Makers (AMM), Single Asset Vaults, and the Lending Protocol—require assets to be transferable to and from an object.
36+
A nonce-based approach is used to generate the unique `AccountRoot` ID:
2237

23-
The [XLS-30](https://github.com/XRPLF/XRPL-Standards/tree/master/XLS-0030-automated-market-maker#readme) specification introduced the `AMMID` field in the `AccountRoot` ledger entry. This field associates a _pseudo-account_ with an `AMM` instance, allowing it to track XRP and token balances in the pool and issue `LPTokens` on behalf of the `AMM` instance.
38+
1. Initialize a nonce, $i$, to $0$.
39+
2. Compute a candidate ID: `AccountID` = `SHA512-Half`($i$ || `ParentLedgerHash` || `<ObjectID>`).
40+
3. Check if an `AccountRoot` with this `AccountID` already exists on the ledger.
41+
4. If it exists, increment the nonce $i$ and repeat from step 2.
42+
5. If it does not exist, the computed `AccountID` is used for the new pseudo-account.
2443

25-
This specification formalises the requirements for an `AccountRoot` when used as a _pseudo-account_. Specifically, it defines:
44+
###### **Fields**
2645

27-
- A set of flags that must be enabled.
28-
- A naming convention for the field identifying the object the `AccountRoot` is associated with.
29-
- Minimum requirements for any protocol implementing a _pseudo-account_.
46+
| Field Name | Constant | Required | Internal Type | Default Value | Description |
47+
| :--- | :---: | :---: | :---: | :---: | :--- |
48+
| `<Object>ID` | Yes | Yes | `HASH256` | N/A | The unique identifier of the ledger object this pseudo-account is associated with. |
49+
| `Flags` | Yes | Yes | `UINT32` | N/A | A set of flags that must be set for a pseudo-account. |
50+
| `Sequence` | Yes | Yes | `UINT32` | `0` | The sequence number, which must be `0`. |
51+
| `RegularKey` | Yes | No | `ACCOUNT` | N/A | A regular key, which must not be set for a pseudo-account. |
3052

31-
## 2. Ledger Entries
53+
A detailed description of these fields follows:
3254

33-
### 2.1. `AccountRoot` Ledger Entry
55+
**`<Object>ID`**
3456

35-
#### 2.1.1. Object Identifier
57+
This field links the pseudo-account to its parent ledger object. Any protocol introducing a pseudo-account must define a new, optional field on the `AccountRoot` object to store this ID. The field name must follow this convention:
3658

37-
The address of the `AccountRoot` must be randomised to prevent users from identifying and funding the address before its creation. The protocol that creates an `AccountRoot` must ensure the account address is unoccupied.
59+
* `<Object>` is the name of the associated ledger object (e.g., `AMM`, `Vault`). Names that are acronyms should be fully capitalized (`AMMID`). Otherwise, use PascalCase (`VaultID`).
60+
* The suffix `ID` must always be appended.
3861

39-
The unique ID of the **`AccountRoot`** object, a.k.a. **`AccountRootID`** is computed as follows:
62+
**`Flags`**
4063

41-
- for (i = 0; i <= 256; i--)
42-
- Compute `AccountRootID` = `SHA512-Half`(i || [Parent Ledger Hash](https://xrpl.org/ledgerhashes.html) || `<Object>ID>`)
43-
- If the computed `AccountRootID` exists, repeat
44-
- else, return `AccountRootID`
64+
The following flags must be set on a pseudo-account's `AccountRoot` and must be immutable:
4565

46-
#### 2.1.2. Fields
66+
| Flag Name | Hex Value | Description |
67+
| :--- | :---: | :--- |
68+
| `lsfDisableMaster` | `0x00040000` | Disables the master key pair, ensuring no entity can sign transactions directly for this account. Control is ceded entirely to protocol rules. |
69+
| `lsfDepositAuth` | `0x01000000` | Requires authorization for deposits, typically meaning that funds can only be sent to this account via specific protocol transactions rather than standard `Payment` transactions. |
4770

48-
| Field Name | Modifiable? | Required? | JSON Type | Internal Type | Default Value | Description |
49-
| ------------ | :---------: | :-------: | :-------: | :-----------: | :-----------: | :---------------------------------------------------------------------------------------------------------- |
50-
| `<Object>ID` | `N/A` | `no` | `string` | `HASH256` | `N/A` | The object identifier the `pseudo-account` is associated with. |
51-
| `Flags` | `no` | `yes` | `number` | `UINT32` | `N/A` | A set of flags that must be set for a `pseudo-account`. |
52-
| `Sequence` | `no` | `yes` | `number` | `UINT32` | `0` | The sequence number of the `pseudo-account`. |
53-
| `RegularKey` | `no` | `yes` | `string` | `ACCOUNTID` | `N/A` | The address of a key pair that can be used to sign transactions for this account instead of the master key. |
71+
**`Sequence`**
5472

55-
##### 2.1.2.1. `<Object>ID`
73+
The `Sequence` number of a pseudo-account must be initialized to `0` and must not be changed. This, combined with the disabled master key, prevents the account from ever submitting a transaction on its own behalf.
5674

57-
The `<Object>ID` field uniquely identifies the ledger entry associated with an account. Any protocol introducing a `pseudo-account` must include a new, optional `<Object>ID` field.
75+
**`RegularKey`**
5876

59-
The naming convention for this field follows these rules:
77+
A `RegularKey` must not be set on a pseudo-account.
6078

61-
- `<Object>` represents the name of the related object:
62-
- All letters must be capitalised if the name is an acronym (e.g., `AMM`).
63-
- Otherwise, capitalise the first letter of each noun (e.g., `Vault` or `LoanBroker`).
64-
- `ID` must always be appended as a suffix.
79+
###### **Reserves**
6580

66-
##### 2.1.2.2. `Flags`
81+
The cost of creating a pseudo-account depends on whether it is owned and controlled by another account.
6782

68-
The following flags must be set for a `pseudo-account`:
83+
* **Owned Pseudo-Accounts:** For objects like a `Vault` where a single account owns and controls the associated pseudo-account, the transaction must increase the owner's XRP reserve by one increment. This is in addition to any other reserve requirements of the transaction (e.g., for the `Vault` object itself). The transaction fee is the standard network fee.
6984

70-
| Flag Name | Flag Value | Modifiable? | Description |
71-
| ------------------ | :--------: | :---------: | :---------------------------------------------------------------------------------------: |
72-
| `lsfDisableMaster` | `0x01` | `No` | Ensure that no one can control the account directly and send transactions on its behalf. |
73-
| `lsfDepositAuth` | `0x001` | `No` | Ensure that the only way to add funds to the account is by using a `deposit` transaction. |
85+
* **Unowned Pseudo-Accounts:** For objects like an `AMM` that are not owned by any account, the creation transaction must charge a special, higher-than-normal transaction fee. This fee must be at least the value of one incremental owner reserve (currently **2 XRP**, subject to change via Fee Voting). This amount is burned, compensating for the permanent ledger space without tying the reserve to a specific owner.
7486

87+
###### **Deletion**
7588

89+
A pseudo-account must be deleted together with the associated object.
7690

77-
##### 2.1.2.3. `Sequence`
78-
The `Sequence` number of a` _pseudo-account_` **must** be `0`. A _pseudo-account_ cannot submit valid transactions.
91+
###### **Invariants**
7992

80-
##### 2.1.2.4. `RegularKey`
81-
A _pseudo-account_ **must not** have a `RegularKey` set.
93+
The following invariants must hold true for any `AccountRoot` entry functioning as a pseudo-account:
8294

83-
#### 2.1.3. Cost
95+
* The ledger object identified by the `<Object>ID` field must exist.
96+
* Exactly one `<Object>ID` field must be present on the `AccountRoot` (e.g., an account cannot be linked to both an `AMMID` and a `VaultID`).
97+
* The `lsfDisableMaster` and `lsfDepositAuth` flags must always be set.
98+
* The `Sequence` number must always be `0`.
99+
* A `RegularKey` must not be set.
84100

85-
A transaction that creates a `pseudo-account` must incur a higher-than-usual transaction fee to deter ledger spam. Additionally, the transaction must destroy at least the incremental owner reserve amount, currently `2 XRP`.
101+
### Security Considerations
86102

87-
#### 2.1.4. Invariant
103+
The design of pseudo-accounts includes several critical security features:
88104

89-
The following invariants **must** hold for a _pseudo-account_:
90-
- The object identified by `<Object>ID` **must** exist on the ledger.
91-
- Exactly one `<Object>ID` **must** be set (e.g., a _pseudo-account_ cannot have both `AMMID` and `VaultID` at the same time).
92-
- The `lsfDepositAuth` and `lsfDisableMaster` flags **must** be set.
93-
- The `Sequence` number **must** be `0`.
94-
- The `RegularKey` **must not** be set.
105+
* **No Direct Control:** The mandatory `lsfDisableMaster` flag and the absence of a `RegularKey` ensure that no user can directly control the pseudo-account or its assets. All fund movements are governed exclusively by the rules of the associated protocol.
106+
* **Transaction Prevention:** A `Sequence` of `0` makes it impossible for the account to submit transactions, preventing any misuse of the account itself.
107+
* **Address Front-running Prevention:** The deterministic but unpredictable method for generating the account address prevents attackers from guessing the address and sending funds to it before it is officially created by the protocol.
108+
* **Controlled Deposits:** The `lsfDepositAuth` flag prevents arbitrary `Payment` transactions from being sent to the account, ensuring that its balances can only be modified through legitimate protocol transactions.

0 commit comments

Comments
 (0)