# Configure equity collateral

Source: https://docs.settlemint.com/docs/developer-guides/runbooks/configure-equity-collateral
Configure collateral backing requirements for equity tokens with the Collateral Compliance Module. Install the module, issue a token-identity collateral claim, verify collateral stats, and mint only when backing is sufficient.



The Collateral Compliance Module enforces reserve requirements for equity tokens. Before each mint, the module checks the token identity for a valid collateral claim. The mint fails when the claim does not cover the post-mint supply at the configured ratio.

Use this how-to when you already have an equity token and need mint-time reserve controls. You will install the module and issue the claim. Then check the stats endpoint and mint only after the backing is visible.

<Mermaid
  chart="`
flowchart TD
Issuer[&#x22;Equity issuer&#x22;] --> Evidence[&#x22;Collateral reserve evidence&#x22;]
Evidence --> Claim[&#x22;Collateral claim on token identity&#x22;]
Operator[&#x22;Compliance operator&#x22;] --> Module[&#x22;Collateral Compliance Module&#x22;]
Module --> Policy[&#x22;Required reserve ratio&#x22;]
Claim --> MintCheck[&#x22;Mint compliance check&#x22;]
Policy --> MintCheck
MintCheck --> Equity[&#x22;Equity token mint&#x22;]
`"
/>

## What the module enforces [#what-the-module-enforces]

The CollateralComplianceModule checks the token contract's OnchainID identity before minting. The identity must hold a valid collateral claim. The claim amount must meet or exceed the required ratio against the post-mint total supply. Regular transfers skip this check.

**Enforcement behavior:**

* **Configurable proof topic** – Specify which ERC-735 claim topic represents collateral proofs
* **Adjustable collateral ratio** – Set ratios from 0% (disabled) to 200% (over-collateralized) in basis points
* **Additional trusted issuers** – Extend the global and subject-specific trusted issuer registry with token-specific issuers
* **Mint-only enforcement** – Only validates minting operations; regular transfers are unrestricted

**Production requirement:** the claim is not the reserve itself. Keep the off-chain reserve evidence, valuation method, attestor approval, and renewal process outside DALP, then publish only the signed collateral amount and expiry that the token identity needs for mint checks.

***

## Collateral configuration workflow [#collateral-configuration-workflow]

This diagram shows the SDK workflow for configuring collateral requirements on an equity token:

<Mermaid
  chart="`flowchart TB
  Start(Equity Token<br/>Already Deployed) --> GetModule(Get module address<br/>system.read)
  GetModule --> GetTopic(Get collateral topic ID<br/>system.claimTopics.list)
  GetTopic --> AddModule(Install module<br/>token.installComplianceModule)
  AddModule --> NeedUpdate{Need to adjust<br/>parameters?}
  NeedUpdate -->|Yes| UpdateParams(Update parameters<br/>token.configureComplianceModule)
  NeedUpdate -->|No| IssueClaim(Issue collateral claim<br/>token.claimIssue)
  UpdateParams --> IssueClaim
  IssueClaim --> Verify(Verify stats<br/>token.statsCollateralRatio)
  Verify --> Ready(Ready to Mint<br/>with Collateral Validation)
  
  style Start fill:#5fc9bf,stroke:#3a9d96,stroke-width:2px,color:#fff
  style GetModule fill:#6ba4d4,stroke:#4a7ba8,stroke-width:2px,color:#fff
  style GetTopic fill:#6ba4d4,stroke:#4a7ba8,stroke-width:2px,color:#fff
  style AddModule fill:#8571d9,stroke:#654bad,stroke-width:2px,color:#fff
  style NeedUpdate fill:#5fc9bf,stroke:#3a9d96,stroke-width:2px,color:#fff
  style UpdateParams fill:#8571d9,stroke:#654bad,stroke-width:2px,color:#fff
  style IssueClaim fill:#8571d9,stroke:#654bad,stroke-width:2px,color:#fff
  style Verify fill:#6ba4d4,stroke:#4a7ba8,stroke-width:2px,color:#fff
  style Ready fill:#b661d9,stroke:#8a3fb3,stroke-width:2px,color:#fff
`"
/>

**SDK calls in this workflow:**

* **`system.read`** – Retrieve the system configuration, including the Collateral Compliance Module address from the compliance module registry
* **`system.claimTopics.list`** – Retrieve the registered collateral claim topic ID from the system
* **`token.installComplianceModule`** – Install the Collateral Compliance Module using the retrieved address, topic ID, initial ratio, and trusted issuers
* **`token.configureComplianceModule`** – Adjust collateral ratio or trusted issuers after installation (optional)
* **`token.claimIssue`** – Add the collateral claim to the token identity with an amount and expiry
* **`token.statsCollateralRatio`** – Verify total collateral, required collateral, mintable supply, utilization, and parity confidence before or after minting

***

## Prerequisites [#prerequisites]

Before configuring collateral requirements, ensure you have:

1. **Deployed equity token** – Created with `token.create` and `type: "equity"`
2. **Governance role** – Required to issue the collateral claim to the token identity
3. **Compliance-module permissions** – Required to install and configure the module
4. **Supply-management role** – Required for the mint that the module checks
5. **API key** – See [Getting started](/docs/developer-guides/api-integration/getting-started)
6. **Collateral claim infrastructure** – The token identity must receive collateral claims from an authorized issuer or governance operator

**Note:** Retrieve the Collateral Compliance Module address dynamically from the system with `system.read` in Step 1.

***

## Step 1: Get the collateral module address [#step-1-get-the-collateral-module-address]

Before adding the Collateral Compliance Module to your token, retrieve its deployed address from the system's compliance module registry.

### Retrieve module address from system [#retrieve-module-address-from-system]

```ts file=<rootDir>/src/examples/configure-equity-collateral.ts#L60-L75
  // Step 5: Get Collateral Compliance Module address from system
  const system = await dalp.system.read({ params: { systemAddress: "default" } });
  const registry = system.data.complianceModuleRegistry;
  if (!registry) {
    throw new Error("Compliance module registry not found. Ensure the system is fully deployed.");
  }
  const collateralModule = registry.complianceModules.find((m) => m.typeId === "collateral");

  if (!collateralModule) {
    throw new Error(
      "Collateral compliance module not registered in system. Check system admin has deployed the module."
    );
  }

  const collateralModuleAddress = collateralModule.module;
  console.log("Collateral module:", collateralModuleAddress);
```

**Expected result:**

* Returns the deployed Collateral Compliance Module address from the system
* This address is required when adding the module to your token in Step 3

**Key points:**

* Use `"default"` as the `systemAddress` to get the system used by the dApp
* The `complianceModuleRegistry` contains all registered compliance modules
* Filter by `typeId === "collateral"` to find the collateral module
* The `module` field contains the deployed contract address

***

## Step 2: Get collateral topic ID [#step-2-get-collateral-topic-id]

Retrieve the registered collateral claim topic ID from the system. This ID identifies which ERC-735 claim topic represents collateral proofs.

### Retrieve claim topics [#retrieve-claim-topics]

```ts file=<rootDir>/src/examples/configure-equity-collateral.ts#L77-L84
  // Step 6: Get topic ID for collateral claims
  const topics = await dalp.system.claimTopics.list({ query: {} });
  const collateralTopic = topics.data.find((t) => t.name === "collateral");

  if (!collateralTopic) {
    throw new Error("Collateral topic not found in registry. Ensure the topic is registered by a claimPolicyManager.");
  }
  console.log("Collateral topic ID:", collateralTopic.topicId);
```

**Expected result:**

* Returns the collateral topic ID registered in the system
* This ID is required for the next step when configuring the compliance module

***

## Step 3: Add the collateral module [#step-3-add-the-collateral-module]

Install the Collateral Compliance Module on your equity token with `token.installComplianceModule`. Pass the collateral topic ID, initial ratio, and trusted issuers in the module values.

### Configuration parameters [#configuration-parameters]

The module accepts three parameters via the `values` object:

| Parameter        | Type       | Description                                                                                                                                                                                                                               | Example                              |
| ---------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ |
| `proofTopic`     | BigInt     | ERC-735 claim topic ID for collateral proofs (use `keccak256("COLLATERAL")` or custom topic)                                                                                                                                              | `"123456789..."`                     |
| `ratioBps`       | number     | Collateral ratio in basis points. 0 = disabled, 10000 = 100%, 20000 = 200%. Required collateral = supply × ratio / 10000                                                                                                                  | `10000` (100% backing)               |
| `trustedIssuers` | address\[] | **Optional.** Additional trusted issuers for the proof topic. Only required if the claim issuer is not already registered as a global trusted issuer for the collateral topic. These are merged with global and subject-specific issuers. | `[]` (use global) or `["0xABCD..."]` |

### TypeScript example [#typescript-example]

```ts file=<rootDir>/src/examples/configure-equity-collateral.ts#L86-L104
  // Step 7: Add Collateral Compliance Module
  await dalp.token.installComplianceModule({
    params: { tokenAddress: equityAddress },
    body: {
      params: {
        typeId: "collateral",
        module: collateralModuleAddress,
        values: {
          proofTopic: collateralTopic.topicId,
          ratioBps: 10_000,
          trustedIssuers: [],
        },
      },
      walletVerification: {
        secretVerificationCode: pincode,
        verificationType: "PINCODE",
      },
    },
  });
```

**Expected result:**

* The module is registered on the equity token's compliance contract
* Future mints will validate collateral claims against the configured ratio
* The token data is returned with updated compliance modules

***

## Step 4: Update collateral parameters (optional) [#step-4-update-collateral-parameters-optional]

If you need to adjust the collateral ratio or trusted issuers after initial configuration, use `token.configureComplianceModule`.

### When to update parameters [#when-to-update-parameters]

* **Increase collateral ratio** – Strengthen investor protections during market volatility
* **Decrease collateral ratio** – Adjust after successful track record or regulatory changes
* **Add trusted issuers** – Include additional attestors if they're not registered as global trusted issuers for the collateral topic
* **Change proof topic** – Switch to a different claim topic (requires coordination with claim issuers)

### TypeScript example [#typescript-example-1]

```ts file=<rootDir>/src/examples/configure-equity-collateral.ts#L107-L125
  // Step 8 (Optional): Update collateral parameters to 150%
  await dalp.token.configureComplianceModule({
    params: { tokenAddress: equityAddress },
    body: {
      params: {
        typeId: "collateral",
        module: collateralModuleAddress,
        values: {
          proofTopic: collateralTopic.topicId,
          ratioBps: 15_000,
          trustedIssuers: [],
        },
      },
      walletVerification: {
        secretVerificationCode: pincode,
        verificationType: "PINCODE",
      },
    },
  });
```

**Note:** Parameter updates take effect immediately for subsequent minting operations. Existing token holders are not affected.

***

## Step 5: Issue collateral claim to token identity [#step-5-issue-collateral-claim-to-token-identity]

The Collateral Compliance Module validates claims on the **token's OnchainID identity**, not individual investor identities. Before minting, you must add a collateral claim to the token identity using the governance role.

### Claim structure [#claim-structure]

Collateral claims contain two fields:

* `amount` – Collateral amount as string (e.g., `"1000000000000000000000"` for 1000 tokens with 18 decimals)
* `expiryTimestamp` – Unix timestamp as string when the claim expires (must be > current time)

### Issue the claim via API [#issue-the-claim-via-api]

Use `token.claimIssue` to add a collateral claim to the token identity. This requires the **governance role** on the token.

```ts file=<rootDir>/src/examples/configure-equity-collateral.ts#L140-L158
  // Step 10: Issue collateral claim to token identity
  const expiryTimestamp = Math.floor(Date.now() / 1000) + 365 * 24 * 60 * 60;

  await dalp.token.claimIssue({
    params: { tokenAddress: equityAddress },
    body: {
      claim: {
        topic: "collateral",
        data: {
          amount: 1_500_000_000_000_000_000_000n,
          expiryTimestamp: expiryTimestamp.toString(),
        },
      },
      walletVerification: {
        secretVerificationCode: pincode,
        verificationType: "PINCODE",
      },
    },
  });
```

**Key points:**

* **Governance-authorized issuance** – The governance role authorizes direct claim issuance in this SDK flow
* **Automatic on-chain encoding** – The API handles ABI encoding of `(uint256 amount, uint256 expiry)`
* **Claim ownership** – The claim is issued **to** the token identity and later checked by the collateral module
* **Trusted-issuer validation** – Mint-time validation accepts claims from the global registry, subject-specific registry entries, or addresses in `trustedIssuers`

***

## Step 6: Verify configuration [#step-6-verify-configuration]

After adding the module and issuing collateral claims, verify the configuration before attempting to mint.

### Check collateral stats [#check-collateral-stats]

Call `token.statsCollateralRatio` after issuing the claim and before large mints:

```ts
const collateralStats = await dalp.token.statsCollateralRatio({
  params: { tokenAddress: equityAddress },
});

console.log("Collateral stats:", collateralStats.data);
```

`token.statsCollateralRatio` returns the indexed collateral view for the token. Check `totalCollateral`, `requiredCollateral`, `mintableSupply`, `utilizationPercentage`, `configuredCollateralRatioBps`, and `parity_confidence`. A `high` parity confidence means the indexed stats match the contract-readable inputs. A `degraded` value means the response is still usable, but an operator should inspect claim decoding, registry availability, or legacy metadata before relying on the ratio operationally.

***

## Understanding collateral validation [#understanding-collateral-validation]

The Collateral Compliance Module performs validation during minting operations using a multi-step process.

<Mermaid
  chart="`flowchart TB
  MintReq(Mint Request) --> CheckFrom{from == zero address?}
  CheckFrom -->|No| AllowTransfer(✅ Allow<br/>Regular transfer)
  CheckFrom -->|Yes| CheckRatio{ratioBps &gt; 0?}
  
  CheckRatio -->|No| AllowMint(✅ Allow<br/>Ratio disabled)
  CheckRatio -->|Yes| GetIdentity(Load Token's<br/>OnchainID Identity)
  
  GetIdentity --> GetIssuers(Build Trusted Issuers List<br/>Global + Subject + Config)
  GetIssuers --> FindClaim(Search for Valid<br/>Collateral Claim)
  
  FindClaim --> FoundClaim{Valid claim<br/>found?}
  FoundClaim -->|No| RejectNoClai(❌ Revert<br/>No collateral claim)
  FoundClaim -->|Yes| CheckExpiry{Claim expired?}
  
  CheckExpiry -->|Yes| RejectExpired(❌ Revert<br/>Claim expired)
  CheckExpiry -->|No| Calculate(Calculate Required Collateral<br/>postSupply × ratioBps / 10000)
  
  Calculate --> Compare{claimAmount &gt;= required?}
  Compare -->|No| RejectInsuff(❌ Revert<br/>Insufficient collateral)
  Compare -->|Yes| AllowMint
  
  style MintReq fill:#5fc9bf,stroke:#3a9d96,stroke-width:2px,color:#fff
  style GetIdentity fill:#6ba4d4,stroke:#4a7ba8,stroke-width:2px,color:#fff
  style FindClaim fill:#8571d9,stroke:#654bad,stroke-width:2px,color:#fff
  style AllowTransfer fill:#5fc9bf,stroke:#3a9d96,stroke-width:2px,color:#fff
  style AllowMint fill:#5fc9bf,stroke:#3a9d96,stroke-width:2px,color:#fff
  style RejectNoClai fill:#b661d9,stroke:#8a3fb3,stroke-width:2px,color:#fff
  style RejectExpired fill:#b661d9,stroke:#8a3fb3,stroke-width:2px,color:#fff
  style RejectInsuff fill:#b661d9,stroke:#8a3fb3,stroke-width:2px,color:#fff
`"
/>

### Validation steps [#validation-steps]

1. **Mint detection** – Module checks if `from == address(0)` (minting operation). Regular transfers skip validation.

2. **Ratio check** – If `ratioBps == 0`, collateral enforcement is disabled and minting proceeds.

3. **Identity resolution** – Module loads the token's OnchainID identity address from the token contract.

4. **Issuer aggregation** – Module builds a combined list of trusted issuers:
   * Global issuers from the trusted issuer registry for the proof topic
   * Subject-specific issuers authorized for the token identity
   * Additional issuers from the module configuration

5. **Claim search** – Module queries all claims on the token's identity matching the proof topic and validates:
   * Claim is issued by a trusted issuer
   * Claim signature is valid (verified with issuer's `isClaimValid`)
   * Claim data is properly ABI-encoded as `(uint256 amount, uint256 expiry)`
   * Claim has not expired (`expiry > block.timestamp`)

6. **Collateral calculation** – Module calculates required collateral using ceiling division:

   ```solidity
   uint256 postSupply = currentSupply + mintAmount;
   uint256 requiredCollateral = (postSupply * ratioBps + 9999) / 10000;
   ```

7. **Comparison** – If `claimAmount >= requiredCollateral`, minting proceeds. Otherwise, the transaction reverts with `"ComplianceCheckFailed: Insufficient collateral for mint"`.

### Best claim selection [#best-claim-selection]

If multiple valid collateral claims exist on the token identity, the module uses the **highest collateral amount**. Issuers can maintain multiple attestations from different sources without lowering the effective backing amount.

***

## Production checklist [#production-checklist]

Before using collateral-backed equity minting in production:

* Keep the source reserve evidence and valuation process current outside the platform.
* Choose a proof topic that matches the attestation process your auditors and operators recognize.
* Register or configure only issuers that are allowed to attest reserve amounts for this token.
* Set `ratioBps` to the policy threshold. Use `10000` for 100% backing, `15000` for 150%, and `20000` for the maximum 200% ratio.
* Renew the collateral claim before `expiryTimestamp`; expired claims fail mint-time validation.
* Check collateral stats before large mints and investigate `parity_confidence: "degraded"` before using the result as operating evidence.
* Separate emergency pause and supply-management procedures from reserve evidence. The module blocks under-collateralized mints. It does not manage reserve custody or off-chain valuation.

***

## Full example script [#full-example-script]

Complete TypeScript script demonstrating collateral configuration and validation:

```ts file=<rootDir>/src/examples/configure-equity-collateral.ts
import { createDalpClient } from "@settlemint/dalp-sdk";

async function main() {
  // Step 1: Create the SDK client
  const dalp = createDalpClient({
    url: "https://your-platform.example.com",
    apiKey: "YOUR_API_KEY",
  });
  const pincode = "YOUR_PINCODE";

  // Step 2: Get your wallet address
  const me = await dalp.user.me({});
  const myWallet = me.data.wallet;
  if (!myWallet) {
    throw new Error("No wallet found. Create a wallet first via the DALP dashboard.");
  }
  console.log("Wallet:", myWallet);

  // Step 3: Create equity token
  const equity = await dalp.token.create({
    body: {
      type: "equity",
      name: "Collateralized Series A Shares",
      symbol: "CSAS",
      decimals: 0,
      countryCode: "840",
      priceCurrency: "USD",
      basePrice: "10.00",
      class: "COMMON_EQUITY",
      category: "VOTING_COMMON_STOCK",
      initialModulePairs: [],
      walletVerification: {
        secretVerificationCode: pincode,
        verificationType: "PINCODE",
      },
    },
  });

  if ("transactionId" in equity) {
    console.log("Equity creation queued:", equity.transactionId);
    return;
  }
  const equityAddress = equity.data.id;
  console.log("Equity created:", equityAddress);

  // Step 4: Grant token roles
  await dalp.token.grantRole({
    params: { tokenAddress: equityAddress },
    body: {
      account: myWallet,
      roles: ["supplyManagement", "emergency", "governance"],
      walletVerification: {
        secretVerificationCode: pincode,
        verificationType: "PINCODE",
      },
    },
  });
  console.log("Roles granted");

  // Step 5: Get Collateral Compliance Module address from system
  const system = await dalp.system.read({ params: { systemAddress: "default" } });
  const registry = system.data.complianceModuleRegistry;
  if (!registry) {
    throw new Error("Compliance module registry not found. Ensure the system is fully deployed.");
  }
  const collateralModule = registry.complianceModules.find((m) => m.typeId === "collateral");

  if (!collateralModule) {
    throw new Error(
      "Collateral compliance module not registered in system. Check system admin has deployed the module."
    );
  }

  const collateralModuleAddress = collateralModule.module;
  console.log("Collateral module:", collateralModuleAddress);

  // Step 6: Get topic ID for collateral claims
  const topics = await dalp.system.claimTopics.list({ query: {} });
  const collateralTopic = topics.data.find((t) => t.name === "collateral");

  if (!collateralTopic) {
    throw new Error("Collateral topic not found in registry. Ensure the topic is registered by a claimPolicyManager.");
  }
  console.log("Collateral topic ID:", collateralTopic.topicId);

  // Step 7: Add Collateral Compliance Module
  await dalp.token.installComplianceModule({
    params: { tokenAddress: equityAddress },
    body: {
      params: {
        typeId: "collateral",
        module: collateralModuleAddress,
        values: {
          proofTopic: collateralTopic.topicId,
          ratioBps: 10_000,
          trustedIssuers: [],
        },
      },
      walletVerification: {
        secretVerificationCode: pincode,
        verificationType: "PINCODE",
      },
    },
  });
  console.log("Collateral module added (100% ratio)");

  // Step 8 (Optional): Update collateral parameters to 150%
  await dalp.token.configureComplianceModule({
    params: { tokenAddress: equityAddress },
    body: {
      params: {
        typeId: "collateral",
        module: collateralModuleAddress,
        values: {
          proofTopic: collateralTopic.topicId,
          ratioBps: 15_000,
          trustedIssuers: [],
        },
      },
      walletVerification: {
        secretVerificationCode: pincode,
        verificationType: "PINCODE",
      },
    },
  });
  console.log("Collateral parameters updated (150% ratio)");

  // Step 9: Unpause the equity
  await dalp.token.unpause({
    params: { tokenAddress: equityAddress },
    body: {
      walletVerification: {
        secretVerificationCode: pincode,
        verificationType: "PINCODE",
      },
    },
  });
  console.log("Equity unpaused");

  // Step 10: Issue collateral claim to token identity
  const expiryTimestamp = Math.floor(Date.now() / 1000) + 365 * 24 * 60 * 60;

  await dalp.token.claimIssue({
    params: { tokenAddress: equityAddress },
    body: {
      claim: {
        topic: "collateral",
        data: {
          amount: 1_500_000_000_000_000_000_000n,
          expiryTimestamp: expiryTimestamp.toString(),
        },
      },
      walletVerification: {
        secretVerificationCode: pincode,
        verificationType: "PINCODE",
      },
    },
  });
  console.log("Collateral claim issued");

  // Step 11: Mint shares (validates collateral)
  await dalp.token.mint({
    params: { tokenAddress: equityAddress },
    body: {
      recipients: [myWallet],
      amounts: [100n],
      walletVerification: {
        secretVerificationCode: pincode,
        verificationType: "PINCODE",
      },
    },
  });
  console.log("Mint succeeded — collateral validation passed");
}

await main();
```

The full script above can be copied and adapted for a collateral-backed equity setup.

***

## Troubleshooting [#troubleshooting]

### "ComplianceCheckFailed: Insufficient collateral for mint" [#compliancecheckfailed-insufficient-collateral-for-mint]

**Cause:** The collateral amount in the claim is less than the required amount for the requested mint.

**Solution:**

1. Calculate required collateral:

   ```ts
   const currentSupply = 1000; // Current total supply
   const mintAmount = 500; // Requested mint
   const ratioBps = 10000; // 100% ratio

   const postSupply = currentSupply + mintAmount; // 1500
   const required = Math.ceil((postSupply * ratioBps) / 10000); // 1500
   ```

2. Issue a new collateral claim with sufficient amount or update existing claim

3. Retry minting operation

### "Proof topic cannot be zero" [#proof-topic-cannot-be-zero]

**Cause:** The `proofTopic` parameter is set to `0` when adding the module.

**Solution:** Specify a valid ERC-735 claim topic ID (keccak256 hash of topic name or custom numeric ID).

### "Ratio cannot exceed 20000 (200%)" [#ratio-cannot-exceed-20000-200]

**Cause:** The `ratioBps` parameter exceeds the maximum allowed value.

**Solution:** Set `ratioBps` to a value between `0` and `20000`. For 200% over-collateralization, use `20000`.

### "Trusted issuer cannot be zero address" [#trusted-issuer-cannot-be-zero-address]

**Cause:** The `trustedIssuers` array contains `0x0000000000000000000000000000000000000000`.

**Solution:** Remove zero addresses from the `trustedIssuers` array or leave it empty to rely only on global trusted issuers.

### Mint succeeds but collateral not validated [#mint-succeeds-but-collateral-not-validated]

**Cause:** The `ratioBps` is set to `0`, which disables collateral enforcement.

**Solution:** Set `ratioBps` to a non-zero value (e.g., `10000` for 100% backing) via `token.configureComplianceModule`.

### Claim exists but validation fails [#claim-exists-but-validation-fails]

**Cause:** The claim may be:

* Issued by an untrusted issuer (not in global registry or module config)
* Expired (`expiry <= block.timestamp`)
* Improperly encoded (not matching `(uint256, uint256)` format)
* Revoked or invalid according to issuer's `isClaimValid` function

**Solution:**

1. Verify the issuer address is in the trusted issuer registry for the collateral topic
2. Check claim expiry timestamp is in the future
3. Confirm claim data encoding matches `abi.encode(amount, expiry)`
4. Verify issuer's `isClaimValid` returns true for the claim

***

## Next steps [#next-steps]

* **[Identity and compliance system](/docs/architecture/security/identity-compliance)** – Understand claim-based verification and trusted issuer registries
* **[Compliance module architecture](/docs/architecture/security/compliance)** – Learn how compliance modules integrate with token operations
* **[Create and mint equities](/docs/developer-guides/runbooks/create-mint-equities)** – Deploy equity tokens with initial compliance configuration
* **[API reference](/docs/developer-guides/api-integration/api-reference)** – Explore all compliance module endpoints
