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.
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
This diagram shows the SDK workflow for configuring collateral requirements on an equity token.
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
Before configuring collateral requirements, you need:
- A deployed equity token created with
token.createandtype: "equity" - The governance role, which is required to issue the collateral claim to the token identity
- Compliance-module permissions to install and configure the module
- The supply-management role, which is required for the mint that the module checks
- An API key. See Getting started.
- 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
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);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
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);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
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",
},
},
});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)
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
// 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
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
Collateral claims contain two fields:
amount: collateral amount as a string, for example"1000000000000000000000"for 1000 tokens with 18 decimalsexpiryTimestamp: Unix timestamp as a string when the claim expires. The value must be greater than the current block timestamp.
Issue the claim via API
Use token.claimIssue to add a collateral claim to the token identity. This call requires the governance role.
// 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
After installing the module and issuing collateral claims, call token.statsCollateralRatio before any mint to confirm the backing is sufficient:
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 runs a multi-step check during each minting operation. The steps below explain exactly what the module validates and in what order.
Validation steps
-
Mint detection: the module checks if
from == address(0). Regular transfers skip validation. -
Ratio check: if
ratioBps == 0, collateral enforcement is disabled and minting proceeds. -
Identity resolution: the module loads the token's OnchainID identity address from the token contract.
-
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.
-
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. -
Collateral calculation: the 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
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
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 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
Copy and adapt this TypeScript script for a collateral-backed equity setup:
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
"ComplianceCheckFailed: Insufficient collateral for mint"
The collateral amount in the claim is less than the required amount for the requested mint. To resolve:
-
Calculate the 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 a sufficient amount, or update the existing claim.
-
Retry the minting operation.
"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%)"
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"
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
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
The claim may be issued by an untrusted issuer, expired, improperly encoded, or revoked. Check each of these in order:
- Verify the issuer address is in the trusted issuer registry for the collateral topic.
- Confirm the claim expiry timestamp is in the future.
- Confirm the claim data encoding matches
abi.encode(amount, expiry). - Confirm the issuer's
isClaimValidreturns true for the claim.
Next steps
- Identity and compliance system: claim-based verification and trusted issuer registries
- Compliance module architecture: how compliance modules integrate with token operations
- Create and mint equities: deploy equity tokens with initial compliance configuration
- API reference: all compliance module endpoints