> For the complete documentation index, see [llms.txt](https://docs.t-rex.network/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.t-rex.network/governance-and-infrastructure/namespaced-storage-erc-7201.md).

# Namespaced storage (ERC-7201)

Every upgradeable contract in the protocol keeps its state in namespaced storage, following ERC-7201. Instead of placing variables in sequential slots, each contract places its state in a storage region whose position is derived from a name. A contract's layout can then evolve across upgrades without the risk that a new variable overwrites an old one, or the state of a contract it inherits from or is composed with.

For a system that is meant to be upgraded over a long life, and that builds accounts and tokens out of several layers, this is a safeguard and not a convenience. It removes a class of upgrade error that has caused serious failures in upgradeable systems built without it.

## The problem it removes

A proxy keeps the state. The implementation behind it defines how that state is read. With sequential storage, a variable's position is its rank in the order of declaration, counted across the whole inheritance chain.

| Change in an upgrade                     | Effect with sequential storage                                                                          |
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| A variable is added to a parent contract | Every variable declared after it, in every child, shifts by one slot and reads another variable's data. |
| The order of inheritance changes         | The same.                                                                                               |
| A dependency adds state in a new release | The same, without any change in the project's own code.                                                 |

The usual defense is to reserve empty slots in each contract and to audit the layout by hand at every upgrade. It works as long as nobody makes a mistake.

## How namespaced storage works

Each contract, or each layer of a contract, defines one structure holding all its state, and stores it at a position computed from a name.

| Element       | Meaning                                                                                                        |
| ------------- | -------------------------------------------------------------------------------------------------------------- |
| **Namespace** | A string that identifies the layer, for example `erc3643.storage.TREXToken`.                                   |
| **Location**  | A storage position derived from the namespace by a fixed formula. Two namespaces give two positions far apart. |
| **Structure** | The state of the layer, laid out from that location onward.                                                    |

A layer reads and writes only inside its own structure. Adding a field to one layer cannot move anything in another, whatever the inheritance.

## The namespaces of the protocol

### Token suite

Each contract of a suite is composed of several layers, each with its own namespace.

| Contract                  | Layers and their namespaces                                                                                                                                                                                          |
| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Token`                   | The standard token: `erc3643.storage.ERC3643Token`. The T-REX extension, with the bridged ledger: `erc3643.storage.TREXToken`. Messaging: `erc3643.storage.TREXMessaging`.                                           |
| `TREXRegistry`            | The three standard registries: `erc3643.storage.IdentityRegistry`, `erc3643.storage.TrustedIssuersRegistry`, `erc3643.storage.ClaimTopicsRegistry`. The T-REX extension: `erc3643.storage.TREXEligibility`.          |
| `IdentityRegistryStorage` | `erc3643.storage.IdentityRegistryStorage`                                                                                                                                                                            |
| `ModularCompliance`       | The standard compliance: `erc3643.storage.Compliance`. The T-REX extension: `erc3643.storage.TREXCompliance`. The ledger: `erc3643.storage.ComplianceLedger`. The validations: `erc3643.storage.TransferValidation`. |
| `TREXAccessManager`       | The domain registry: `erc3643.storage.TREXAccessManager`, next to the namespaces of OpenZeppelin's AccessManager.                                                                                                    |
| Compliance modules        | The common base: `erc3643.storage.AbstractModuleUpgradeable`. One namespace per module that keeps settings, for example `erc3643.storage.MaxBalancePerIdentityModule`.                                               |

The OpenZeppelin contracts these build on, such as the ERC-20 base and the pause, use namespaced storage of their own.

### Identity layer

| Contract             | Namespace                               |
| -------------------- | --------------------------------------- |
| `Identity`           | `onchainid.identity.metadata`           |
| `ERC734Validator`    | `onchainid.validators.erc734-validator` |
| `IdentityFactory`    | `onchainid.IdentityFactory`             |
| `ReputationRegistry` | `onchainid.ReputationRegistry`          |

## What the separation buys

**The standard and the extension evolve independently.** The token keeps the state defined by ERC-3643 in one namespace and the state that T-REX adds in another. No extension writes into the namespace of a standard base. The standard layer can be replaced or updated without touching the extension's state, and the reverse.

**Each concern can be reviewed alone.** Messaging has its own namespace, so the messaging layer is reviewed without the token's ledger, and the ledger's layout is never disturbed by a change to messaging. The same holds for the compliance ledger and for the validations.

**A dependency cannot shift the protocol's state.** A new release of a library that adds state adds it in the library's namespace.

## Shared contracts keep state per user

Some contracts are deployed once and serve many users. Their state is keyed inside the namespace, so users never share it.

| Contract            | Serves                          | State is keyed by                       |
| ------------------- | ------------------------------- | --------------------------------------- |
| `ERC734Validator`   | Every identity                  | The identity                            |
| `KeyApprovalModule` | Every identity that installs it | The identity                            |
| A compliance module | Every compliance that binds it  | The compliance, and the current binding |

For a compliance module, tying the settings to the current binding means that a module unbound and bound again starts from empty settings. Nothing from a previous binding can reappear.

## What it does not do

Namespacing protects layers from one another. It does not make every change to a layer safe.

| Still required                                                                                                                       | Why                                                                                                                                                                                                                                                                                                                                                                                 |
| ------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Fields are only appended.** Inside a structure, new fields go at the end. Existing fields are never reordered, removed or retyped. | Within one namespace, the layout is still positional.                                                                                                                                                                                                                                                                                                                               |
| **A namespace is never renamed.**                                                                                                    | The name defines the location. A new name points at empty storage.                                                                                                                                                                                                                                                                                                                  |
| **Values fixed in the implementation are not storage.**                                                                              | An identity reads its factory and its key registry from its implementation, not from its own storage. An upgrade of the implementation changes them for every identity, which is why the `IdentityFactory` checks that a new implementation names the same ones. See [Upgradeability: beacons and versions](/governance-and-infrastructure/upgradeability-beacons-and-versions.md). |

## For integrators

Do not read the protocol's state by storage slot. The location of a variable is an implementation detail of a layer, and the supported way to read state is the view functions of each contract. Tools that inspect storage, such as upgrade-safety checkers, recognize ERC-7201 through the annotation each structure carries.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.t-rex.network/governance-and-infrastructure/namespaced-storage-erc-7201.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
