The eligibility registry
The eligibility of a holder is defined by three bodies of configuration: the claim topics an investor must satisfy, the Claim Issuers trusted to attest them, and the binding between addresses and identities. In earlier versions these lived in three registry contracts that the token wired together. T-REX consolidates them in one contract, the TREXRegistry, backed by an identity storage that several tokens can share.
This page describes what the registry holds, how it resolves an address, and how it is configured. The decision it makes, isVerified, is walked through in Eligibility and compliance: the two gates.
What the registry is
Decide whether an address may receive the asset
Identity Registry
isVerified, isWalletVerified
Resolve an address to its identity
Identity Registry
identity, contains, resolveIdentity
Keep registrations made for this asset
Identity Registry, through the storage
registerIdentity, updateIdentity, deleteIdentity
Keep the required claim topics
Claim Topics Registry
addClaimTopic, removeClaimTopic, getClaimTopics, and the per-type variants
Keep the trusted Claim Issuers
Trusted Issuers Registry
addTrustedIssuer, removeTrustedIssuer, updateIssuerClaimTopics, and the getters
The three standard registries are one address. issuersRegistry() and topicsRegistry() return the registry itself, and the setters that would point it at separate registries revert.
Resolving an address
The registry answers two different questions about an address, and they do not always have the same answer.
Attribution. Whose is what this address holds?
identity(address), contains(address), resolveIdentity(wallet)
Still its identity. A position never loses its owner.
Admission. May this address receive the asset?
isVerified(address), isWalletVerified(wallet)
No.
Attribution is what the compliance uses to keep positions, and what an agent relies on to recover or burn a position. Admission is what the token checks before crediting a recipient.
An address on the reference chain resolves in this order:
A local registration, if there is one in the identity storage.
The global link otherwise: the identity the address is linked to in the
IdentityFactory. An ONCHAINID resolves to itself.
A wallet on another chain is resolved by its ERC-7930 interoperable address, through the IdentityFactory directly. That is what resolveIdentity and isWalletVerified are for. They take the interoperable address and serve the cross-chain validations of the asset.
Local registrations
Most holders need no registration. They link their wallets to their identity once, or hold in the identity itself, and every asset recognizes them. See Wallet linking and the global identity registry.
A Registry Agent registers an address for an asset when the address cannot link itself.
Can link itself to its identity: a wallet whose owner signs, a wallet on a satellite
Its owner links it, once, in the global identity registry.
Cannot link itself and has to hold the asset: a custody account, a contract that cannot sign
The Issuer's agent registers it for the asset, under the identity it belongs to.
An omnibus wallet, for example at a centralized exchange
It is attributed to the entity that operates it, not to the individual owners behind the omnibus position.
A contract that takes part in its own right, such as a venue, is not registered this way. It has an ONCHAINID of type SMART_CONTRACT, bound to it at creation, and resolves through the global identity registry. A local registration is for an address held on behalf of an existing identity.
The recommendation is to register only identities created by the IdentityFactory. The registry accepts any non-zero address as an identity, and an identity from another source is unlikely to be accepted elsewhere in the ecosystem.
registerIdentity(address, identity, country)
Binds the address to the identity for this asset. The country argument is ignored.
batchRegisterIdentity
The same for several addresses.
updateIdentity(address, identity)
Changes the identity an address is registered with.
deleteIdentity(address)
Removes the local registration.
All four require the AGENT role.
Three rules govern the relation between a local registration and the global link.
The local registration takes precedence. When an address has both, the asset uses the local one. The storage emits
IdentityOverriddenwhen a local registration differs from the global link, andIdentityOverrideReleasedwhen that difference ends.Deleting a registration does not exclude an address. It removes the local entry only. If the address is linked globally, it resolves through that link again, and it is still verified if its identity is eligible.
A revoked wallet is refused however it is registered. A local registration does not reinstate a wallet that its owner has revoked.
To keep an address out of an asset, freeze it. Registration is attribution, not permission.
isLocallyRegistered(address) tells whether an address has a local registration, ignoring the global link.
Required claim topics
addClaimTopic(topic), removeClaimTopic(topic)
Changes the default set: the topics every holder must satisfy.
addClaimTopicForIdentityType(type, topic), removeClaimTopicForIdentityType(type, topic)
Changes the set for one identity type.
getClaimTopics(), getClaimTopicsForIdentityType(type)
Reads them.
A set defined for a type replaces the default set for identities of that type. It does not add to it.
The same requirements for every holder
Default topics only
Different requirements for companies
Default topics, and a set for CORPORATE that lists everything a company must satisfy
A requirement added for everyone later
Add it to the default set and to every type that has its own set
The last row matters: a topic added to the default set does not reach a type that has a set of its own. When the set of a type becomes empty, that type falls back to the default set.
The type of an identity is read from the IdentityFactory. An identity the factory did not create has no type and is held to the default set.
A set holds at most 15 topics.
Trusted issuers
The Issuer lists the Claim Issuers whose claims count for the asset, each with the topics it is trusted for: addTrustedIssuer, updateIssuerClaimTopics, removeTrustedIssuer. A registry holds at most 50 trusted issuers, each trusted for at most 15 topics.
How trust in Claim Issuers works, at the level of the asset and of the network, is described in Claim issuers, trust and reputation.
These limits, with the limit on topics, bound the work the registry does on every transfer. The registry also calls each Claim Issuer in a way that a faulty or hostile issuer cannot use to block verification: if an issuer fails to answer, its claim does not count, and the check continues with the next issuer trusted for the topic.
No country in the registry
The registry stores no country. investorCountry returns zero, updateCountry reverts, and the country argument of registerIdentity is ignored.
Where a holder resides is a fact about the holder. It is attested by a claim on the identity. A rule that depends on it is a compliance rule, and belongs to a compliance module.
The eligibility switch
disableEligibilityChecks makes isVerified return true for every address, including one that resolves to no identity. enableEligibilityChecks restores the checks. Both require the OWNER role. The switch exists for assets that do not restrict who may hold them, and it leaves the compliance gate untouched.
Shared storage
The local registrations are not kept in the registry itself. They are kept in an IdentityRegistryStorage, to which several registries can be bound.
Required claim topics
Yes
Trusted issuers
Yes
The eligibility switch
Yes
Local registrations
Yes
An Issuer with several assets binds their registries to one storage. An address registered once is then registered for all of them, while each asset keeps its own requirements.
At deployment, a token suite gets a new storage, or is pointed at an existing one that is governed by the same AccessManager.
Binding a registry to a storage requires the
IRS_BINDERrole on the storage. The registry and the storage must be governed by the same AccessManager.Unbinding requires the
OWNERrole on the storage.A storage accepts up to 300 registries.
Agents never write to the storage directly. A bound registry holds the
IRS_WRITERrole. Agents go through a registry.
Sharing a storage is not what lets a holder use one identity across assets. The global identity registry does that, for every asset in the network. A shared storage only shares the local registrations an Issuer chooses to make.
Roles
OWNER
TREXRegistry
Claim topics, trusted issuers, the eligibility switch, the choice of storage
AGENT
TREXRegistry
Local registrations
IRS_BINDER
IdentityRegistryStorage
Binding a registry
OWNER
IdentityRegistryStorage
Unbinding a registry
IRS_WRITER
IdentityRegistryStorage
Writing registrations. Held by bound registries.
The token itself holds AGENT on its registry, so that the recovery of a lost wallet can register the new one.
Last updated