Owner: Configure token compliance

Compliance rules are a critical component of tokenized assets, ensuring that regulatory, legal, and operational constraints are enforced directly at the token level. This article provides a detailed overview of the available compliance rule types, their data structure, and the specific parameters and validation requirements associated with each.

Each compliance rule follows a standardized format and can be configured before or after the token is deployed, depending on the rule's current status. Proper configuration helps issuers enforce jurisdictional restrictions, supply caps, investor limits, conditional transfers, and more.

📘

Note:

For an overview of how tokens are deployed and initially configured, including when compliance rules can be added or modified, please refer to the Token deployment and configuration article.

The following sections outline each rule type in detail, including example payloads, field definitions, and parameter validation logic. For detailed parameter specifications and error codes, please refer to the Swagger documentation.

Summary

All compliance rules will follow the same data format:

{  
	"complianceRule":  
  {  
    "id":  
    "type":  
    "status":  
    "configuration":  
  }  
}

Where:

  • id: UUID generated when the compliance rule is added to the token.
  • type: defines the type of compliance rule. Each token can have only one rule of a given type except for custom type. If we implement new compliance modules in the future, they will have new types. All types available are described below.
  • status: status of the compliance rule to manage blockchain interaction, allowed values are:
    • NotDeployed: it is possible to configure and store compliance rules in the process of creating/deploying a new token. Any compliance rule added to a not deployed token will have Not deployed status
    • InProgress: status while the rule is being processed in the blockchain in case of deployed tokens. This applies when adding, updating or removing a rule.
    • Failed: status when a blockchain operation linked to a compliance rule has failed for any reason. This applies when adding, updating or removing a rule.
    • Active: status when a blockchain operation linked to a compliance rule has succeeded. This applies when adding or updating a rule. For removing it does not apply as the rule will not exist anymore.
  • configuration: JSON object containing the set of params for that specific type of compliance rule.

List of Compliance Types

Type: jurisdiction

Jurisdiction: only investors from selected countries are eligible to receive the token.

{  
  "type": "Jurisdiction"  
  "configuration":  
  {  
    "allowedCountries": [  
      "LUX",  
      "FRA,  
      "ESP",  
      ...  
    ]  
  }  
}

Params format validations:

  • All values on allowedCountries array must be an existing country according to ISO 3166-1 alpha-3 : Error: xxx is a non valid country code
  • There should be no repeated countries. Error: xxx is a repeated.
  • allowedCountries cannot be empty. Error: For enabling this rule you need to set at least one allowed country

 Type: supplyLimit

Total supply limit: it ensures that the total supply of tokens does not exceed the amount set in this limit.

{  
  "type": "SupplyLimit"  
  "configuration":  
  {  
    "amount":"10.9999"  
  }  
}

Params format validations:

  • amount should be greater than 0
  • number of decimals of amount should match number of decimals of the token

 Type: investorLimit

Balance limit per investor: It ensures that balance of tokens for each investor does not exceed the amount set in this limit.

{  
  "type": "InvestorLimit"  
  "configuration":  
  {  
    "amount":"10.9999"  
  }  
}

Params format validations:

  • amount should be greater than 0
  • number of decimals of amount should match number of decimals of the token

 Type: conditionalTransfer

Conditional transfers: It ensures that all transfers between investors are executed only after the approval of different counterparts defined in an approval flow.

{  
  "type": "ConditionalTransfer"  
  "configuration":  
  {  
    "recipientApproval": true/false,  
    "agentApproval": true/false,  
    "walletsApproval": [  
      "0x1BA6791aBb346785c473313A70472bA1BCcf091B",  
      "0x8fD26370598e1845b9C4972E4379a006968b83FE,  
      "0x8fD26370598e1845b9C4972E4379a006968b83FE",  
      ...  
      ]  
    ]  
  }  
}

Params format validations:

  • At least one of the fields need to be set, otherwise is a direct transfer with no approvers: recipientApproval = true or agentAproval = true or walletsApproval is not empty. Error: at least one approver is required to enable conditional transfers
  • If walletsApproval array is not empty, wallet addresses should follow the generic format validation rule:
  • If checksumed, checksum need to be correct, otherwise: Error: The checksum format of your wallet address is incorrect. Please copy and paste from your wallet provider or ensure that the address is in lowercase letters.
  • If lowercase, address need to be stored checksumed

 Type: transferLimit

It ensures a limit on the amount allowed for each investor to transfer within a certain period of time. There can be up to four time intervals (for example: daily, weekly, monthly and yearly).

{  
  "type": "TransferLimit"  
  "configuration":  
  {  
    "limits": [  
      {  
        "timePeriod":  
        "amount":  
      },  
      {  
        "timePeriod":  
        "amount":  
      },  
      ...  
    ]  
  }  
}

Params format validations:

  • Number of elements in limits array should be 0 < N <=4
    • If N <= 0: Error: For enabling this rule you need to set at least one limit
    • If N > 4: Error: This rule supports a maximum of 4 limits
  • timePeriod: integer in seconds
  • amount should be greater than 0
  • number of decimals of amount should match number of decimals of the token

 Type: transferWhitelisting

If enabled, only investors listed are able to perform transfers. Note: any investor can receive if compliance rules are fulfilled.

{  
  "type": "TransferWhitelisting"  
  "configuration":  
  {  
    "identities": [  
      "2e879477-a65f-45b7-ae58-e9ac8c522339",  
      "1e048bb3-2cd1-44fc-a2e5-74f0c37707e8",  
      "d77c20cc-5fe5-40e3-ba26-1286a0ebbe75",  
      ...  
    ]  
  }  
}

Params format validations:

  • identities should not be empty: Error: For enabling this rule you need to set at least one investor.
  • identities are identityIds
  • maybe we can consider wallet addresses instead of identities?

 Type: transferFees

If enabled, a % fee will be taken from the transfer and sent to a collector’s wallet. This collector’s wallet needs to belong to a qualified investor.

{  
  "type": "TransferFees"  
  "configuration":  
  {  
    "fee": "2.00",  
    "collectorWallet": "0x8fD26370598e1845b9C4972E4379a006968b83FE"  
  }  
}

Params format validations:

  • fee is a % with 2 decimals: 0.01 <= fee <= 100.00
  • collectorWallet should follow the generic format validation rule:
  • If checksumed, checksum need to be correct, otherwise: Error: The checksum format of your wallet address is incorrect. Please copy and paste from your wallet provider or ensure that the address is in lowercase letters.
  • If lowercase, address need to be stored checksumed

Type: custom

Only investors from selected countries are eligible to receive the token.

{  
  "type": "Custom"  
  "configuration":  
  {  
    "title": "",  
    "description": "",  
    "moduleAddress": "0x8fD26370598e1845b9C4972E4379a006968b83FE"  
    ]  
  }  
}

Params format validations:

  • moduleAddress should follow the generic format validation rule:
  • If checksumed, checksum need to be correct, otherwise: Error: The checksum format of smart contract is incorrect.
  • If lowercase, address need to be stored checksumed