# Configure equity collateral

Source: https://docs.settlemint.com/docs/developers/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, it checks the token identity for a valid collateral claim and rejects the mint when the claim does not cover the post-mint supply at the configured ratio. Use this guide when you already have an equity token and need mint-time reserve controls: install the module, issue the claim, verify the stats, then mint.

<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]

Before minting, the CollateralComplianceModule reads the token contract's OnchainID identity and looks for a valid collateral claim. The claim amount must meet or exceed the required ratio against the post-mint total supply. The module skips regular transfers.

You configure three behaviors: which ERC-735 claim topic represents collateral proofs, using the `proofTopic` parameter; the required ratio in basis points, from 0 to disable enforcement up to 20000 for 200% over-collateralization; and any additional trusted issuers beyond the global registry.

The claim is not the reserve. Publish only the signed collateral amount and expiry.

***

## 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:

| Call                              | Purpose                                                                                                 |
| --------------------------------- | ------------------------------------------------------------------------------------------------------- |
| `system.read`                     | Retrieve the system configuration, including the Collateral Compliance Module address from the registry |
| `system.claimTopics.list`         | Retrieve the registered collateral claim topic ID                                                       |
| `token.installComplianceModule`   | Install the module with the address, topic ID, initial ratio, and trusted issuers                       |
| `token.configureComplianceModule` | Adjust the ratio or trusted issuers after installation                                                  |
| `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       |

***

## Prerequisites [#prerequisites]

Before configuring collateral requirements, you need:

1. A deployed equity token created with `token.create` and `type: "equity"`
2. The governance role, which is required to issue the collateral claim to the token identity
3. Compliance-module permissions to install and configure the module
4. The supply-management role, which is required for the mint that the module checks
5. An API key. See [Getting started](/docs/api-reference/reference/getting-started).
6. Collateral claim infrastructure: the token identity must receive claims from an authorized issuer or governance operator

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);
```

The call returns the deployed Collateral Compliance Module address. You need this address when you install the module on your token in Step 3. Use `"default"` as the `systemAddress` to get the system used by the Console. Filter `complianceModuleRegistry` by `typeId === "collateral"` to locate the entry. The `module` field holds 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);
```

The call returns the collateral topic ID registered in the system. Pass this ID to `token.installComplianceModule` in Step 3.

***

## 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",
      },
    },
  });
```

The platform registers the module on the equity token's compliance contract. Future mints validate collateral claims against the configured ratio. The response returns the token data with updated compliance modules.

***

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

To adjust the collateral ratio or trusted issuers after initial configuration, call `token.configureComplianceModule`. Raise the ratio to strengthen investor protections during market volatility, or lower it after a successful track record or regulatory change. Add attestors that are not already registered as global trusted issuers for the collateral topic. To switch proof topics, coordinate with claim issuers first.

### 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",
      },
    },
  });
```

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 on individual investor identities. The module checks one identity: the token contract's own identity. Before minting, add a collateral claim to that identity using the governance role.

### Claim structure [#claim-structure]

Collateral claims contain two fields:

* `amount`: collateral amount as a string, for example `"1000000000000000000000"` for 1000 tokens with 18 decimals
* `expiryTimestamp`: Unix timestamp as a string when the claim expires. The value must be greater than the current block timestamp.

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

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

```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",
      },
    },
  });
```

The governance role authorizes direct claim issuance in this SDK flow. The Platform API encodes `(uint256 amount, uint256 expiry)` automatically. The platform issues the claim to the token identity and validates it at mint time.

Mint-time validation accepts claims from the global registry, subject-specific registry entries, or addresses listed in `trustedIssuers`.

***

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

After installing the module and issuing collateral claims, call `token.statsCollateralRatio` before any mint to confirm the backing is sufficient:

```ts fixture=dalp-client
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 runs a multi-step check during each minting operation. The steps below explain exactly what the module validates and in what order.

<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: the module checks if `from == address(0)`. Regular transfers skip validation.

2. Ratio check: if `ratioBps == 0`, collateral enforcement is disabled and minting proceeds.

3. Identity resolution: the module loads the token's OnchainID identity address from the token contract.

4. Issuer aggregation: the module builds a combined list of trusted issuers from the global registry for the proof topic, subject-specific issuers authorized for the token identity, and additional issuers from the module configuration.

5. Claim search: the module queries all claims on the token's identity matching the proof topic. For each claim, it checks that the issuer is trusted, the signature passes `isClaimValid`, the data is ABI-encoded as `(uint256 amount, uint256 expiry)`, and the expiry is in the future.

6. Collateral calculation: the 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]

When multiple valid collateral claims exist on the token identity, the module uses the claim with the highest 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 ahead of 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]

Copy and adapt this TypeScript script for a collateral-backed equity setup:

```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();
```

***

## Troubleshooting [#troubleshooting]

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

The collateral amount in the claim is less than the required amount for the requested mint. To resolve:

1. Calculate the 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 a sufficient amount, or update the existing claim.

3. Retry the minting operation.

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

The `proofTopic` parameter is set to `0`. Specify a valid ERC-735 claim topic ID, such as the keccak256 hash of the topic name or a custom numeric ID.

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

The `ratioBps` parameter exceeds the maximum. Set it 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]

The `trustedIssuers` array contains the zero address. Remove it from the array, or leave the array empty to rely only on global trusted issuers.

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

`ratioBps` is set to `0`, which disables enforcement. Set it to a non-zero value, such as `10000` for 100% backing, using `token.configureComplianceModule`.

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

The claim may be issued by an untrusted issuer, expired, improperly encoded, or revoked. Check each of these in order:

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

***

## Next steps [#next-steps]

* [Identity and compliance system](/docs/compliance-security/security/identity-compliance): claim-based verification and trusted issuer registries
* [Compliance module architecture](/docs/compliance-security/compliance): how compliance modules integrate with token operations
* [Create and mint equities](/docs/developers/runbooks/create-mint-equities): deploy equity tokens with initial compliance configuration
* [API reference](/docs/api-reference/reference/openapi): all compliance module endpoints
