A comprehensive implementation of CMTAT (Capital Markets and Technology Association Token) standard in Cairo for Starknet, featuring full ABI compatibility with Solidity CMTAT implementation.
- β 100% Solidity ABI Compatible - Exact function signatures matching Solidity CMTAT
- β Four Module Variants - Light, Allowlist, Debt, and Standard implementations
- β ERC20 Compliance with regulatory extensions
- β Role-Based Access Control with role getter functions
- β Batch Operations for efficient multi-address operations
- β Cross-Chain Support (Standard module)
- β Transfer Validation (ERC-1404 compatible)
- β Meta-Transaction Support (Allowlist & Standard modules)
- β OpenZeppelin Components for security and reliability
# Install Scarb (Cairo package manager)
curl --proto '=https' --tlsv1.2 -sSf https://docs.swmansion.com/scarb/install.sh | sh
# Install Starkli (Starknet CLI)
curl https://get.starkli.sh | sh
starkliup# Build all contracts
scarb build
# Run tests
scarb test# Deploy complete ecosystem
./scripts/deploy.shMinimal feature set for basic CMTAT compliance
Constructor:
constructor(
admin: ContractAddress,
name: ByteArray,
symbol: ByteArray,
initial_supply: u256,
recipient: ContractAddress
)Features:
- β Basic ERC20 functionality
- β Minting (mint, batch_mint)
- β Burning (burn, burn_from, batch_burn, forced_burn, burn_and_mint)
- β Pause/Unpause/Deactivate
- β Address freezing (set_address_frozen, batch_set_address_frozen)
- β Information management (terms, information, token_id)
- β Batch balance queries
- β 4 Role constants (DEFAULT_ADMIN, MINTER, PAUSER, ENFORCER)
Use Cases: Standard token deployments, simple compliance requirements
All Light features plus allowlist functionality
Constructor:
constructor(
forwarder_irrevocable: ContractAddress, // For meta-transactions
admin: ContractAddress,
name: ByteArray,
symbol: ByteArray,
initial_supply: u256,
recipient: ContractAddress
)Additional Features:
- β Allowlist control (enable_allowlist, set_address_allowlist, batch_set_address_allowlist)
- β Partial token freezing (freeze_partial_tokens, unfreeze_partial_tokens)
- β Active balance queries (get_active_balance_of)
- β Engine management (snapshot_engine, document_engine)
- β Meta-transaction support (is_trusted_forwarder)
- β 9 Role constants (includes ERC20ENFORCER, SNAPSHOOTER, DOCUMENT, EXTRA_INFORMATION)
Use Cases: Regulated tokens with whitelist requirements, KYC/AML compliance
Specialized for debt securities
Constructor:
constructor(
admin: ContractAddress,
name: ByteArray,
symbol: ByteArray,
initial_supply: u256,
recipient: ContractAddress
)Debt-Specific Features:
- β Debt information management (debt, set_debt)
- β Credit events tracking (credit_events, set_credit_events)
- β Debt engine integration (debt_engine, set_debt_engine)
- β Default flagging (flag_default)
- β All Allowlist features (except allowlist-specific)
- β 10 Role constants (includes DEBT_ROLE)
Use Cases: Corporate bonds, structured debt products, fixed income securities
Full feature set with cross-chain support
Constructor:
constructor(
forwarder_irrevocable: ContractAddress, // For meta-transactions
admin: ContractAddress,
name: ByteArray,
symbol: ByteArray,
initial_supply: u256,
recipient: ContractAddress
)Advanced Features:
- β Cross-chain operations (crosschain_mint, crosschain_burn)
- β Transfer validation (restriction_code, message_for_transfer_restriction)
- β ERC-1404 compliance
- β All core CMTAT features
- β 10 Role constants (includes CROSS_CHAIN_ROLE)
Use Cases: Multi-chain deployments, advanced compliance, institutional securities
All modules are 100% compatible with the Solidity CMTAT ABI specification:
Information Management:
fn terms(self: @ContractState) -> ByteArray
fn set_terms(ref self: ContractState, new_terms: ByteArray) -> bool
fn information(self: @ContractState) -> ByteArray
fn set_information(ref self: ContractState, new_information: ByteArray) -> bool
fn token_id(self: @ContractState) -> ByteArray
fn set_token_id(ref self: ContractState, new_token_id: ByteArray) -> boolBatch Operations:
fn batch_balance_of(self: @ContractState, accounts: Span<ContractAddress>) -> Array<u256>
fn batch_mint(ref self: ContractState, tos: Span<ContractAddress>, values: Span<u256>) -> bool
fn batch_burn(ref self: ContractState, accounts: Span<ContractAddress>, values: Span<u256>) -> boolRole Getters:
fn get_default_admin_role(self: @ContractState) -> felt252
fn get_minter_role(self: @ContractState) -> felt252
fn get_pauser_role(self: @ContractState) -> felt252
// ... all role gettersMinting & Burning:
fn mint(ref self: ContractState, to: ContractAddress, value: u256) -> bool
fn burn(ref self: ContractState, value: u256) -> bool
fn burn_from(ref self: ContractState, from: ContractAddress, value: u256) -> bool
fn burn_and_mint(ref self: ContractState, from: ContractAddress, to: ContractAddress, value: u256) -> boolPause & Freeze:
fn paused(self: @ContractState) -> bool
fn pause(ref self: ContractState) -> bool
fn unpause(ref self: ContractState) -> bool
fn deactivated(self: @ContractState) -> bool
fn deactivate_contract(ref self: ContractState) -> bool
fn set_address_frozen(ref self: ContractState, account: ContractAddress, is_frozen: bool) -> bool
fn batch_set_address_frozen(ref self: ContractState, accounts: Span<ContractAddress>, frozen: Span<bool>) -> bool
fn is_frozen(self: @ContractState, account: ContractAddress) -> boolAllowlist Module:
fn enable_allowlist(ref self: ContractState, status: bool) -> bool
fn is_allowlist_enabled(self: @ContractState) -> bool
fn set_address_allowlist(ref self: ContractState, account: ContractAddress, status: bool) -> bool
fn batch_set_address_allowlist(ref self: ContractState, accounts: Span<ContractAddress>, statuses: Span<bool>) -> bool
fn is_allowlisted(self: @ContractState, account: ContractAddress) -> boolDebt Module:
fn debt(self: @ContractState) -> ByteArray
fn set_debt(ref self: ContractState, debt_: ByteArray) -> bool
fn credit_events(self: @ContractState) -> ByteArray
fn set_credit_events(ref self: ContractState, credit_events_: ByteArray) -> bool
fn debt_engine(self: @ContractState) -> ContractAddress
fn set_debt_engine(ref self: ContractState, debt_engine_: ContractAddress) -> bool
fn flag_default(ref self: ContractState) -> boolStandard Module:
fn crosschain_mint(ref self: ContractState, to: ContractAddress, value: u256) -> bool
fn crosschain_burn(ref self: ContractState, from: ContractAddress, value: u256) -> bool
fn restriction_code(self: @ContractState, from: ContractAddress, to: ContractAddress, value: u256) -> u8
fn message_for_transfer_restriction(self: @ContractState, restriction_code: u8) -> ByteArray| Feature | Light | Allowlist | Debt | Standard |
|---|---|---|---|---|
| Basic ERC20 | β | β | β | β |
| Minting | β | β | β | β |
| Burning | β | β | β | β |
| Forced Burn | β | β | β | β |
| Pause/Unpause | β | β | β | β |
| Deactivation | β | β | β | β |
| Address Freezing | β | β | β | β |
| Partial Token Freezing | β | β | β | β |
| Batch Operations | β | β | β | β |
| Information Management | β | β | β | β |
| Allowlist | β | β | β | β |
| Debt Management | β | β | β | β |
| Cross-Chain | β | β | β | β |
| Transfer Validation | β | β | β | β |
| Meta-Transactions | β | β | β | β |
| Engine Integration | β | β | β | β |
| Role Count | 4 | 9 | 10 | 10 |
cairo-cmtat/
βββ src/
β βββ contracts/
β β βββ light_cmtat.cairo # Minimal CMTAT (4 roles)
β β βββ allowlist_cmtat.cairo # With allowlist (9 roles)
β β βββ debt_cmtat.cairo # For debt securities (10 roles)
β β βββ standard_cmtat.cairo # Full feature set (10 roles)
β βββ engines/
β β βββ rule_engine.cairo # Transfer restrictions
β β βββ snapshot_engine.cairo # Balance snapshots
β βββ interfaces/
β βββ icmtat.cairo # Interface definitions
βββ tests/
β βββ cmtat_tests.cairo # Comprehensive tests
βββ scripts/
βββ deploy.sh # Deployment automation
// Deploy Allowlist CMTAT for KYC/AML compliance
let allowlist_cmtat = deploy_allowlist_cmtat(
forwarder,
admin,
"Regulated Security Token",
"RST",
1000000 * 10^18,
treasury
);
// Enable allowlist
allowlist_cmtat.enable_allowlist(true);
// Add approved addresses
let kyc_addresses = array![addr1, addr2, addr3];
let statuses = array![true, true, true];
allowlist_cmtat.batch_set_address_allowlist(kyc_addresses, statuses);// Deploy Debt CMTAT for bond issuance
let bond_token = deploy_debt_cmtat(
admin,
"Corporate Bond 2025",
"BOND25",
10000000 * 10^18,
issuer
);
// Set debt information
bond_token.set_debt("5% Senior Notes due 2025");
bond_token.set_credit_events("Investment Grade BBB+");
// Integrate debt calculation engine
bond_token.set_debt_engine(debt_calculation_engine);// Deploy Standard CMTAT with cross-chain support
let standard_cmtat = deploy_standard_cmtat(
forwarder,
admin,
"Global Security Token",
"GST",
5000000 * 10^18,
treasury
);
// Enable cross-chain operations
standard_cmtat.grant_role(CROSS_CHAIN_ROLE, bridge_operator);
// Bridge tokens to another chain
standard_cmtat.crosschain_burn(user, 1000 * 10^18);- DEFAULT_ADMIN_ROLE: Master administrator, can grant/revoke all roles
- MINTER_ROLE: Can create new tokens
- BURNER_ROLE: Can destroy tokens
- PAUSER_ROLE: Can pause/unpause contract
- ENFORCER_ROLE: Can freeze/unfreeze addresses
- ERC20ENFORCER_ROLE: Can freeze partial tokens
- SNAPSHOOTER_ROLE: Can create snapshots
- DOCUMENT_ROLE: Can manage documents
- EXTRA_INFORMATION_ROLE: Can update token metadata
- DEBT_ROLE: Can manage debt parameters
- CROSS_CHAIN_ROLE: Can execute cross-chain operations
All modules implement transfer restrictions via ERC20 hooks:
- Pause state check
- Sender/recipient freeze check
- Active balance validation (for partial freezing)
- Custom validation (via transfer validation in Standard)
scarb buildcp .env.example .env
# Edit .env with your configuration./scripts/deploy.shThe script will:
- Deploy all four CMTAT modules
- Set up proper role assignments
- Configure engine integrations
- Output all contract addresses
# Run all tests
scarb test
# Run specific test
scarb test test_name
# Run with verbose output
scarb test --verboseFull API documentation for all modules available in-code documentation.
- Cairo 2.6.3+
- Scarb 2.6.4+
- OpenZeppelin Cairo 0.13.0
src/contracts/ # Token implementations
src/engines/ # Compliance engines
src/interfaces/ # Contract interfaces
tests/ # Test suite
scripts/ # Deployment scripts
Contributions are welcome! Please follow these guidelines:
- Fork the repository
- Create a feature branch
- Write tests for new functionality
- Ensure all tests pass
- Submit a pull request
Mozilla Public License 2.0 (MPL-2.0)
- Starknet: https://starknet.io
- CMTAT: https://www.cmtat.org
- OpenZeppelin Cairo: https://github.com/OpenZeppelin/cairo-contracts
Built for compliant securities on Starknet π
Version 2.0.0 - ABI Compatible Implementation