For the complete documentation index, see llms.txt. This page is also available as Markdown.

18. Remove an investor's registration

Removing a registration deletes the local record that attributes an address to an identity for an asset. An agent does it to undo a registration made in error, or to stop overriding the global link of an address. It does not remove an investor from the asset: the address falls back to its global link if it has one, and the tokens it holds stay where they are, attributed to their owner.

At a glance

Triggered by

Registry Agent

Actors

Registry Agent, Issuer, Investor, Platform

Contracts

TREXRegistry, IdentityRegistryStorage, IdentityFactory (read only, for the fallback)

Preconditions

The address has a local registration (see 06); the caller holds AGENT in the asset's domain

Result

The local registration is deleted, and the address resolves through the global identity registry, or to no identity if it is not linked there

Actors and roles

Actor
Role in this flow
What they hold

Registry Agent

Submits the removal.

AGENT on the TREXRegistry

Issuer

Decides that the local registration no longer applies. Does not transact in this flow.

Its own records

Investor

Is the subject of the registration. Does not transact.

Its ONCHAINID and, possibly, tokens at the address

Platform

Runs the reads, assesses the effect and submits with the Registry Agent's key.

The Registry Agent's signing key, or a key authorized for it

Sequence

Step by step

Step 1. Assess what the address will resolve to

Who: Platform, on behalf of the Registry Agent

Call: Off-chain, using read calls

Before the call: The Issuer has decided to delete the registration.

What happens: The Platform reads TREXRegistry.isLocallyRegistered(address), which must be true. It reads IdentityFactory.getIdentityIncludingRevoked(account), where account is the address encoded as an ERC-7930 interoperable address, to learn what the address resolves to once the local registration is gone.

The address, in the global identity registry
After the removal

Linked to the same identity

Nothing changes for the asset. The registration was redundant.

Linked to another identity

The address resolves to that other identity.

Linked, then revoked by its owner

The address still resolves to the identity of the revoked link, so its tokens keep their owner. It is not verified and cannot receive.

Not linked

The address resolves to no identity. It is not verified and cannot receive.

It also reads Token.balanceOf(address). Tokens held at the address stay there in every case.

What changes: Nothing on-chain.

Step 2. Remove the registration

Who: Registry Agent (AGENT)

Call: TREXRegistry.deleteIdentity(userAddress)

Before the call: Step 1 is done.

What the contract checks:

  1. The caller holds AGENT in the asset's domain. Otherwise the call reverts with AccessManagedUnauthorized.

  2. The identity storage accepts the registry as a writer: the registry holds IRS_WRITER in the storage's domain, which commissioning grants. Otherwise AccessManagedUnauthorized, naming the registry.

  3. The address is not zero. Otherwise ZeroAddress.

  4. The address has a local registration. Otherwise AddressNotYetStored.

What changes: The storage deletes the local record and emits IdentityUnstored(address, identity). When the address is linked globally to a different identity, it also emits IdentityOverrideReleased(address, localIdentity, globalIdentity). The registry emits IdentityRemoved(address, identity). From now on the address resolves through the global identity registry.

Step 3. Confirm the effect

Who: Platform

Call: Off-chain, using read calls

Before the call: Step 2 is confirmed.

What happens: The Platform reads TREXRegistry.identity(address) and TREXRegistry.isVerified(address), and compares them with what step 1 predicted. If the address holds tokens, it reads ModularCompliance.ownerOf(address), the identity the compliance attributes them to.

What changes: Nothing on-chain.

State after the flow

  • TREXRegistry.isLocallyRegistered(address) is false.

  • TREXRegistry.identity(address) returns the identity of the global link, or zero.

  • The removal applies to every asset whose registry is bound to the same identity storage.

  • The balance of the address is unchanged. No Transfer event was emitted.

  • When the address resolves to no identity any longer, the compliance keeps attributing its tokens to the last identity it credited. A position never loses its owner.

  • When the address now resolves to a different identity, the compliance moves the address's balance to that identity at the next movement through the address.

Failure modes

Symptom
Cause
Fix

Reverts with AccessManagedUnauthorized

The caller does not hold AGENT in the asset's domain (step 2, check 1)

Grant the role: 25

Reverts with AccessManagedUnauthorized, naming the registry

The registry does not hold IRS_WRITER on the identity storage: the suite is not commissioned, or the storage is shared and sits in another domain (step 2, check 2)

Commission the suite: 25

Reverts with ZeroAddress

The address is zero (step 2, check 3)

Pass the address

Reverts with AddressNotYetStored

The address has no local registration. It resolves through the global link only (step 2, check 4)

Nothing to remove. An agent cannot delete a global link

The registration is removed and the address can still receive

The address is linked globally to an eligible identity

Intended. To keep an address out of the asset, freeze it: 13

The registration is removed and the holder can still send

Removing a registration does not immobilize tokens

Freeze the address, or move the position with a forced transfer

The registration is removed and the holder can no longer receive

The address resolves to no identity now

Intended if the registration was the only attribution. The owner links the wallet: 07

A recovery removed a registration by itself

The recovery of a lost wallet deletes the lost wallet's local registration

Intended

Common misunderstandings

Wrong: "Deleting the identity removes the investor from the token."

Right: It deletes one local record. The address falls back to its global link and, if that identity is eligible, stays verified. To keep an address out of an asset, the tool is a freeze. To end a holding, the tools are a forced transfer or a redemption.

Wrong: "Deleting the registration removes the investor's tokens."

Right: No balance changes. The tokens stay at the address, and the compliance keeps attributing them to an identity: the one the address now resolves to, or the last one it credited.

Wrong: "deleteIdentity deletes the ONCHAINID."

Right: The function name comes from the standard. It deletes the registration of an address in one asset's storage. The identity, its keys and its claims are untouched, and no agent can delete them.

Wrong: "An agent can unlink a wallet from its identity."

Right: The global link belongs to the Identity Owner and is permanent. The owner can revoke the wallet. An agent can only add, change or remove its own asset's local registration.

Integration notes

  • Predict the result before submitting, from getIdentityIncludingRevoked(account). The effect of a removal depends entirely on the global link.

  • Index IdentityUnstored together with IdentityOverrideReleased. The second tells an indexer that the asset now follows the global link for that address.

  • Do not use this flow as an offboarding step. It gives no guarantee that the address stops receiving.

  • Check ModularCompliance.positionGap() after removing registrations on addresses that hold tokens. It stays at zero as long as each address still resolves to its owner, or to nobody.

  • A removal has no batch variant. Group several calls through the caller's own account if it can batch.

Last updated