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.
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
This diagram shows the SDK workflow for configuring collateral requirements on an equity token:
SDK calls in this workflow:
system.read– Retrieve the system configuration, including the Collateral Compliance Module address from the compliance module registrysystem.claimTopics.list– Retrieve the registered collateral claim topic ID from the systemtoken.installComplianceModule– Install the Collateral Compliance Module using the retrieved address, topic ID, initial ratio, and trusted issuerstoken.configureComplianceModule– Adjust collateral ratio or trusted issuers after installation (optional)token.claimIssue– Add the collateral claim to the token identity with an amount and expirytoken.statsCollateralRatio– Verify total collateral, required collateral, mintable supply, utilization, and parity confidence before or after minting
Prerequisites
Before configuring collateral requirements, ensure you have:
- Deployed equity token – Created with
token.createandtype: "equity" - Governance role – Required to issue the collateral claim to the token identity
- Compliance-module permissions – Required to install and configure the module
- Supply-management role – Required for the mint that the module checks
- API key – See Getting started
- 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
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
// 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 thesystemAddressto get the system used by the dApp - The
complianceModuleRegistrycontains all registered compliance modules - Filter by
typeId === "collateral"to find the collateral module - The
modulefield contains the deployed contract address
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
// 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
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
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
// 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)
If you need to adjust the collateral ratio or trusted issuers after initial configuration, use token.configureComplianceModule.
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
// 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
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
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
Use token.claimIssue to add a collateral claim to the token identity. This requires the governance role on the token.
// 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
After adding the module and issuing collateral claims, verify the configuration before attempting to mint.
Check collateral stats
Call token.statsCollateralRatio after issuing the claim and before large mints:
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
The Collateral Compliance Module performs validation during minting operations using a multi-step process.
Validation steps
-
Mint detection – Module checks if
from == address(0)(minting operation). Regular transfers skip validation. -
Ratio check – If
ratioBps == 0, collateral enforcement is disabled and minting proceeds. -
Identity resolution – Module loads the token's OnchainID identity address from the token contract.
-
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
-
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)
-
Collateral calculation – Module calculates required collateral using ceiling division:
uint256 postSupply = currentSupply + mintAmount; uint256 requiredCollateral = (postSupply * ratioBps + 9999) / 10000; -
Comparison – If
claimAmount >= requiredCollateral, minting proceeds. Otherwise, the transaction reverts with"ComplianceCheckFailed: Insufficient collateral for mint".
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
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
ratioBpsto the policy threshold. Use10000for 100% backing,15000for 150%, and20000for 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
Complete TypeScript script demonstrating collateral configuration and validation:
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
"ComplianceCheckFailed: Insufficient collateral for mint"
Cause: The collateral amount in the claim is less than the required amount for the requested mint.
Solution:
-
Calculate required collateral:
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 -
Issue a new collateral claim with sufficient amount or update existing claim
-
Retry minting operation
"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%)"
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"
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
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
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
isClaimValidfunction
Solution:
- Verify the issuer address is in the trusted issuer registry for the collateral topic
- Check claim expiry timestamp is in the future
- Confirm claim data encoding matches
abi.encode(amount, expiry) - Verify issuer's
isClaimValidreturns true for the claim
Next steps
- Identity and compliance system – Understand claim-based verification and trusted issuer registries
- Compliance module architecture – Learn how compliance modules integrate with token operations
- Create and mint equities – Deploy equity tokens with initial compliance configuration
- API reference – Explore all compliance module endpoints
Deploy and mint a stablecoin
Create a stablecoin token with the DALP TypeScript client, configure the required roles and collateral issuer, add collateral, and mint supply.
Webhook events
Subscribe to DALP lifecycle events with AsyncAPI, signed webhooks, idempotent delivery, and typed SDK verification.