19. Revoke a claim
Revoking a claim withdraws an attestation. The Claim Issuer does it when the fact it attested is no longer true, or when the claim was issued in error. The effect is immediate and needs no action from any Issuer: from the next eligibility check, the claim stops counting for every asset, and an investor that relied on it alone can no longer receive.
At a glance
Triggered by
Claim Issuer
Actors
Claim Issuer, Investor, Issuer, Platform
Contracts
The ONCHAINID of the Claim Issuer, ERC734Validator, the ONCHAINID of the Investor (when the claim is also removed), TREXRegistry (read only, for the effect)
Preconditions
The claim was issued (see 05); the Claim Issuer controls a MANAGEMENT key of its identity; the Claim Issuer knows the claim: the identity, the topic and the claim data
Result
The claim reads as Revoked, and no asset counts it any longer
Actors and roles
Claim Issuer
Decides the revocation and submits it.
A MANAGEMENT key of its ONCHAINID
Investor
Is affected: it may no longer be eligible. Does not transact, unless it removes the claim from its identity.
Its ONCHAINID and its positions
Issuer
Is affected: a holder of its asset may have become ineligible. Does not transact in this flow.
The agent operations of its asset
Platform
Computes the digest, relays the call and reports the effect.
Whatever keys the Claim Issuer has authorized
Sequence
Step by step
Step 1. Identify the claim
Who: Platform, on behalf of the Claim Issuer
Call: Off-chain, using read calls
Before the call: The Claim Issuer has decided to withdraw its attestation for an identity and a topic.
What happens: The Platform computes claimId = keccak256(abi.encode(issuer, topic)) and reads getClaim(claimId) on the Investor's identity, which returns the claim as stored: signature and data. It reads getClaimHash(identity, topic, data) on the Claim Issuer's identity, which returns the digest of that claim, and isDigestRevoked(digest), which must be false. A Claim Issuer that stored the digest when it issued the claim skips the first two reads.
What changes: Nothing on-chain.
Step 2. Revoke the claim
Who: Claim Issuer (MANAGEMENT key of its identity)
Call: revokeClaimByDigest(digest), called on the Claim Issuer's ONCHAINID
Before the call: Step 1 is done. The call is made directly on the issuer's identity by the key holder.
What the contract checks:
The caller holds
MANAGEMENTon the Claim Issuer's identity. Otherwise the call reverts withSenderDoesNotHaveManagementKey.The digest is not already revoked. Otherwise
ClaimAlreadyRevoked.
What changes: The issuer's identity records the digest as revoked and emits ClaimRevoked(digest, issuer, caller). The claim is still stored on the Investor's identity. From now on, isClaimValid returns false for it and getClaimStatus returns Revoked.
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 isClaimValid(identity, topic, signature, data) on the Claim Issuer's identity, which returns false. For each asset concerned, it reads TREXRegistry.isVerified(address) for the Investor's addresses. The result is false when no other valid claim from a trusted issuer covers the topic. The Claim Issuer informs the Investor, and the Issuers it has an agreement with, under its own process.
What changes: Nothing on-chain.
Step 4. Remove the claim from the identity
Optional. It tidies the identity. It is not needed for the revocation to take effect.
Who: Identity Owner (CLAIM_SIGNER key of the Investor's identity), or the Claim Issuer's ONCHAINID if the Claim Issuer has standing in the network
Call: removeClaim(claimId), called on the Investor's ONCHAINID
Before the call: The claim is on the identity.
What the contract checks:
The claim exists on the identity. Otherwise
ClaimNotRegistered.The caller holds
CLAIM_SIGNERon the identity. If it does not: the caller is the issuer of this claim, and that issuer is aCLAIM_ISSUERidentity with sufficient reputation. OtherwiseSenderDoesNotHaveClaimSignerKey,IdentityNotClaimIssuerTypeorReputationBelowClaimAddThreshold.
What changes: The claim is deleted from the identity, and its digest is marked as revoked on both sides. The ERC734Validator emits ClaimRemoved.
State after the flow
isDigestRevoked(digest)on the Claim Issuer's identity is true.isClaimValidreturns false andgetClaimStatusreturnsRevokedfor the claim.For every asset that relied on this claim alone for a required topic,
TREXRegistry.isVerifiedis false for every address of the Investor's identity.The Investor's positions are unchanged. It keeps what it holds, cannot receive more, and can still transfer to an eligible recipient.
The same signed claim can never be made valid again. To attest the fact again, the Claim Issuer signs a new claim.
After step 4, the identity no longer holds the claim.
Failure modes
Reverts with SenderDoesNotHaveManagementKey
The caller does not hold MANAGEMENT on the issuer's identity, for example it is the signing key (step 2, check 1)
Submit with a MANAGEMENT key
Reverts with ClaimAlreadyRevoked
The digest is already revoked (step 2, check 2)
Nothing to do
The revocation succeeds and the claim still reads Valid
The digest revoked is not the digest of the stored claim: another identity, topic or data was used
Read the stored claim with getClaim, recompute with getClaimHash, revoke that digest
The call is refused when sent as a user operation
revokeClaimByDigest and removeClaim require a direct call from the key holder
Call the identity directly
The claim is revoked and the Investor is still eligible
Another trusted Claim Issuer has a valid claim for the same topic on the identity
Intended. Eligibility needs one valid claim per topic
removeClaim reverts with ClaimNotRegistered
The identity holds no claim with that identifier (step 4, check 1)
Recompute claimId from the issuer and the topic
Many claims must be withdrawn at once
A signing key was compromised
Remove CLAIM_SIGNER from that key (see 22). Every claim it signed stops validating
Common misunderstandings
Wrong: "The Issuer revokes the investor's KYC."
Right: A claim is revoked by the Claim Issuer that signed it. An Issuer can stop trusting a Claim Issuer for its asset, which is a different operation with a different scope: it affects one asset and every investor that relied on that issuer.
Wrong: "After a revocation, someone has to update the token or the registry."
Right: Nothing is updated. The registry asks the Claim Issuer whether each claim is valid at every eligibility check. The revocation is the answer changing.
Wrong: "A revoked claim removes the investor's tokens."
Right: Eligibility is checked on the recipient of a movement. The investor keeps its position, can no longer receive, and can still sell or transfer to an eligible recipient: it was eligible when it received the tokens and it is still identified. An Issuer that wants to block it freezes its tokens or its address.
Wrong: "Revocation removes the claim from the identity."
Right: The claim stays stored and reads as
Revoked. Removing it from the identity is a separate call, and is optional.
Integration notes
Keep the digest of every claim issued, with the verification record. Revocation takes the digest, and recomputing it needs the exact claim data.
For a claim that should end on a known date, set
validUntilwhen issuing. Expiry needs no revocation and no transaction.For a compromised signing key, remove
CLAIM_SIGNERfrom the key. It withdraws every claim that key signed in one transaction.Index
ClaimRevokedon theERC734Validator, filtered by issuer. An application that shows eligibility re-readsisVerifiedfor the identities concerned.A revocation is not reversible. Renewing an attestation is a new claim, with a new
issuedAt, issued with 05.Tell the Issuers concerned. The protocol stops counting the claim at once, and the Issuer decides what to do about the positions already held.
Related flows
05 Issue a claim to an investor : issuing, and re-issuing after a revocation
22 Add and remove keys on an ONCHAINID : rotating a signing key
20 Remove a trusted Claim Issuer : what an Issuer does on its side
13 Freeze and unfreeze an address or a partial balance : what an Issuer can do about a holder that became ineligible
Last updated