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
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.
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:
The caller holds
AGENTin the asset's domain. Otherwise the call reverts withAccessManagedUnauthorized.The identity storage accepts the registry as a writer: the registry holds
IRS_WRITERin the storage's domain, which commissioning grants. OtherwiseAccessManagedUnauthorized, naming the registry.The address is not zero. Otherwise
ZeroAddress.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
Transferevent 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
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: "
deleteIdentitydeletes 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
IdentityUnstoredtogether withIdentityOverrideReleased. 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.
Related flows
06 Register an investor for an asset : the inverse operation
17 Update an investor's registration : changing the registered identity
13 Freeze and unfreeze an address or a partial balance : keeping an address out of an asset
23 Revoke a wallet : what the owner does on the global link
14 Execute a forced transfer : ending a holding
Last updated